forked from tan/xkcdtextbot
Use aiohttp instead of requests
This commit is contained in:
parent
5d5ddb7db2
commit
d263f315be
30
bot.py
30
bot.py
|
@ -3,11 +3,10 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
from os import environ
|
from os import environ
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from json import loads
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import requests
|
import aiohttp
|
||||||
from telethon import TelegramClient, events
|
from telethon import TelegramClient, events
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
@ -26,15 +25,17 @@ XKCD_JSON_FMT_STR = "https://xkcd.com/{}/info.0.json"
|
||||||
MAX_SEARCH_RESULTS = 10
|
MAX_SEARCH_RESULTS = 10
|
||||||
|
|
||||||
bot = TelegramClient('xkcd', 6, 'eb06d4abfb49dc3eeb1aeb98ae0f581e')
|
bot = TelegramClient('xkcd', 6, 'eb06d4abfb49dc3eeb1aeb98ae0f581e')
|
||||||
|
session = None # set later
|
||||||
|
|
||||||
# blockquote element -> Xkcd
|
# blockquote element -> Xkcd
|
||||||
def parse_blockquote(elem):
|
async def parse_blockquote(elem):
|
||||||
children = list(elem.children)
|
children = list(elem.children)
|
||||||
title = children[0].text
|
title = children[0].text
|
||||||
link = 'https' + children[-1].text[4:]
|
link = 'https' + children[-1].text[4:]
|
||||||
|
|
||||||
number = link.rsplit('/', 2)[1]
|
number = link.rsplit('/', 2)[1]
|
||||||
info = loads(requests.get(XKCD_JSON_FMT_STR.format(number)).text)
|
async with session.get(XKCD_JSON_FMT_STR.format(number)) as resp:
|
||||||
|
info = await resp.json()
|
||||||
alt = info['alt']
|
alt = info['alt']
|
||||||
|
|
||||||
# TODO markdown bold the <span> matches
|
# TODO markdown bold the <span> matches
|
||||||
|
@ -47,16 +48,17 @@ def parse_blockquote(elem):
|
||||||
return Xkcd(title, link, text, alt, number)
|
return Xkcd(title, link, text, alt, number)
|
||||||
|
|
||||||
# string -> [Xkcd]
|
# string -> [Xkcd]
|
||||||
def get_xkcds(text):
|
async def get_xkcds(text):
|
||||||
logger.info("getting %s", text)
|
logger.info("getting %s", text)
|
||||||
if text == '':
|
if text == '':
|
||||||
return []
|
return []
|
||||||
# TODO return newest when empty
|
# TODO return newest when empty
|
||||||
soup = BeautifulSoup(requests.get(URL_FMT_STR.format(text)).text, "html.parser")
|
async with session.get(URL_FMT_STR.format(text)) as resp:
|
||||||
|
soup = BeautifulSoup(await resp.text(), "html.parser")
|
||||||
|
|
||||||
bqs = soup.find_all("blockquote")[:MAX_SEARCH_RESULTS]
|
bqs = soup.find_all("blockquote")[:MAX_SEARCH_RESULTS]
|
||||||
logger.info(bqs)
|
logger.info(bqs)
|
||||||
return (parse_blockquote(e) for e in bqs)
|
return await asyncio.gather(*(parse_blockquote(e) for e in bqs))
|
||||||
|
|
||||||
|
|
||||||
# Define a few command handlers. These usually take the two arguments bot and
|
# Define a few command handlers. These usually take the two arguments bot and
|
||||||
|
@ -84,7 +86,7 @@ async def inlinequery(event):
|
||||||
title=xkcd.title,
|
title=xkcd.title,
|
||||||
url=xkcd.link,
|
url=xkcd.link,
|
||||||
text=MSG_FMT_STR.format(number=xkcd.number, link=xkcd.link, title=xkcd.title, alt=xkcd.alt)
|
text=MSG_FMT_STR.format(number=xkcd.number, link=xkcd.link, title=xkcd.title, alt=xkcd.alt)
|
||||||
) for xkcd in get_xkcds(event.text)))
|
) for xkcd in await get_xkcds(event.text)))
|
||||||
|
|
||||||
# FIXME get_xkcds returns duplicates, which lead to the same result ID
|
# FIXME get_xkcds returns duplicates, which lead to the same result ID
|
||||||
# Build a dict by their ID to remove the duplicates
|
# Build a dict by their ID to remove the duplicates
|
||||||
|
@ -92,11 +94,13 @@ async def inlinequery(event):
|
||||||
await event.answer(result)
|
await event.answer(result)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
async def main():
|
||||||
bot.start(bot_token=environ['TOKEN'])
|
global session
|
||||||
with bot:
|
async with aiohttp.ClientSession() as session:
|
||||||
bot.run_until_disconnected()
|
await bot.start(bot_token=environ['TOKEN'])
|
||||||
|
async with bot:
|
||||||
|
await bot.run_until_disconnected()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
asyncio.get_event_loop().run_until_complete(main())
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
telethon~=1.7
|
aiohttp~=3.5
|
||||||
requests~=2.21
|
|
||||||
beautifulsoup4~=4.7
|
beautifulsoup4~=4.7
|
||||||
|
telethon~=1.7
|
||||||
|
|
Loading…
Reference in New Issue