Merge branch 'master' of Lonami/xkcdtextbot into master

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

86
bot.py
View File

@ -1,21 +1,14 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from uuid import uuid4
import asyncio
from os import environ
from collections import namedtuple
from json import loads
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
from telethon import TelegramClient, events
from bs4 import BeautifulSoup
# 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={}"
# 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"
MAX_SEARCH_RESULTS = 10
bot = TelegramClient('xkcd', 6, 'eb06d4abfb49dc3eeb1aeb98ae0f581e')
# blockquote element -> Xkcd
def parse_blockquote(elem):
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
# 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."""
# 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."""
# 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."""
# TODO show transcript in result but not message?
query = update.inline_query.query
results = []
for xkcd in get_xkcds(query):
number = xkcd.number
link = xkcd.link
title = xkcd.title
alt = xkcd.alt
builder = event.builder
result = await asyncio.gather(*(builder.article(
title=xkcd.title,
url=xkcd.link,
text=MSG_FMT_STR.format(number=xkcd.number, link=xkcd.link, title=xkcd.title, alt=xkcd.alt)
) for xkcd in get_xkcds(event.text)))
results.append(InlineQueryResultArticle(
id=uuid4(),
title=xkcd.title,
url=xkcd.link,
input_message_content=InputTextMessageContent(
MSG_FMT_STR.format(number=number, link=link, title=title, alt=alt),
parse_mode=ParseMode.MARKDOWN)))
update.inline_query.answer(results)
def error(bot, update, error):
"""Log Errors caused by Updates."""
logger.warning('Update "%s" caused error "%s"', update, error)
# 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())
await event.answer(result)
def main():
# Create the Updater and pass it your bot's token.
updater = Updater(environ["TOKEN"])
# 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()
bot.start(bot_token=environ['TOKEN'])
with bot:
bot.run_until_disconnected()
if __name__ == '__main__':