Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

2 changed files with 20 additions and 41 deletions

58
bot.py
View File

@ -1,15 +1,14 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import asyncio
import html
from os import environ
from collections import namedtuple
from json import loads
import logging
import aiohttp
import requests
from telethon import TelegramClient, events
from telethon.tl.custom import Button
from bs4 import BeautifulSoup
# Enable logging
@ -21,25 +20,21 @@ logger = logging.getLogger(__name__)
Xkcd = namedtuple('Xkcd', ['title', 'link', 'transcript', 'alt', 'number'])
URL_FMT_STR = "http://www.ohnorobot.com/index.php?Search=Search&comic=56&s={}"
MSG_FMT_STR = '<a href="{link}">{number}</a>: <b>{title}</b>\n\n<i>{alt}</i>'
# FIXME HTML parsemode + escaping
MSG_FMT_STR = "[{number}]({link}): **{title}**\n\n__{alt}__"
XKCD_JSON_FMT_STR = "https://xkcd.com/{}/info.0.json"
MAX_SEARCH_RESULTS = 10
bot = TelegramClient('xkcd', 6, 'eb06d4abfb49dc3eeb1aeb98ae0f581e')
bot.parse_mode = 'html'
session = None # set later
me = None # set later
# blockquote element -> Xkcd
async def parse_blockquote(elem):
def parse_blockquote(elem):
children = list(elem.children)
title = children[0].text
link = 'https' + children[-1].text[4:]
number = link.rsplit('/', 2)[1]
async with session.get(XKCD_JSON_FMT_STR.format(number)) as resp:
info = await resp.json()
info = loads(requests.get(XKCD_JSON_FMT_STR.format(number)).text)
alt = info['alt']
# TODO markdown bold the <span> matches
@ -52,17 +47,16 @@ async def parse_blockquote(elem):
return Xkcd(title, link, text, alt, number)
# string -> [Xkcd]
async def get_xkcds(text):
def get_xkcds(text):
logger.info("getting %s", text)
if text == '':
return []
# TODO return newest when empty
async with session.get(URL_FMT_STR.format(text)) as resp:
soup = BeautifulSoup(await resp.text(), "html.parser")
soup = BeautifulSoup(requests.get(URL_FMT_STR.format(text)).text, "html.parser")
bqs = soup.find_all("blockquote")[:MAX_SEARCH_RESULTS]
logger.info(bqs)
return await asyncio.gather(*(parse_blockquote(e) for e in bqs))
return (parse_blockquote(e) for e in bqs)
# Define a few command handlers. These usually take the two arguments bot and
@ -70,19 +64,15 @@ async def get_xkcds(text):
@bot.on(events.NewMessage(pattern='/start$'))
async def start(event):
"""Send a message when the command /start is issued."""
await event.respond(
f"Hello! I'm {me.username} and I search for XKCD when used inline.",
buttons=Button.switch_inline('Try it!', 'cheaply')
)
# TODO
await event.respond('Hi!')
@bot.on(events.NewMessage(pattern='/help$'))
async def help(event):
"""Send a message when the command /help is issued."""
await event.respond(
f"I only work inline, and it is my job to search for XKCD comics!",
buttons=Button.switch_inline('Try it!', 'cheaply')
)
# TODO
await event.respond('Help!')
@bot.on(events.InlineQuery)
@ -93,13 +83,8 @@ async def inlinequery(event):
result = await asyncio.gather(*(builder.article(
title=xkcd.title,
url=xkcd.link,
text=MSG_FMT_STR.format(
number=xkcd.number,
link=xkcd.link,
title=html.escape(xkcd.title),
alt=html.escape(xkcd.alt)
)
) for xkcd in await get_xkcds(event.text)))
text=MSG_FMT_STR.format(number=xkcd.number, link=xkcd.link, title=xkcd.title, alt=xkcd.alt)
) for xkcd in get_xkcds(event.text)))
# FIXME get_xkcds returns duplicates, which lead to the same result ID
# Build a dict by their ID to remove the duplicates
@ -107,14 +92,11 @@ async def inlinequery(event):
await event.answer(result)
async def main():
global session, me
async with aiohttp.ClientSession() as session:
await bot.start(bot_token=environ['TOKEN'])
async with bot:
me = await bot.get_me()
await bot.run_until_disconnected()
def main():
bot.start(bot_token=environ['TOKEN'])
with bot:
bot.run_until_disconnected()
if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(main())
main()

View File

@ -1,3 +0,0 @@
aiohttp~=3.5
beautifulsoup4~=4.7
telethon~=1.7