From debfa91167225daa5ec91bfdaa97152d22c075fa Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 8 Feb 2024 07:47:01 +0100 Subject: [PATCH] initial try --- fosdem_video_progress.py | 71 ++++++++++++++++++++++++++++++++++++++++ notes | 7 ++++ 2 files changed, 78 insertions(+) create mode 100644 fosdem_video_progress.py create mode 100644 notes diff --git a/fosdem_video_progress.py b/fosdem_video_progress.py new file mode 100644 index 0000000..6336384 --- /dev/null +++ b/fosdem_video_progress.py @@ -0,0 +1,71 @@ +import pickle +from matplotlib import pyplot as plt +import requests +import json +from datetime import datetime +from dataclasses import dataclass +from collections import defaultdict +from time import sleep +from pathlib import Path + +api_url = r'https://review.video.fosdem.org/api/v1/event/1/overview' +poll_rate = 10*60 # seconds +pickle_file = Path(r'./talk_data.pickle') + +@dataclass +class TimeSeries: + "The object to pickle and unpickle" + states: set[str] + jobstates: set[str] + data: dict[datetime, tuple[dict[str, int], dict[str, int]]] # time → (states(name → count), jobstates(ditto)) + +def get_data() -> tuple[datetime, dict[str, int], dict[str, int]]: + resp = requests.get(api_url) + # TODO: error handling? + time = datetime.now().astimezone() + data = json.loads(resp.content.decode()) + states = defaultdict(lambda: 0) + jobstates = defaultdict(lambda: 0) + # should be an array/list + for talk in data: + states[talk['state']] += 1 + jobstates[talk['progress']] += 1 + return time, states, jobstates + + +def main(): + if pickle_file.exists(): + with open(pickle_file, 'rb') as f: + ts = pickle.load(f) + else: + print("New time series.") + ts = TimeSeries(states=[], data=[]) + + while True: + time, states, jobstates = get_data() + assert time not in ts.data + ts.data[time] = (states, jobstates) + ts.states |= states + ts.jobstates |= jobstates + + # Save the pickle + # Should probably save elsewhere and do atomic rename, but whatever. + with open(pickle_file, 'wb') as f: + pickle.dump(ts, f) + + # Show the plot + x = sorted(ts.data.keys()) # times + # vvv should be a defaultdict anyway, but let's be defensive :-) + ys = [tuple(ts.data[time][0].get(state, 0) for state in ts.states) for time in x] # numbers per state + # We do not show jobstates atm. Too lazy. + # ys are transposed – we need vectors by times, not by states. + ys = list(zip(*ys)) + plt.stackplot(x, *ys) + plt.show(block=False) + + sleep(poll_rate) + plt.close() + plt.clf() + + +main() diff --git a/notes b/notes new file mode 100644 index 0000000..bc3bd5a --- /dev/null +++ b/notes @@ -0,0 +1,7 @@ +https://review.video.fosdem.org/api/v1/event/1/overview +^^ current status +(There seems to be some api about the api in /api/v1/, but have not read that yet.) + +matplotlib stackplot + +Makes sense to scrape every ~10 minutes, the stuff goes slow. Also probably want some kind of saving of the data. Pickle?