From ad58e198f24f25e6cfda1677dbbe710ac4f79e5d Mon Sep 17 00:00:00 2001 From: clemens Date: Mon, 6 Nov 2017 19:15:14 +0100 Subject: [PATCH] Initialer Commit --- bot.py | 86 ++++++++++++++++++++++++++++++++++++++++++++ plot.py | 73 +++++++++++++++++++++++++++++++++++++ requirements.txt | 2 ++ settings.sample.json | 12 +++++++ 4 files changed, 173 insertions(+) create mode 100644 bot.py create mode 100644 plot.py create mode 100644 requirements.txt create mode 100644 settings.sample.json diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..846cd8f --- /dev/null +++ b/bot.py @@ -0,0 +1,86 @@ +import argparse +import datetime +import json +import time +from tempfile import NamedTemporaryFile + +import requests +import schedule + + +def parse_time(string): + return datetime.datetime.strptime(string, "%Y-%m-%d %H:%M:%S") + +def get_status(): + status = requests.get("https://isfswiaiopen.wiai.de?json").json() + status["timestamp"] = parse_time(status['timestamp']) + return status + +def get_status_text(src=get_status): + if get_status()["doorstate"]: + text = "fs WIAI is open :)" + else: + text = "fs WIAI is closed :(" + return text + +def post(chats, text, token): + url = "https://api.telegram.org/bot{token}/sendMessage".format(token=token) + for chat in chats: + requests.post(url, data={'chat_id': chats[chat], "text": text}) + +def main(args={"config": "settings.json"}): + text = get_status_text() + config = json.load(open(args['config'])) + post(config['groups'], text, config['token']) + post_plot(config) + +def loop(args={"config": "settings.json"}): + config = json.load(open(args['config'])) + while True: + try: + do_loop(config) + except Exception as e: + print(e, e.args) + time.sleep(config['sleep']) + +def do_loop(config): + last_state = None + while True: + changed = False + new_state = get_status() + if last_state is None: + changed = True + elif not last_state["doorstate"] == new_state["doorstate"]: + changed = True + if changed: + last_state = new_state + text = get_status_text(lambda: last_state) + post(config["groups"], text, config["token"]) + schedule.run_pending() + time.sleep(config['sleep']) + +def post_plot(config): + from plot import get_plot + target= NamedTemporaryFile() + image_url = 'https://api.telegram.org/bot{token}/sendPhoto'.format(token=config['token']) + files = {'photo': get_plot(target)} + for chat in config['groups']: + files['photo'].seek(0) + values = {"chat_id":config['groups'][chat]} + r = requests.post(image_url, files=files, data=values) + print(r) + +def setup(config): + schedule.every(30).seconds.do(lambda: post_plot(config)) + #schedule.every().week.do(post_plot) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="DoorStateBot") + parser.add_argument("--config", "-c", default="settings.json", help="Configuration file") + parser.add_argument("--loop", "-l", action="store_true", help="Loop") + args = parser.parse_args() + setup(vars(args)) + if args.loop: + loop(vars(args)) + else: + main(vars(args)) \ No newline at end of file diff --git a/plot.py b/plot.py new file mode 100644 index 0000000..7f6143b --- /dev/null +++ b/plot.py @@ -0,0 +1,73 @@ +import argparse +from datetime import datetime, timedelta +import json + +import requests +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt +import matplotlib.patches as mpatches +import numpy as np + + +DAYS_ABBR = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"] + + +def parse_time(string): + return datetime.strptime(string, "%Y-%m-%d %H:%M:%S") + + +def plot(raw, target="wiai.png"): + data = np.zeros([7, 24]) + last = (parse_time(raw[0]['timestamp']), 0) + increment = timedelta(hours=1) + for log in raw: + date = parse_time(log['timestamp']) + state = log["doorstate"] + + delta = date - last[0] + if delta.seconds >= 3600: + for i in range(1, int(delta / increment)): + intermediate = last[0] + (increment * i) + data[intermediate.weekday()][intermediate.hour] += 1 + + data[date.weekday()][date.hour] += state + last = (date, state) + + values = np.unique(data.ravel()) + fig, ax = plt.subplots() + im = ax.imshow(data) + ax.set_yticks(np.arange(7)) + ax.set_yticklabels(DAYS_ABBR) + ax.set_xticks(np.arange(24)) + + colors = [ im.cmap(im.norm(value)) for value in values ] + patches = [ mpatches.Patch(color=colors[i], label=str(values[i])) for i in range(len(values))] + plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) + plt.savefig(target, format="PNG", transparent=True, bbox_inches="tight") + return target + + +def local(): + with open("log") as src: + raw = json.load(src) + plot(raw) + + +def prod(): + plot(requests.get('https://isfswiaiopen.wiai.de/log').json()) + +def get_plot(target): + return plot(requests.get('https://isfswiaiopen.wiai.de/log').json(), target=target) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description="plot openness of FS WIAI") + parser.add_argument('-l', '--local', action='store_true') + parser.add_argument('-o', '--output', default="wiai.png") + + args = parser.parse_args() + if args.local: + local(args.output) + else: + prod(args.output) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..651d147 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +requests +schedule \ No newline at end of file diff --git a/settings.sample.json b/settings.sample.json new file mode 100644 index 0000000..62fa900 --- /dev/null +++ b/settings.sample.json @@ -0,0 +1,12 @@ +{ + "token": "BOTID:TOKEN", + "sleep": 30, + "groups":{ + "wiaidoor": -12357567 + }, + "disabled":{ + "WIAIdoorTest": -234502, + "name": -1333, + "fswiai main": -1001 + } +}