Port bot to asyncio

This commit is contained in:
Davide Depau 2018-06-24 15:47:23 +02:00
parent fd692c4df7
commit 5f898f22bb
Signed by: depau
GPG key ID: C7D999B6A55EFE86
2 changed files with 74 additions and 61 deletions

View file

@ -1,7 +1,9 @@
import asyncio
import sys, random import sys, random
import aiohttp as aiohttp
import traceback import traceback
import time from typing import Sequence
from typing import Sequence, AnyStr
from depytg import types, methods, errors from depytg import types, methods, errors
HASHTAGS = { HASHTAGS = {
@ -29,76 +31,88 @@ Source code: https://git.depau.eu/Depau/CallMeByYourBot
Based on DepyTG: https://github.com/Depau/DepyTG""" Based on DepyTG: https://github.com/Depau/DepyTG"""
def send_help(token: AnyStr, msg: types.Message): class CallMeByYourBot:
send_msg = methods.sendMessage(msg.chat.id, HELP_TEXT) def __init__(self, token: str, loop: asyncio.AbstractEventLoop, session: aiohttp.ClientSession):
send_msg.reply_to_message_id = msg.message_id self.token = token
send_msg["disable_web_page_preview"] = True self.loop = loop
send_msg(token) 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): async def parse_message(self, msg: types.Message):
if not 'text' in msg: if not 'text' in msg:
return return
if "/help" in msg.text: if "/help" in msg.text:
if "group" in msg.chat.type: if "group" in msg.chat.type:
username = methods.getMe()(token).username username = self.me.username
if msg.text == "/help@{}".format(username): if msg.text == "/help@{}".format(username):
send_help(token, msg) await self.send_help(msg)
elif msg.text == "/help": elif msg.text == "/help":
send_help(token, msg) await self.send_help(msg)
for hashtag in HASHTAGS: for hashtag in HASHTAGS:
if hashtag.lower() in msg.text.lower(): if hashtag.lower() in msg.text.lower():
send_photo = methods.sendPhoto(chat_id=msg.chat.id) send_photo = methods.sendPhoto(chat_id=msg.chat.id)
send_photo.reply_to_message_id = msg.message_id send_photo.reply_to_message_id = msg.message_id
send_photo.photo = random.choice(HASHTAGS[hashtag]) send_photo.photo = random.choice(HASHTAGS[hashtag])
send_photo.caption = hashtag send_photo.caption = hashtag
send_photo(token) 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: for i in ('message', 'edited_message', 'channel_post', 'edited_channel_post'):
print(update) if i in update:
print() asyncio.ensure_future(self.parse_message(update[i]))
for i in ('message', 'edited_message', 'channel_post', 'edited_channel_post'): break
if i in update: return update.update_id
parse_message(token, 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: try:
upd_id = parse_update(token, u) while True:
self._offset = await self.mainloop(self._offset) + 1
if upd_id > max_id: except KeyboardInterrupt:
max_id = upd_id pass
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)
def main(): def main():
token = sys.argv[1] token = sys.argv[1]
prev_offset = 0 loop = asyncio.get_event_loop()
session = aiohttp.ClientSession(loop=loop)
try: bot = CallMeByYourBot(token, loop, session)
while True: loop.run_until_complete(bot.run())
prev_offset = mainloop(token, prev_offset) + 1 loop.close()
time.sleep(0.2)
except KeyboardInterrupt:
pass
if __name__ == "__main__": if __name__ == '__main__':
main() main()

View file

@ -2,15 +2,14 @@ from setuptools import setup
setup( setup(
name='Call Me By Your Bot', name='Call Me By Your Bot',
version='0.1', version='0.2',
packages=['callmebyyourbot'], packages=['callmebyyourbot'],
url='https://github.com/Depaulicious/', url='https://git.depau.eu/Depau/CallMeByYourBot',
license='', license='',
author='Davide Depau', author='Davide Depau',
author_email='davide@depau.eu', author_email='davide@depau.eu',
description='A Telegram bot that replies with a picture of Elio when #TeamElio is sent', 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[asyncio]", "aiohttp"],
requires=["DepyTG", "requests"],
entry_points={ entry_points={
'console_scripts': ['callmebyyourbot=callmebyyourbot:main'], 'console_scripts': ['callmebyyourbot=callmebyyourbot:main'],
} }