TFinance

Форк
0
/
main.py 
203 строки · 9.9 Кб
1
# ----------------------------------------- Основной файл приложения ----------------------------------------- #
2
# --------------- Импорт необходимых библиотек, функций, классов --------------- #
3
# Встроенные библиотеки.
4
import logging
5
import os
6
import warnings
7

8
# Для работы со временем.
9
import datetime
10
import pytz
11

12
# Работа с telegram-bot-api.
13
from telegram.ext import Updater, CommandHandler, ConversationHandler, CallbackQueryHandler
14

15
# Работа с акциями (загрузка, вывод, проверка, игра, визуализация, рассылка).
16
from blast import notify_assignees, daily
17
from functions import create_user
18
from graphics.visualize import do_stock_image, pdr
19
from stock import check_stock, load_stocks, get_all_stocks
20
from database import Database
21
from game import game_menu, higher_game, lower_game, game_results  # ORM (БД с данными о пользователях).
22

23
# Импортируем TOKEN из безопасного места
24
from safety_key import TOKEN
25

26
# Запускаем логирование
27
if not os.path.exists(f'{os.getcwd()}/logs'):
28
    os.mkdir(f'{os.getcwd()}/logs')
29
logging.basicConfig(
30
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.WARNING,
31
    filename=f"{os.getcwd()}/logs/tfinance_main.log")
32
logger = logging.getLogger(__name__)
33

34
# Отключаем предупреждения пользователей библиотек
35
warnings.simplefilter("ignore")
36

37

38
# Отправка всех акций из заданного диапазона (start, end).
39
def send_stocks(update, start, end, templates):
40
    msg = ''
41
    for i in range(start, end):
42
        msg += templates['stocks'][i] + ', '
43
    update.message.reply_text(msg)
44

45

46
# Получение списка необходимых акций по команде /stocks [args]. Обработчик команды /stocks.
47
def get_list_stocks(update, context):
48
    try:
49
        templates = load_stocks('stocks.json')  # Загружаем список всех акций
50

51
        # Проверка на наличие аргументов
52
        if context.args[0] == 'all':
53
            # Большим сообщением все сразу не отправится, поэтому разделяем на 3 поменьше.
54
            send_stocks(update, 0, 700, templates)
55
            send_stocks(update, 700, 1400, templates)
56
            send_stocks(update, 1400, 2100, templates)
57
        elif context.args[0].isdigit():  # Если аргумент - число, отсылаем первые n акций.
58
            numb = int(context.args[0])
59
            if numb > 700:
60
                while numb > 700:
61
                    numb = 700
62
                    send_stocks(update, 0, numb, templates)
63
                    numb = int(context.args[0]) - 700
64
            send_stocks(update, 0, numb, templates)
65
        else:  # Если аргумент - строка, выводим все акции на первую букву строки.
66
            message = []
67
            for el in templates['stocks']:
68
                if el[0].lower() == context.args[0].lower()[0]:
69
                    message.append(el)
70
            update.message.reply_text(', '.join(message))
71
    except (IndexError, ValueError):
72
        update.message.reply_text("Неверный способ ввода. /help")
73

74

75
# Обработчик команды /stock [stock_index]. Визуализирует график и отправляет его в прямом порядке.
76
def get_stock_image(update, context):
77
    try:
78
        if context.args[0]:
79
            update.message.reply_photo(do_stock_image(context.args[0]))
80
        else:
81
            raise ValueError
82
    except (IndexError, ValueError):
83
        update.message.reply_text("Неверный способ ввода. /stock [индекс акции]. Например: /stock AAPL")
84
    except pdr._utils.RemoteDataError:
85
        update.message.reply_text("Такой акции не было найдено в данных Yahoo Finance.")
86

87

88
# Обработчик команды /start. Добавляет пользователя в БД, тем самым открывая ему доступ к командам.
89
def start(update, _):
90
    user = create_user(update)
91
    db.add_user(user)
92
    update.message.reply_text(f"Привет, {user.first_name}! Теперь доступ к командам открыт.")
93

94

95
# Обработчик команды /help.
96
def help(update, _):
97
    update.message.reply_text("""   /stocks [количество акций] Например: /stocks 100 - посмотреть первые 100 акций
98
    /stocks all - посмотреть все акции на бирже
99
    /stocks [буква алфавита] Например: /stocks A - посмотреть все акции,название которых начинается с 'A'
100
    /follow [stock_name] - добавить акцию в избранное
101
    /unfollow [stock_name] - удалить акцию из избранного
102
    /favourites - посмотреть список избранных акций
103
    /daily - установить ежедневную рассылку избранных акций
104
    /stats - посмотреть собственную статистику
105
    /game [stock_name] - начать игру с прогнозом выбранной акции""")
