From 5f898f22bbd7130d27d8d0e140e6736658adef6e Mon Sep 17 00:00:00 2001 From: Davide Depau Date: Sun, 24 Jun 2018 15:47:23 +0200 Subject: [PATCH] Port bot to asyncio --- callmebyyourbot/__init__.py | 128 ++++++++++++++++++++---------------- setup.py | 7 +- 2 files changed, 74 insertions(+), 61 deletions(-) diff --git a/callmebyyourbot/__init__.py b/callmebyyourbot/__init__.py index 8c43f64..6d862c1 100644 --- a/callmebyyourbot/__init__.py +++ b/callmebyyourbot/__init__.py @@ -1,7 +1,9 @@ +import asyncio import sys, random + +import aiohttp as aiohttp import traceback -import time -from typing import Sequence, AnyStr +from typing import Sequence from depytg import types, methods, errors HASHTAGS = { @@ -29,76 +31,88 @@ Source code: https://git.depau.eu/Depau/CallMeByYourBot Based on DepyTG: https://github.com/Depau/DepyTG""" -def send_help(token: AnyStr, msg: types.Message): - send_msg = methods.sendMessage(msg.chat.id, HELP_TEXT) - send_msg.reply_to_message_id = msg.message_id - send_msg["disable_web_page_preview"] = True - send_msg(token) +class CallMeByYourBot: + def __init__(self, token: str, loop: asyncio.AbstractEventLoop, session: aiohttp.ClientSession): + self.token = token + self.loop = loop + self.session = session + self._offset = 0 + self.me = None + async def send_help(self, msg: types.Message): + send_msg = methods.sendMessage(msg.chat.id, HELP_TEXT) + send_msg.reply_to_message_id = msg.message_id + send_msg["disable_web_page_preview"] = True + await send_msg.async_call(self.session, self.token) -def parse_message(token: AnyStr, msg: types.Message): - if not 'text' in msg: - return + async def parse_message(self, msg: types.Message): + if not 'text' in msg: + return - if "/help" in msg.text: - if "group" in msg.chat.type: - username = methods.getMe()(token).username + if "/help" in msg.text: + if "group" in msg.chat.type: + username = self.me.username - if msg.text == "/help@{}".format(username): - send_help(token, msg) + if msg.text == "/help@{}".format(username): + await self.send_help(msg) - elif msg.text == "/help": - send_help(token, msg) + elif msg.text == "/help": + await self.send_help(msg) - for hashtag in HASHTAGS: - if hashtag.lower() in msg.text.lower(): - send_photo = methods.sendPhoto(chat_id=msg.chat.id) - send_photo.reply_to_message_id = msg.message_id - send_photo.photo = random.choice(HASHTAGS[hashtag]) - send_photo.caption = hashtag - send_photo(token) + for hashtag in HASHTAGS: + if hashtag.lower() in msg.text.lower(): + send_photo = methods.sendPhoto(chat_id=msg.chat.id) + send_photo.reply_to_message_id = msg.message_id + send_photo.photo = random.choice(HASHTAGS[hashtag]) + send_photo.caption = hashtag + resp = await send_photo.async_call(self.session, self.token) + async def parse_update(self, update: types.Update) -> int: + print(update) + print() -def parse_update(token: AnyStr, update: types.Update) -> int: - print(update) - print() - for i in ('message', 'edited_message', 'channel_post', 'edited_channel_post'): - if i in update: - parse_message(token, update[i]) - break - return update.update_id + for i in ('message', 'edited_message', 'channel_post', 'edited_channel_post'): + if i in update: + asyncio.ensure_future(self.parse_message(update[i])) + break + return update.update_id + async def on_updates(self, updates: Sequence[types.Update]) -> int: + max_id = 0 + for u in updates: + try: + upd_id = await self.parse_update(u) + + if upd_id > max_id: + max_id = upd_id + except errors.TelegramError: + traceback.print_exc(file=sys.stderr) + + return max_id + + async def mainloop(self, offset: int = 0) -> int: + updates = await methods.getUpdates(offset).async_call(self.session, self.token) + return await self.on_updates(updates) + + async def run(self): + self._offset = 0 + self.me = await methods.getMe().async_call(self.session, self.token) -def on_updates(token: AnyStr, updates: Sequence[types.Update]) -> int: - max_id = 0 - for u in updates: try: - upd_id = parse_update(token, u) - - if upd_id > max_id: - max_id = upd_id - except errors.TelegramError: - traceback.print_exc(file=sys.stderr) - - return max_id - - -def mainloop(token: AnyStr, offset: int = 0) -> int: - updates = methods.getUpdates(offset)(token) - return on_updates(token, updates) + while True: + self._offset = await self.mainloop(self._offset) + 1 + except KeyboardInterrupt: + pass def main(): token = sys.argv[1] - prev_offset = 0 - - try: - while True: - prev_offset = mainloop(token, prev_offset) + 1 - time.sleep(0.2) - except KeyboardInterrupt: - pass + loop = asyncio.get_event_loop() + session = aiohttp.ClientSession(loop=loop) + bot = CallMeByYourBot(token, loop, session) + loop.run_until_complete(bot.run()) + loop.close() -if __name__ == "__main__": +if __name__ == '__main__': main() diff --git a/setup.py b/setup.py index b628e98..352a07d 100644 --- a/setup.py +++ b/setup.py @@ -2,15 +2,14 @@ from setuptools import setup setup( name='Call Me By Your Bot', - version='0.1', + version='0.2', packages=['callmebyyourbot'], - url='https://github.com/Depaulicious/', + url='https://git.depau.eu/Depau/CallMeByYourBot', license='', author='Davide Depau', author_email='davide@depau.eu', description='A Telegram bot that replies with a picture of Elio when #TeamElio is sent', - dependency_links=["https://github.com/Depaulicious/DepyTG/archive/wip.zip"], - requires=["DepyTG", "requests"], + requires=["DepyTG[asyncio]", "aiohttp"], entry_points={ 'console_scripts': ['callmebyyourbot=callmebyyourbot:main'], }