commit 34e2d6b48df2fb2dcadf7ab8abbf2986bb3d593c
parent e601e56875e889ee166a278df668ca3c912042cf
Author: torresjrjr <b.torres.edu@gmail.com>
Date: Fri, 13 Mar 2020 03:51:35 +0000
Error handling, log datetimes, quit secret, DPI
Untested at time of commit!
- Improved DPI of images with API extention "\512dpi".
- New "secret quit method".
- Logs (stdout) have iso-formatted datetimes.
- New error handling callback for cleaner logs.
Diffstat:
M | bot.py | | | 115 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
1 file changed, 72 insertions(+), 43 deletions(-)
diff --git a/bot.py b/bot.py
@@ -1,11 +1,13 @@
#!/usr/bin/python
"""
-This is a Telegram Bot which returns rendered images of LaTeX with an API.
+This is a Telegram Bot which returns rendered images of LaTeX using an API.
"""
import telegram
from telegram.ext import Updater, MessageHandler, CommandHandler, Filters
-import requests
+from telegram.error import (TelegramError, Unauthorized, BadRequest,
+ TimedOut, ChatMigrated, NetworkError)
+import datetime
import urllib
import logging
@@ -15,46 +17,54 @@ logging.basicConfig(
)
-# constants
+# CONSTANTS
try:
- with open('token') as File:
- TOKEN = File.read().splitlines()[0]
-except FileNotFoundError as Err:
+ with open('token') as TokenFile:
+ TOKEN = TokenFile.read().splitlines()[0]
+except FileNotFoundError:
print(
"""
-You need a bot token to run this Telegram bot. Please make a
-file named 'token' with your bot token in there, in the same
-folder as your bot file.
+You need a bot token to run an instance of this Telegram bot.
+Please make a file named 'token' with your bot token in there,
+in the same folder as this bot file.
Learn more at t.me/botfather
""" )
quit()
-API = "https://latex.codecogs.com/png.latex?"
+IMAGE_DPI = 512
+API = f"https://latex.codecogs.com/png.latex?\\{IMAGE_DPI}dpi&space;%s"
EXAMPLE_LATEX = r"x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}"
-# callback handlers
+# UTIL
+
+# Returns a iso-formatted string of datetime at moment of call.
+dt_now = lambda: datetime.datetime.now().isoformat(timespec="seconds")
+
+
+# CALLBACK HANDLERS
def cb_start(upd, ctx):
first_name = upd.message.from_user.first_name
- upd.message.reply_text(
- f"Hello, {first_name}\n"
- "Type some _LaTeX_ and this bot will "
- "return a rendered image of it.\n\n"
+ out_msg = f"""Hello, {first_name}
+Type some _LaTeX_ and this bot will return a rendered image of it.
- "Use /link (_with some LaTeX_) to also return an image link.\n\n"
+Use /link _(with some LaTeX)_ to also return an image link.
- "This bot will support inline queries in the future.\n\n"
+This bot aims to support inline queries in the future.
- "Try the following:\n"
- "```\n"
- f"{EXAMPLE_LATEX}\n"
- "```\n\n"
+Try the following:
- "Author: t.me/torresjrjr",
+```
+{EXAMPLE_LATEX}
+```
+Author: t.me/torresjrjr
+"""
+ upd.message.reply_text(
+ out_msg,
parse_mode=telegram.ParseMode.MARKDOWN,
)
@@ -63,53 +73,72 @@ def cb_help(upd, ctx):
cb_start(upd, ctx)
-def cb_echo(upd, ctx):
- ctx.bot.send_message(
- chat_id = upd.effective_chat.id,
- text = upd.message.text,
- )
-
-
def handler(upd, ctx, kind="standard"):
- msg = upd.message.text
- print("Incomming message:", msg)
+ msg = upd.message.text
+ name = upd.message.from_user.name
+ log_msg = f"{dt_now()} :: {name}\t:: {msg}"
+ print(log_msg)
- if kind == "linked": latex = msg[5:] # remove the "/link" part
- else: latex = msg
+ if kind == "link": latex = msg.replace("/link","")
+ else : latex = msg
encoded_latex = urllib.parse.quote(latex)
- latex_url = API + encoded_latex
+ latex_url = API % encoded_latex
- if kind == "standard": caption = f"`{msg}`"
- elif kind == "linked": caption = f"`{msg}`" + "\n" + latex_url
+ if kind == "standard": caption = f"`{latex}`"
+ elif kind == "linked" : caption = f"`{latex}`" + "\n" + latex_url
ctx.bot.send_photo(
- chat_id = upd.effective_chat.id,
- photo = latex_url,
- caption = caption,
+ chat_id = upd.effective_chat.id,
+ photo = latex_url,
+ caption = caption,
parse_mode = telegram.ParseMode.MARKDOWN,
)
-cb_link = lambda upd, ctx: handler(upd, ctx, kind="linked")
+cb_link = lambda upd, ctx: handler(upd, ctx, kind="link")
cb_handler = lambda upd, ctx: handler(upd, ctx)
+cb_QUITBOT = lambda upd, ctx: quit()
+
+
+def cb_error(update, context):
+ try:
+ raise context.error
+ except Unauthorized as e:
+ print("Error:", e) # remove update.message.chat_id from conversation list
+ except BadRequest as e:
+ print("Error:", e) # handle malformed requests - read more below!
+ except TimedOut as e:
+ print("Error:", e) # handle slow connection problems
+ except NetworkError as e:
+ print("Error:", e) # handle other connection problems
+ except ChatMigrated as e:
+ print("Error:", e) # the chat_id of a group has changed, use e.new_chat_id instead
+ except TelegramError as e:
+ print("Error:", e) # handle all other telegram related errors
-# main
+# MAIN
def main():
- print("Running...")
+ print("Starting bot...")
+
updater = Updater(TOKEN, use_context=True)
dp = updater.dispatcher
+ dp.add_error_handler(cb_error)
dp.add_handler(CommandHandler('start' , cb_start))
dp.add_handler(CommandHandler('help' , cb_help))
dp.add_handler(CommandHandler('link' , cb_link))
+ dp.add_handler(CommandHandler('QUITBOT' , cb_QUITBOT))
dp.add_handler(MessageHandler(Filters.text, cb_handler))
+ print(dt_now(), "Serving...")
+
updater.start_polling()
updater.idle()
- print("Done.")
+
+ print(dt_now(), "Ended.")
if __name__=='__main__':