diff --git a/src/Commands.py b/src/Commands.py index 8a8c9d7..b6cc54a 100644 --- a/src/Commands.py +++ b/src/Commands.py @@ -1,8 +1,13 @@ +import asyncio +from asyncio import sleep +from datetime import datetime, timedelta from telegram.ext import CallbackContext -from telegram import Update +from telegram import Update, ParseMode +from Background import interval from LimitedList import LimitedList -from Utils import parse_command, config, Section +from Market import Market +from Utils import parse_command, config, Section, persistence, updater def get_watchlist(context: CallbackContext) -> LimitedList: @@ -23,7 +28,7 @@ def watchlist_delete(update: Update, context: CallbackContext): def watchlist_all(update: Update, context: CallbackContext): items = get_watchlist(context).all() - update.message.reply_text('\n'.join(items)) + update.message.reply_text('\n'.join(items) if len(items) > 0 else 'Your list is empty 📭') def watchlist_clear(update: Update, context: CallbackContext): @@ -38,4 +43,70 @@ def set_api_key(update: Update, context: CallbackContext): def get_api_key(update: Update, context: CallbackContext): - update.message.reply_text(context.user_data.get(Section.API_Key.value, 'API Key not set')) + update.message.reply_text(context.user_data.get(Section.API_Key.value, 'API Key not set ⛔️')) + + +def data(update: Update, context: CallbackContext): + id = update.message.chat_id + delta = datetime.now() - timedelta(days=365 * 1) + asyncio.run(send_update_to_user(user=id, delta=delta)) + + +def start(update: Update, context: CallbackContext): + update.message.reply_markdown("""*Welcome! 👋* + +*1.* First you will need to get a (free) api token for the stock data. +[https://www.alphavantage.co/support/#api-key](Alphavantage Key 🔑) + +*2.* Then enter it by sending the code to me with `/setKey myApiCode` + +*3.* Add stocks or ETFs to your `/list` by going to [https://finance.yahoo.com/](Yahoo Finance 📈) and the sending it to `/add` +_Example_ For Apple `/add AAPL` + +Enjoy 🚀 +""") + + +async def send_update_to_user(user: str, delta: datetime): + try: + data = persistence.get_user_data()[user] + running = data.setdefault(Section.Running.value, False) + if Section.API_Key.value not in data: + return + + if running: + updater.bot.send_message(user, text='Already running 🏃') + return + + data[Section.Running.value] = True + print('Sending updates to {}'.format(user)) + market = Market(data[Section.API_Key.value]) + updater.bot.send_message(user, text='Getting updates 🌎') + first = True + for item in data.get(Section.Watchlist.value, []): + if first: + first = False + else: + msg = updater.bot.send_message(user, text='Waiting 60 seconds for API... ⏳') + await sleep(60) + msg.delete() + + msg = updater.bot.send_message(user, text='Calculating {}... ⏳'.format(item)) + chart = market.get_wma(item, delta) + msg.delete() + updater.bot.send_message(user, text='*{}*'.format(item), parse_mode=ParseMode.MARKDOWN) + updater.bot.send_photo(user, photo=chart) + + except Exception as e: + print(e) + updater.bot.send_message(user, text='There was an error ⚠️') + finally: + data[Section.Running.value] = False + + +@interval(every=3 * 60 * 60.0, autorun=False, isolated=True) +async def send_updates(): + delta = datetime.now() - timedelta(days=365 * 1) + + for key in persistence.get_user_data().keys(): + await send_update_to_user(user=key, delta=delta) diff --git a/src/Mercatus.py b/src/Mercatus.py index 5bce150..fcbdd71 100644 --- a/src/Mercatus.py +++ b/src/Mercatus.py @@ -1,54 +1,21 @@ -from asyncio import sleep -from datetime import datetime, timedelta -from telegram.ext import Updater, CommandHandler +from telegram.ext import CommandHandler -from Background import interval -from Market import Market -from Utils import persistence, config, Section -from Commands import watchlist_add, watchlist_delete, watchlist_all, watchlist_clear, set_api_key, get_api_key - -updater: Updater = Updater(config['token'], use_context=True, persistence=persistence) - - -@interval(every=1.0 * 60 * 60, autorun=False, isolated=True) -async def send_updates(): - delta = datetime.now() - timedelta(days=365 * 1) - - for key, data in persistence.get_user_data().items(): - if Section.API_Key.value not in data: - continue - - print('Sending updates to {}'.format(key)) - market = Market(data[Section.API_Key.value]) - updater.bot.send_message(key, text='Getting updates 🌎') - first = True - for item in data.get(Section.Watchlist.value, []): - if first: - first = False - else: - msg = updater.bot.send_message(key, text='Waiting 60 seconds for API... ⏳') - await sleep(60) - msg.delete() - - msg = updater.bot.send_message(key, text='Calculating... ⏳') - updater.bot.send_photo(key, photo=market.get_wma(item, delta)) - msg.delete() - updater.bot.send_message(key, text=item) - - # Repeat after every hour - # threading.Timer(1.0 * 60 * 60, send_updates).start() +from Utils import updater +from Commands import watchlist_add, watchlist_delete, watchlist_all, watchlist_clear, \ + set_api_key, get_api_key, start, data, send_updates def main(): - global updater dp = updater.dispatcher 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(CommandHandler('setKey', set_api_key)) - dp.add_handler(CommandHandler('getKey', get_api_key)) + dp.add_handler(CommandHandler('setkey', set_api_key)) + dp.add_handler(CommandHandler('getkey', get_api_key)) + dp.add_handler(CommandHandler('start', start)) + dp.add_handler(CommandHandler('data', data)) print('Started 🚀') send_updates() diff --git a/src/Utils.py b/src/Utils.py index 3703897..01d9742 100644 --- a/src/Utils.py +++ b/src/Utils.py @@ -1,15 +1,17 @@ from telegram import Update -from telegram.ext import PicklePersistence +from telegram.ext import PicklePersistence, Updater from yaml import load, Loader from enum import Enum config = load(open('./config.yml', 'r'), Loader=Loader) -persistence = PicklePersistence('./data/mercatus') +persistence = PicklePersistence('./data.db') +updater: Updater = Updater(config['token'], use_context=True, persistence=persistence) class Section(Enum): Watchlist = 'watchlist' API_Key = 'api_key' + Running = 'running' def parse_command(update: Update) -> (str, str):