#!/usr/bin/python import requests import re import sys import json from datetime import datetime from json.decoder import JSONDecodeError import os POLLING_TIMEOUT = 15 * 60 # 15 minutes token = os.environ["MENSA_BOT_TOKEN"] # the bot's token as obtained by the BotFather pattern = re.compile("[a-zA-ZäöüÄÖÜ]{2}\s*@mensamap") table_indices = { "a": [chr(i) for i in range(ord("a"), ord("o") + 1)], "b": [chr(i) for i in range(ord("a"), ord("t") + 1)], "c": [chr(i) for i in range(ord("a"), ord("z") + 1)] + ["ä", "ö", "ü"], "d": [chr(i) for i in range(ord("a"), ord("o") + 1)], "e": [chr(i) for i in range(ord("a"), ord("s") + 1)], "f": [chr(i) for i in range(ord("a"), ord("m") + 1)], "g": [chr(i) for i in range(ord("a"), ord("s") + 1)], "h": [chr(i) for i in range(ord("a"), ord("h") + 1)], "i": [chr(i) for i in range(ord("a"), ord("f") + 1)] } def log(text, log_file, prepend_time=False): if not log_file: return if prepend_time: log_file.write(str(datetime.now()) + ':\n') log_file.flush() log_file.buffer.write(text.encode("utf-8")) log_file.flush() def send_image(path, chat_id, log_file): try: for old, new in [('ä', 'ae'), ('ö', 'oe'), ('ü', 'ue')]: path = path.replace(old, new) url = f"https://api.telegram.org/bot{token}/sendPhoto"; data = {'chat_id' : chat_id, 'photo': f'http://leafbla.de/mensa/img/{path}'} log(f" SENDING IMAGE:\n file name = {path}\n chat id = {chat_id}\n", log_file) r = requests.post(url, data=data) except: pass def send_map(message, chat_id, log_file): try: m = pattern.search(message) command = m.group() loc = command[:2].lower() grp = loc[0] idx = loc[1] log(f" FOUND COMMAND:\n text = \"{command}\"\n group = {grp}\n table = {idx}\n", log_file) if idx in table_indices[grp]: send_image(f"{loc}.png", chat_id, log_file) except (AttributeError, IndexError, KeyError): pass def get_inline_query_result(s): for old, new in [('ä', 'ae'), ('ö', 'oe'), ('ü', 'ue')]: s = s.replace(old, new) return { "type": "photo", "id": s, "photo_url": "http://leafbla.de/mensa/img/" + s + ".png", "thumb_url": "http://leafbla.de/mensa/thumbs/" + s + ".png", } def answer_inline_query(query_id, request, log_file): print("answer_inline_query") print(query_id, request, log_file) if len(request) == 0: print("handle empty request") results = json.dumps( { "type": "photo", "id": 1, "photo_url": "https://gitea.leafbla.de/img/gitea-lg.png", "thumb_url": "https://gitea.leafbla.de/img/gitea-lg.png", } ) if len(request) == 1 and request in table_indices: results = json.dumps([get_inline_query_result(request + s1) for s1 in table_indices[request]]) elif len(request) == 2 and request[0] in table_indices and request[1] in table_indices[request[0]]: results = json.dumps([get_inline_query_result(request)]) else: results = "[]" data = { "inline_query_id": query_id, "results": results } log(f" ANSWERING INLINE QUERY:\n request = {request}\n query id = {query_id}\n", log_file) requests.post(f"https://api.telegram.org/bot{token}/answerInlineQuery", data=data) def run(log_file=None): update_id = None while True: url = f"https://api.telegram.org/bot{token}/getUpdates" data = {'timeout': POLLING_TIMEOUT} if update_id is not None: data['offset'] = update_id log(f" REQUESTING UPDATE:\n timeout = {data['timeout']}\n offset = {update_id}\n", log_file, prepend_time=True) response = requests.post(url, data=data) log(" RECEIVED RESPONSE:\n", log_file, prepend_time=True) try: j = response.json() update_id = j["result"][-1]["update_id"] + 1 result = j["result"][-1] if "message" in result: msg = result["message"] chat_id = msg["chat"]["id"] text = msg["text"] log(f" update id = {update_id}\n chat id = {chat_id}\n text = \"{text}\"\n", log_file) send_map(text, chat_id, log_file) elif "inline_query" in result: msg = result["inline_query"] query_id = msg["id"] request = msg["query"] answer_inline_query(query_id, request, log_file) except (IndexError, KeyError, JSONDecodeError): log(" no new messages\n", log_file) if __name__ == "__main__": try: path = sys.argv[1] if len(sys.argv) > 1 else None if path == "stdout": run(log_file=sys.stdout) elif path: run(log_file=open(path, 'a')) else: run() except KeyboardInterrupt: pass