From e1c93963d94e851ff4d1eb59b2b5e5001320f759 Mon Sep 17 00:00:00 2001 From: cupcakearmy Date: Thu, 19 Dec 2019 16:28:37 +0100 Subject: [PATCH] new menu for more granular control over the single stocks --- src/Background.py | 37 ---- src/commands/config.py | 74 +++----- src/commands/other.py | 98 ++++++---- src/commands/watchlist.py | 237 +++++++++++++++++++++--- src/generator_dict.py | 16 ++ src/{LimitedDict.py => limited_dict.py} | 28 +-- src/limited_list.py | 5 +- src/mercatus.py | 20 +- src/utils.py | 19 +- 9 files changed, 341 insertions(+), 193 deletions(-) delete mode 100644 src/Background.py create mode 100644 src/generator_dict.py rename src/{LimitedDict.py => limited_dict.py} (52%) diff --git a/src/Background.py b/src/Background.py deleted file mode 100644 index cb34719..0000000 --- a/src/Background.py +++ /dev/null @@ -1,37 +0,0 @@ -import asyncio -import threading - - -def interval(every: float or int, autorun=False, iterations=-1, isolated=False, *args_root, **kwargs_root): - def wrapper(fn): - - async def decorator(*args, **kwargs): - it = 0 - first = True - while iterations == -1 or it < iterations: - it += 1 - - if first: - first = False - else: - await asyncio.sleep(every) - - await fn(*args, **kwargs) - - def capsule(*args, **kwargs): - def loop_in_thread(l): - asyncio.set_event_loop(l) - l.run_until_complete(decorator(*args, **kwargs)) - - loop = asyncio.get_event_loop() - threading.Thread(target=loop_in_thread, args=(loop,)).start() - - if autorun: - if isolated: - capsule(*args_root, **kwargs_root) - else: - asyncio.run(decorator(*args_root, **kwargs_root)) - else: - return capsule if isolated else decorator - - return wrapper diff --git a/src/commands/config.py b/src/commands/config.py index 7df667b..fc5cbf9 100644 --- a/src/commands/config.py +++ b/src/commands/config.py @@ -1,23 +1,35 @@ +from enum import Enum + from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardRemove, ParseMode from telegram.ext import CommandHandler, MessageHandler, Filters, ConversationHandler, CallbackQueryHandler, CallbackContext -from utils import Section +MENU, API_KEY, ENABLED = range(3) -MENU, API_KEY, FREQUENCY, ENABLED = range(4) + +class Section(Enum): + Watchlist = 'watchlist' # The list of Stocks/ETF to watch + Code = 'code' # Market code for a given stock, etf, etc. + API_Key = 'api_key' # Alpha Vantage API Key + Running = 'running' # Currently sending updates. Avoid overloading the API + Enabled = 'enabled' # Whether the bot should send automatic updates + Interval = 'interval' # Time axis of the graph + Frequency = 'frequency' # How ofter updates should be sent + LastRun = 'last_run' # Last time an update was sent to the user + CurrentToEdit = 'current_to_edit' # Current element to edit in the conversation handler def show_menu(update: Update, context: CallbackContext): keyboard = [ [InlineKeyboardButton('API Key', callback_data=API_KEY)], - [InlineKeyboardButton('Auto Updates', callback_data=ENABLED)], - [InlineKeyboardButton('Frequency', callback_data=FREQUENCY)], + [InlineKeyboardButton( + f'Turn {"off" if context.user_data.setdefault(Section.Enabled.value, True) else "on"} global auto updates', + callback_data=ENABLED)], [InlineKeyboardButton('Done', callback_data=ConversationHandler.END)], ] update.effective_user.send_message( '_Current settings:_\n' - f'API Key: *{context.user_data[Section.API_Key.value]}*\n' - f'Auto Updates: *{context.user_data[Section.Enabled.value]}*\n' - f'Frequency: *{context.user_data[Section.Frequency.value]}*\n' + f'API Key: *{context.user_data.get(Section.API_Key.value, "No Api key set")}*\n' + f'Global auto updates: *{context.user_data[Section.Enabled.value]}*\n' '\nWhat settings do you want to configure?', parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup(keyboard, one_time_keyboard=True) @@ -35,27 +47,7 @@ def show_menu_api_key(update: Update, context: CallbackContext): return API_KEY -def show_menu_frequency(update: Update, context: CallbackContext): - keyboard = [ - [InlineKeyboardButton('2 minutes', callback_data='2m'), InlineKeyboardButton( - '30 minutes', callback_data='30m')], - [InlineKeyboardButton('hour', callback_data='1h'), InlineKeyboardButton( - '4 hours', callback_data='4h')], - [InlineKeyboardButton('12 hours', callback_data='12h'), InlineKeyboardButton( - 'day', callback_data='1d')], - [InlineKeyboardButton('3 days', callback_data='3d'), InlineKeyboardButton( - 'week', callback_data='1w')], - [InlineKeyboardButton('Cancel', callback_data='cancel')], - ] - update.effective_user.send_message( - 'Send me updates every: โฌ‡', - reply_markup=InlineKeyboardMarkup(keyboard) - ) - - return FREQUENCY - - -def config(update: Update, context: CallbackContext): +def init(update: Update, context: CallbackContext): context.bot.delete_message( chat_id=update.message.chat_id, message_id=update.message.message_id, @@ -73,8 +65,6 @@ def menu(update: Update, context: CallbackContext): if selected == API_KEY: return show_menu_api_key(update, context) - elif selected == FREQUENCY: - return show_menu_frequency(update, context) elif selected == ENABLED: toggle_enabled(update, context) else: @@ -89,25 +79,8 @@ def set_api_key(update, context): return show_menu(update, context) -def set_frequency(update: Update, context: CallbackContext): - selected = update.callback_query.data - - if selected != 'cancel': - update.callback_query.edit_message_text(f'Saved {selected} ๐Ÿ’ช') - context.user_data[Section.Frequency.value] = selected - else: - context.bot.delete_message( - chat_id=update.callback_query.message.chat_id, - message_id=update.callback_query.message.message_id, - ) - - return show_menu(update, context) - - def toggle_enabled(update: Update, context: CallbackContext): - new = not context.user_data.setdefault(Section.Enabled.value, True) - context.user_data[Section.Enabled.value] = new - update.effective_user.send_message('Auto updates enabled' if new else 'Auto updates disabled') + context.user_data[Section.Enabled.value] = not context.user_data[Section.Enabled.value] return show_menu(update, context) @@ -118,16 +91,13 @@ def cancel(update: Update, context: CallbackContext): config_handler = ConversationHandler( - entry_points=[CommandHandler('config', config)], - + entry_points=[CommandHandler('settings', init)], states={ MENU: [CallbackQueryHandler(menu)], API_KEY: [ CommandHandler('cancel', cancel), MessageHandler(Filters.all, set_api_key), ], - FREQUENCY: [CallbackQueryHandler(set_frequency)], }, - fallbacks=[CommandHandler('cancel', cancel)] ) diff --git a/src/commands/other.py b/src/commands/other.py index 2cee468..08abfbf 100644 --- a/src/commands/other.py +++ b/src/commands/other.py @@ -1,74 +1,97 @@ from asyncio import sleep, run from datetime import datetime -from threading import Timer from pytimeparse import parse -from telegram import Update, ParseMode -from telegram.ext import CallbackContext +from telegram import Update, ParseMode, ReplyKeyboardRemove +from telegram.ext import CallbackContext, ConversationHandler from telegram.ext.dispatcher import run_async +from commands.config import Section from market import Market from text import INTRO_TEXT -from utils import Section, persistence, updater, current_timestamp, delta_timestamp +from utils import persistence, updater, current_timestamp, delta_timestamp SENDING = False -def error(update: Update, context: CallbackContext): - print(context.error) +def error_handler(update: Update, context: CallbackContext): + print('Error: ', context.error) -def start(update: Update, context: CallbackContext): +def start_handler(update: Update, context: CallbackContext): update.message.reply_markdown(INTRO_TEXT) +def help_handler(update: Update, context: CallbackContext): + update.message.reply_markdown(INTRO_TEXT) + + +def stop_handler(update: Update, context: CallbackContext): + context.user_data.clear() + update.message.reply_text('You and your data were deleted ๐Ÿ—‘') + + @run_async def data(update: Update, context: CallbackContext): - delta = current_timestamp() - context.user_data.setdefault(Section.Interval.value, delta_timestamp(days=365)) - send_update_to_user(user=update.effective_user['id'], delta=delta) + send_update_to_user(update.effective_user['id'], False) -def send_update_to_user(user: str, delta: int): +def send_update_to_user(user: str, auto, codes=None): user_data = None try: user_data = persistence.user_data[user] running = user_data.setdefault(Section.Running.value, False) - print(f'Running {user} - {user_data}') if Section.API_Key.value not in user_data: - updater.bot.send_message(user, text='API Key not set โ›”๏ธ') + updater.bot.send_message(user, text='API Key not set โ›”๏ธ\nSet in /settings') return if running: updater.bot.send_message(user, text='Already running ๐Ÿƒ') return - print(f'Sending updates to {user}') user_data[Section.Running.value] = True - user_data[Section.LastRun.value] = current_timestamp() - market = Market(user_data[Section.API_Key.value]) - updater.bot.send_message(user, text='Getting updates ๐ŸŒŽ') + now = current_timestamp() + if auto: + updater.bot.send_message(user, text='Getting updates ๐ŸŒŽ') first = True - for item in user_data.get(Section.Watchlist.value, []): - if first: - first = False - else: - # Wait to not overload the api - msg = updater.bot.send_message(user, text='Waiting 60 seconds for API... โณ') - run(sleep(60)) + for code in codes if codes else user_data.get(Section.Watchlist.value, {}).keys(): + try: + code_data = persistence.user_data[user][Section.Watchlist.value][code] + code_data = code_data['value'] + print(code, code_data) + last_run = code_data[Section.LastRun.value] + frequency = parse(code_data[Section.Frequency.value]) + interval = parse(code_data[Section.Interval.value]) + print(code, last_run + frequency, now, last_run + frequency - now) + + if auto and last_run + frequency > now: + continue + persistence.user_data[user][Section.Watchlist.value][code][Section.LastRun.value] = current_timestamp() + persistence.flush() + + if first: + first = False + else: + # Wait to not overload the api + msg = updater.bot.send_message(user, text='Waiting 60 seconds for API... โณ') + run(sleep(60)) + msg.delete() + + msg = updater.bot.send_message(user, text=f'Calculating {code}... โณ') + delta = datetime.fromtimestamp(now - interval) + chart = market.get_wma(code, delta) msg.delete() + updater.bot.send_photo(user, photo=chart, disable_notification=True, + caption=f'{code} - {code_data[Section.Interval.value]}') + except Exception as e: + print(f'โŒ {user} - {e}') + updater.bot.send_message(user, text=f'There was an error โš ๏ธ\n {e}') - msg = updater.bot.send_message(user, text=f'Calculating {item}... โณ') - chart = market.get_wma(item, datetime.fromtimestamp(delta)) - msg.delete() - updater.bot.send_photo(user, photo=chart, caption=f'*{item}*', - parse_mode=ParseMode.MARKDOWN, disable_notification=True) - - except Exception as e: - print(f'โŒ {user} - {e}') - updater.bot.send_message(user, text=f'There was an error โš ๏ธ\n {e}') + if auto: + updater.bot.send_message(user, text=f'Done โœ…') finally: if user_data: user_data[Section.Running.value] = False @@ -81,16 +104,9 @@ def send_updates(context: CallbackContext): return SENDING = True - now = current_timestamp() - for user, user_data in persistence.user_data.items(): - enabled = user_data.setdefault(Section.Enabled.value, True) - last_run = user_data.setdefault(Section.LastRun.value, 0) - frequency = parse(user_data.setdefault(Section.Frequency.value, '1d')) - - if enabled and last_run + frequency < now: - delta = now - user_data.setdefault(Section.Interval.value, delta_timestamp(days=365)) - send_update_to_user(user=user, delta=delta) + if user_data.setdefault(Section.Enabled.value, False): + send_update_to_user(user=user, auto=True) except Exception as e: print(e) finally: diff --git a/src/commands/watchlist.py b/src/commands/watchlist.py index 69bd9d3..408fa8a 100644 --- a/src/commands/watchlist.py +++ b/src/commands/watchlist.py @@ -1,45 +1,232 @@ -from telegram import Update -from telegram.ext import CallbackContext +from telegram import Update, InlineKeyboardButton, ParseMode, InlineKeyboardMarkup, ReplyKeyboardRemove +from telegram.ext import CallbackContext, ConversationHandler, CommandHandler, CallbackQueryHandler, MessageHandler, Filters -from limited_list import LimitedList -from utils import parse_command, config, Section +from commands.config import Section +from commands.other import send_update_to_user +from limited_dict import LimitedDict +from utils import parse_command, config + +ALL, SINGLE, EDIT, ADD, DELETE, BACK, ENABLED, FREQUENCY, INTERVAL, DATA = map(chr, range(10)) +END = str(ConversationHandler.END) -def get_watchlist(context: CallbackContext) -> LimitedList: - return LimitedList( +def get_watchlist(context: CallbackContext) -> LimitedDict: + return LimitedDict( config[Section.Watchlist.value]['max_items'], - context.user_data.setdefault(Section.Watchlist.value, []), + context.user_data.setdefault(Section.Watchlist.value, {}), ) -def save_watchlist(context: CallbackContext, l: LimitedList): - context.user_data[Section.Watchlist.value] = l.all() +def save_watchlist(context: CallbackContext, limited_dict: LimitedDict): + context.user_data[Section.Watchlist.value] = limited_dict.dict -def watchlist_add(update: Update, context: CallbackContext): - value, *rest = parse_command(update) +def init(update: Update, context: CallbackContext): + context.bot.delete_message( + chat_id=update.message.chat_id, + message_id=update.message.message_id, + ) + return show_menu(update, context) + +def show_menu(update: Update, context: CallbackContext): wl = get_watchlist(context) - wl.add(str(value).upper()) - save_watchlist(context, wl) - update.message.reply_text('Saved ๐Ÿ’พ') + saved = [ + [InlineKeyboardButton(item, callback_data=item)] + for item in wl.all() + ] + options = [[ + InlineKeyboardButton('Add', callback_data=ADD), + InlineKeyboardButton('Done', callback_data=END) + ]] + update.effective_user.send_message( + '_Your Watchlist:_\n' + f'*{len(wl)}/{wl.limit}* slots filled\n' + '\nYou can add, modify or delete items', + parse_mode=ParseMode.MARKDOWN, + reply_markup=InlineKeyboardMarkup(saved + options, one_time_keyboard=True) + ) + + return ALL -def watchlist_delete(update: Update, context: CallbackContext): - value, *rest = parse_command(update) +def menu(update: Update, context: CallbackContext): + context.bot.delete_message( + chat_id=update.callback_query.message.chat_id, + message_id=update.callback_query.message.message_id, + ) + + selected: str = update.callback_query.data + if selected == ADD: + return show_add(update, context) + elif selected == END: + return ConversationHandler.END + else: + context.user_data[Section.CurrentToEdit.value] = selected + return show_single(update, context) + + +def show_add(update: Update, context: CallbackContext): + update.effective_user.send_message( + 'Send me the code (e.g. AAPL or URTH)\n' + 'or send /cancel', + reply_markup=ReplyKeyboardRemove() + ) + return ADD + + +def add(update, context): + reply: str = update.message.text wl = get_watchlist(context) - found = wl.delete(value) + wl[reply.upper()] = { + Section.Enabled.value: True, + Section.Frequency.value: '1d', + Section.Interval.value: '52w', + Section.LastRun.value: 0, + } save_watchlist(context, wl) - update.message.reply_text('Deleted ๐Ÿ—‘' if found else 'Not found โ“') + update.message.reply_text(f'Saved {reply} ๐Ÿ’พ', reply_markup=ReplyKeyboardRemove()) + + return show_menu(update, context) -def watchlist_all(update: Update, context: CallbackContext): - items = get_watchlist(context).all() - update.message.reply_text('\n'.join(items) if len(items) > 0 else 'Your list is empty ๐Ÿ“ญ') +def show_single(update, context): + current = context.user_data[Section.CurrentToEdit.value] + current_data = get_watchlist(context)[current] + keyboard = [ + [InlineKeyboardButton(f'Turn {"off" if current_data[Section.Enabled.value] else "on"} auto updates', callback_data=ENABLED)], + [InlineKeyboardButton(f'Frequency', callback_data=FREQUENCY)], + [InlineKeyboardButton(f'Time interval', callback_data=INTERVAL)], + [InlineKeyboardButton(f'Show data', callback_data=DATA)], + [InlineKeyboardButton('Delete', callback_data=DELETE)], + [InlineKeyboardButton('Back', callback_data=BACK)], + ] + update.effective_user.send_message( + '_Current settings:_\n' + f'Auto Updates: *{current_data[Section.Enabled.value]}*\n' + f'Frequency: *{current_data[Section.Frequency.value]}*\n' + f'Interval: *{current_data[Section.Interval.value]}*\n' + f'\nEdit {current}: โฌ‡', + parse_mode=ParseMode.MARKDOWN, + reply_markup=InlineKeyboardMarkup(keyboard) + ) + + return SINGLE -def watchlist_clear(update: Update, context: CallbackContext): +def single(update, context): + current = context.user_data[Section.CurrentToEdit.value] + selected = update.callback_query.data wl = get_watchlist(context) - wl.clear() - save_watchlist(context, wl) - update.message.reply_text('Cleared ๐Ÿงผ') + + context.bot.delete_message( + chat_id=update.callback_query.message.chat_id, + message_id=update.callback_query.message.message_id, + ) + + if selected == DELETE: + update.effective_user.send_message(f'Deleted {current} ๐Ÿ’ช') + del wl[current] + save_watchlist(context, wl) + return show_menu(update, context) + elif selected == BACK: + return show_menu(update, context) + elif selected == ENABLED: + print('Changing', wl[Section.Enabled.value]) + wl[current][Section.Enabled.value] = not wl[current][Section.Enabled.value] + save_watchlist(context, wl) + return show_single(update, context) + elif selected == FREQUENCY: + return show_single_frequency(update, context) + elif selected == INTERVAL: + return show_single_interval(update, context) + elif selected == DATA: + send_update_to_user(update.effective_user['id'], False, [current]) + return show_single(update, context) + else: + return cancel(update, context) + + +def show_single_frequency(update: Update, context: CallbackContext): + keyboard = [ + [InlineKeyboardButton('2 minutes', callback_data='2m'), InlineKeyboardButton( + '30 minutes', callback_data='30m')], + [InlineKeyboardButton('hour', callback_data='1h'), InlineKeyboardButton( + '4 hours', callback_data='4h')], + [InlineKeyboardButton('12 hours', callback_data='12h'), InlineKeyboardButton( + 'day', callback_data='1d')], + [InlineKeyboardButton('3 days', callback_data='3d'), InlineKeyboardButton( + 'week', callback_data='1w')], + [InlineKeyboardButton('Cancel', callback_data='cancel')], + ] + update.effective_user.send_message( + 'Send me updates every: โฌ‡', + reply_markup=InlineKeyboardMarkup(keyboard) + ) + + return FREQUENCY + + +def single_frequency(update: Update, context: CallbackContext): + return save_single_attribute(update, context, Section.Frequency.value) + + +def show_single_interval(update: Update, context: CallbackContext): + keyboard = [ + [InlineKeyboardButton('1 day', callback_data='1d'), InlineKeyboardButton( + '2 days', callback_data='2d')], + [InlineKeyboardButton('1 week', callback_data='7d'), InlineKeyboardButton( + '1 weeks', callback_data='14d')], + [InlineKeyboardButton('1 month', callback_data='30d'), InlineKeyboardButton( + '3 months', callback_data='90d')], + [InlineKeyboardButton('1 year', callback_data='52w'), InlineKeyboardButton( + '2 years', callback_data='104w')], + [InlineKeyboardButton('Cancel', callback_data='cancel')], + ] + update.effective_user.send_message( + 'Select the graph time span ๐Ÿ“ˆ:', + reply_markup=InlineKeyboardMarkup(keyboard) + ) + + return INTERVAL + + +def single_interval(update: Update, context: CallbackContext): + return save_single_attribute(update, context, Section.Interval.value) + + +def save_single_attribute(update: Update, context: CallbackContext, key): + current = context.user_data[Section.CurrentToEdit.value] + selected = update.callback_query.data + wl = get_watchlist(context) + + context.bot.delete_message( + chat_id=update.callback_query.message.chat_id, + message_id=update.callback_query.message.message_id, + ) + + if selected != 'cancel': + update.effective_user.send_message(f'Saved {selected} ๐Ÿ’พ') + wl[current][key] = selected + + return show_single(update, context) + + +def cancel(update: Update, context: CallbackContext): + update.effective_user.send_message('Canceled', reply_markup=ReplyKeyboardRemove()) + return ConversationHandler.END + + +cancel_command_handler = CommandHandler('cancel', cancel) + +watchlist_handler = ConversationHandler( + entry_points=[CommandHandler('list', init)], + states={ + ALL: [CallbackQueryHandler(menu)], + ADD: [cancel_command_handler, MessageHandler(Filters.text, add)], + SINGLE: [cancel_command_handler, CallbackQueryHandler(single)], + FREQUENCY: [CallbackQueryHandler(single_frequency)], + INTERVAL: [CallbackQueryHandler(single_interval)], + }, + fallbacks=[cancel_command_handler], +) diff --git a/src/generator_dict.py b/src/generator_dict.py new file mode 100644 index 0000000..1607ae4 --- /dev/null +++ b/src/generator_dict.py @@ -0,0 +1,16 @@ +class GeneratorDict(dict): + def __init__(self, *args, generator=None, **kwargs): + super().__init__(*args, **kwargs) + + if not generator: + def generator(x): return x + + self.generator = generator + + def __getitem__(self, key): + try: + return super().__getitem__(key) + except: + value = self.generator(key) + super().__setitem__(key, value) + return value diff --git a/src/LimitedDict.py b/src/limited_dict.py similarity index 52% rename from src/LimitedDict.py rename to src/limited_dict.py index 429a744..70a59f3 100644 --- a/src/LimitedDict.py +++ b/src/limited_dict.py @@ -1,38 +1,44 @@ import time -import math +from math import inf class LimitedDict: - def __init__(self, init: dict, limit: int): + def __init__(self, limit: int, init: dict): self.dict = init self.limit = limit - def set(self, key, value): - # Delete oldest element if there are too many + def __len__(self): + return len(self.dict) + + def __setitem__(self, key, value): + # Delete the oldest if there are too many entries if len(self.dict) + 1 > self.limit: - timestamp = math.inf - who = None + timestamp = inf + oldest = None for cur, item in self.dict.items(): if item['when'] < timestamp: timestamp = item['when'] - who = cur - del self.dict[who] + oldest = cur + del self.dict[oldest] self.dict[key] = { 'value': value, 'when': int(time.time()) } - def get(self, key): + def __getitem__(self, key): value = self.dict.get(key, None) return value['value'] if value else None - def delete(self, key): + def __delitem__(self, key): self.dict.pop(key, None) def clear(self): self.dict.clear() def all(self): - return [x['value'] for x in self.dict.values()] + return { + key: value['value'] + for key, value in self.dict.items() + } diff --git a/src/limited_list.py b/src/limited_list.py index bf42879..a82e476 100644 --- a/src/limited_list.py +++ b/src/limited_list.py @@ -11,10 +11,13 @@ class LimitedList: self.data = init if init else [] self.limit = limit + def __len__(self): + return len(self.data) + def _is_index(self, i: int) -> bool: return False if i < 0 or i > len(self.data) - 1 else True - def add(self, value: str): + def add(self, value: any): print(f'Before {self.data}') # Delete oldest element if there are too many if len(self.data) + 1 > self.limit: diff --git a/src/mercatus.py b/src/mercatus.py index e5a4f67..948c384 100644 --- a/src/mercatus.py +++ b/src/mercatus.py @@ -1,10 +1,10 @@ import matplotlib as mpl from telegram.ext import CommandHandler -from utils import updater, persistence +from utils import updater from commands.config import config_handler -from commands.watchlist import watchlist_add, watchlist_delete, watchlist_all, watchlist_clear -from commands.other import start, data, send_updates +from commands.watchlist import watchlist_handler +from commands.other import data, send_updates, start_handler, help_handler, stop_handler, error_handler def main(): @@ -14,16 +14,16 @@ def main(): jq = updater.job_queue # Handlers - dp.add_handler(CommandHandler('add', watchlist_add)) - dp.add_handler(CommandHandler('delete', watchlist_delete)) - dp.add_handler(CommandHandler('list', watchlist_all)) - dp.add_handler(CommandHandler('clear', watchlist_clear)) - dp.add_handler(config_handler) - dp.add_handler(CommandHandler('start', start)) + dp.add_error_handler(error_handler) + dp.add_handler(CommandHandler('start', start_handler)) + dp.add_handler(CommandHandler('stop', stop_handler)) + dp.add_handler(CommandHandler('help', help_handler)) dp.add_handler(CommandHandler('data', data)) + dp.add_handler(config_handler) + dp.add_handler(watchlist_handler) # Cron jobs - jq.run_repeating(send_updates, interval=30, first=0) + jq.run_repeating(send_updates, interval=30, first=5) # Start print('Started ๐Ÿš€') diff --git a/src/utils.py b/src/utils.py index b9b9693..58b5fc2 100644 --- a/src/utils.py +++ b/src/utils.py @@ -10,19 +10,9 @@ CONFIG_FILE = './config.yml' config = load(open(CONFIG_FILE, 'r'), Loader=Loader) persistence = PicklePersistence(DB_FILE) -# persistence.load_singlefile() updater: Updater = Updater(config['token'], use_context=True, persistence=persistence) -class Section(Enum): - Watchlist = 'watchlist' - API_Key = 'api_key' - Running = 'running' - Interval = 'interval' # Time axis of the graph - Frequency = 'frequency' # How ofter updates should be sent - LastRun = 'last_run' - - def current_timestamp(): return int(datetime.now().timestamp()) @@ -32,11 +22,8 @@ def delta_timestamp(**kwargs): def parse_command(update: Update) -> (str, str): + """ + Splits the command from the rest of the message and returns the tuple + """ key, value = (update.message.text.split(' ', 1)[1].split(' ', 1) + [None])[:2] return key, value - - -def parse_callback(update: Update) -> str: - selected = update.callback_query.data - cleaned = ''.join(selected.split(':')[1:]) # Remove the pattern from the start - return cleaned