Merge branch 'master' of Lonami/xkcdtextbot into master

This commit is contained in:
Lonami 2019-05-11 20:26:41 +02:00 committed by Gitea
commit c022d559a4
1 changed files with 27 additions and 59 deletions

82
bot.py
View File

@ -1,21 +1,14 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import asyncio
from uuid import uuid4
from os import environ from os import environ
from collections import namedtuple from collections import namedtuple
from json import loads from json import loads
import logging import logging
from telegram import InlineQueryResultArticle
from telegram import InputTextMessageContent
from telegram import ParseMode
from telegram.ext import CommandHandler
from telegram.ext import InlineQueryHandler
from telegram.ext import Updater
import requests import requests
from telethon import TelegramClient, events
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
# Enable logging # Enable logging
@ -28,10 +21,12 @@ Xkcd = namedtuple('Xkcd', ['title', 'link', 'transcript', 'alt', 'number'])
URL_FMT_STR = "http://www.ohnorobot.com/index.php?Search=Search&comic=56&s={}" URL_FMT_STR = "http://www.ohnorobot.com/index.php?Search=Search&comic=56&s={}"
# FIXME HTML parsemode + escaping # FIXME HTML parsemode + escaping
MSG_FMT_STR = "[{number}]({link}): *{title}*\n\n_{alt}_" MSG_FMT_STR = "[{number}]({link}): **{title}**\n\n__{alt}__"
XKCD_JSON_FMT_STR = "https://xkcd.com/{}/info.0.json" XKCD_JSON_FMT_STR = "https://xkcd.com/{}/info.0.json"
MAX_SEARCH_RESULTS = 10 MAX_SEARCH_RESULTS = 10
bot = TelegramClient('xkcd', 6, 'eb06d4abfb49dc3eeb1aeb98ae0f581e')
# blockquote element -> Xkcd # blockquote element -> Xkcd
def parse_blockquote(elem): def parse_blockquote(elem):
children = list(elem.children) children = list(elem.children)
@ -66,68 +61,41 @@ def get_xkcds(text):
# 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
# update. Error handlers also receive the raised TelegramError object in error. # update. Error handlers also receive the raised TelegramError object in error.
def start(bot, update): @bot.on(events.NewMessage(pattern='/start$'))
async def start(event):
"""Send a message when the command /start is issued.""" """Send a message when the command /start is issued."""
# TODO # TODO
update.message.reply_text('Hi!') await event.respond('Hi!')
def help(bot, update): @bot.on(events.NewMessage(pattern='/help$'))
async def help(event):
"""Send a message when the command /help is issued.""" """Send a message when the command /help is issued."""
# TODO # TODO
update.message.reply_text('Help!') await event.respond('Help!')
def inlinequery(bot, update):
@bot.on(events.InlineQuery)
async def inlinequery(event):
"""Handle the inline query.""" """Handle the inline query."""
# TODO show transcript in result but not message? # TODO show transcript in result but not message?
query = update.inline_query.query builder = event.builder
results = [] result = await asyncio.gather(*(builder.article(
for xkcd in get_xkcds(query):
number = xkcd.number
link = xkcd.link
title = xkcd.title
alt = xkcd.alt
results.append(InlineQueryResultArticle(
id=uuid4(),
title=xkcd.title, title=xkcd.title,
url=xkcd.link, url=xkcd.link,
input_message_content=InputTextMessageContent( text=MSG_FMT_STR.format(number=xkcd.number, link=xkcd.link, title=xkcd.title, alt=xkcd.alt)
MSG_FMT_STR.format(number=number, link=link, title=title, alt=alt), ) for xkcd in get_xkcds(event.text)))
parse_mode=ParseMode.MARKDOWN)))
update.inline_query.answer(results) # FIXME get_xkcds returns duplicates, which lead to the same result ID
# Build a dict by their ID to remove the duplicates
result = list({r.id: r for r in result}.values())
def error(bot, update, error): await event.answer(result)
"""Log Errors caused by Updates."""
logger.warning('Update "%s" caused error "%s"', update, error)
def main(): def main():
# Create the Updater and pass it your bot's token. bot.start(bot_token=environ['TOKEN'])
updater = Updater(environ["TOKEN"]) with bot:
bot.run_until_disconnected()
# Get the dispatcher to register handlers
dp = updater.dispatcher
# on different commands - answer in Telegram
dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("help", help))
# on noncommand i.e message - echo the message on Telegram
dp.add_handler(InlineQueryHandler(inlinequery))
# log all errors
dp.add_error_handler(error)
# Start the Bot
updater.start_polling()
# Block until the user presses Ctrl-C or the process receives SIGINT,
# SIGTERM or SIGABRT. This should be used most of the time, since
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__': if __name__ == '__main__':