Initial commit
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/pics/
|
6216
mensa.svg
Normal file
After Width: | Height: | Size: 229 KiB |
6245
mensa_raw.svg
Normal file
After Width: | Height: | Size: 230 KiB |
139
mensaar-map-bot.py
Executable file
@ -0,0 +1,139 @@
|
||||
#!/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
|
6245
resources/aa.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ab.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ac.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ad.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ae.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/af.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ag.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ah.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ai.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/aj.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ak.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/al.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/am.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/an.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ao.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ba.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bb.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bc.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bd.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/be.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bf.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bg.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bh.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bi.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bj.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bk.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bl.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bm.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bn.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bo.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bp.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bq.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/br.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bs.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/bt.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ca.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cb.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cc.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cd.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ce.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cf.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cg.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ch.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ci.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cj.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ck.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cl.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cm.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cn.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/co.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cp.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cq.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cr.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cs.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ct.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cu.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cv.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cw.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cx.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cy.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cz.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cä.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cö.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/cü.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/da.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/db.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dc.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dd.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/de.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/df.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dg.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dh.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/di.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dj.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dk.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dl.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dm.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/dn.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/do.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ea.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/eb.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ec.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ed.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ee.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ef.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/eg.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/eh.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ei.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ej.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ek.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/el.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/em.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/en.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/eo.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/ep.svg
Normal file
After Width: | Height: | Size: 230 KiB |
6245
resources/eq.svg
Normal file
After Width: | Height: | Size: 230 KiB |