106

107

108
# Обработчик команды /favourites. Отправляет список любимых акций.
109
def favourites(update, _):
110
    user = create_user(update)
111
    stocks = db.get_favourites_stocks(user)
112
    if stocks and stocks[0]:
113
        update.message.reply_text(', '.join(stocks[0].split()))
114
    else:
115
        update.message.reply_text('У вас нет избранных акций')
116

117

118
# Обработчик команды /follow. Возможность подписываться на другие акции.
119
def follow(update, context):
120
    user = create_user(update)
121
    if context.args and context.args[0]:
122
        context.args[0] = context.args[0].upper()
123
        if db.check_favourites_stocks(user, context.args[0]):
124
            update.message.reply_text('Акция уже в избранном')
125
        else:
126
            if check_stock(context.args[0]):
127
                db.add_favourites_stocks(user, context.args[0])
128
                update.message.reply_text('Акция добавлена в избранное')
129
            else:
130
                update.message.reply_text('Акция не найдена')
131
    else:
132
        update.message.reply_text('Неверный способ ввода. /follow [индекс акции]. Например: /follow AAPL')
133

134

135
# Обработчик команды /unfollow. Возможность отписки от акций.
136
def unfollow(update, context):
137
    user = create_user(update)
138
    if context.args and context.args[0]:
139
        context.args[0] = context.args[0].upper()
140
        if not db.check_favourites_stocks(user, context.args[0]):
141
            update.message.reply_text('Акции нет в избранном')
142
        else:
143
            db.remove_favourites_stock(user, context.args[0])
144
            update.message.reply_text('Акция удалена из избранного')
145
    else:
146
        update.message.reply_text('Неверный способ ввода. /unfollow [индекс акции].')
147

148

149
# Обработчик команды /stats. Вывод статистики пользователя из БД.
150
def stats(update, _):
151
    user = create_user(update)
152
    data = db.read_info(user)
153
    try:
154
        update.message.reply_text(f'UserName: {data[0]}\nИзбранные акции:'
155
                                  f' {", ".join(data[1].split()) if data[1] else None}'
156
                                  f'\nОчки, заработанные в игре: {data[2]}')
157
    except TypeError:
158
        update.message.reply_text('Вас нет в бд, запустите команду /start чтобы исправить ошибку')
159

160

161
# Основной цикл, активирующийся при запуске.
162
def main():
163
    # Получение и сохранение списка всех акций в stocks.json.
164
    try:
165
        get_all_stocks()
166
    except Exception as e:
167
        logging.error(e)
168

169
    # Создаём объект updater.
170
    updater = Updater(TOKEN)
171
    dispatcher = updater.dispatcher
172
    job_queue = updater.job_queue
173

174
    # Ежедневные задачи.
175
    job_queue.run_daily(notify_assignees, datetime.time(hour=8, tzinfo=pytz.timezone('Europe/Moscow')))
176
    job_queue.run_daily(game_results, datetime.time(hour=3, tzinfo=pytz.timezone('Europe/Moscow')))
177

178
    # ConversationHandler для игры.
179
    game_handler = ConversationHandler(entry_points=[CommandHandler("game", game_menu)],
180
                                       states={1: [CallbackQueryHandler(higher_game, pattern=f"^1$"),
181
                                                   CallbackQueryHandler(lower_game, pattern=f"^2$")]},
182
                                       fallbacks=[CommandHandler("game", game_menu)])
183
    dispatcher.add_handler(game_handler)
184

185
    # Регистрируем обработчик команд.
186
    dispatcher.add_handler(CommandHandler("daily", daily))
187
    dispatcher.add_handler(CommandHandler("start", start))
188
    dispatcher.add_handler(CommandHandler("help", help))
189
    dispatcher.add_handler(CommandHandler("favourites", favourites))
190
    dispatcher.add_handler(CommandHandler("follow", follow))
191
    dispatcher.add_handler(CommandHandler("unfollow", unfollow))
192
    dispatcher.add_handler(CommandHandler("stock", get_stock_image))
193
    dispatcher.add_handler(CommandHandler("stocks", get_list_stocks))
194
    dispatcher.add_handler(CommandHandler("stats", stats))
195

196
    # Обработка сообщений.
197
    updater.start_polling()
198
    updater.idle()
199

200

201
if __name__ == '__main__':
202
    db: Database = Database('data.db')
203
    main()
204

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.