From a5a07d447dbc4b415675932633db20c6278d28f5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 16 Jan 2023 01:03:07 +0100 Subject: [PATCH 1/4] Also ignore alerts modules --- main.py | 23 ++++++++++++----------- modules/__init__.py | 7 ++++++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index 0ba91dc..6cf1bff 100644 --- a/main.py +++ b/main.py @@ -80,16 +80,17 @@ def main(only_on_coming_evt=False, ignore_module=[], **config_args): shape.append(WidgetPlacement(IcalModule, config, size=(480-int(480/1.6), 255), position=(0, 250))) occuped_space = 0 - ical = IcalModule(config) - evt_coming = ical.non_local_event_coming(config) or ical.local_event_ending(config) - if evt_coming: - from modules.ratp import RATPNextStopModule - nstops = RATPNextStopModule().draw_module(config, ["RB/cite+universitaire", "M7/porte+d'italie"], int(480/1.6), 275) - image.paste(nstops, (480-int(480/1.6), 255)) - occuped_space = nstops.height - elif only_on_coming_evt: - # stop here in this case - return + if "IcalModule" not in ignore_module: + ical = IcalModule(config) + evt_coming = ical.non_local_event_coming(config) or ical.local_event_ending(config) + if evt_coming: + from modules.ratp import RATPNextStopModule + nstops = RATPNextStopModule().draw_module(config, ["RB/cite+universitaire", "M7/porte+d'italie"], int(480/1.6), 275) + image.paste(nstops, (480-int(480/1.6), 255)) + occuped_space = nstops.height + elif only_on_coming_evt: + # stop here in this case + return if occuped_space < 250: # weekly weather @@ -145,7 +146,7 @@ def main(only_on_coming_evt=False, ignore_module=[], **config_args): from modules import AlertsModule - mod = AlertsModule(alerts).draw_module(config, 480, 330) + mod = AlertsModule(alerts, ignore_module).draw_module(config, 480, 330) if mod.height > 260: image.paste(mod, (0, 580-mod.height+67), mod) elif mod.height < 100: diff --git a/modules/__init__.py b/modules/__init__.py index 2452a0c..4f87ace 100644 --- a/modules/__init__.py +++ b/modules/__init__.py @@ -90,9 +90,10 @@ class RuleModule: class AlertsModule: - def __init__(self, alerts=[]): + def __init__(self, alerts=[], ignore_module=[]): self.icon_size = 50 self.alerts = alerts + self.ignore_module = ignore_module def draw_alert(self, alert, width, image, draw, fnt_R, fnt_B, align, font_size): if "icon" in alert and alert["icon"] is not None: @@ -151,6 +152,10 @@ class AlertsModule: alert = alert["module"] if isinstance(alert, type): + if alert.__name__ in self.ignore_module: + logging.info("Skip module " + alert.__name__ + ", as requested by arguments") + continue + try: for alert in alert(*args_module).gen_alerts(*args_func): align = self.draw_alert(alert, width, image, draw, fnt_R, fnt_B, align, font_size) From 9dd2cc56241d09094ddba0040938a869a49032c3 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 16 Jan 2023 02:26:06 +0100 Subject: [PATCH 2/4] New options to force coming event detection to True --- main.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 6cf1bff..f53e4d6 100644 --- a/main.py +++ b/main.py @@ -45,7 +45,7 @@ class WidgetPlacement: self.kwargs = kwargs -def main(only_on_coming_evt=False, ignore_module=[], **config_args): +def main(only_on_coming_evt=False, ignore_module=[], force_coming_event=True, **config_args): image = Image.new('1', (480, 800), 255) #image = Image.new('L', (480, 800), 'white') draw = ImageDraw.Draw(image) @@ -80,9 +80,9 @@ def main(only_on_coming_evt=False, ignore_module=[], **config_args): shape.append(WidgetPlacement(IcalModule, config, size=(480-int(480/1.6), 255), position=(0, 250))) occuped_space = 0 - if "IcalModule" not in ignore_module: + if "IcalModule" not in ignore_module or force_coming_event: ical = IcalModule(config) - evt_coming = ical.non_local_event_coming(config) or ical.local_event_ending(config) + evt_coming = force_coming_event or ical.non_local_event_coming(config) or ical.local_event_ending(config) if evt_coming: from modules.ratp import RATPNextStopModule nstops = RATPNextStopModule().draw_module(config, ["RB/cite+universitaire", "M7/porte+d'italie"], int(480/1.6), 275) @@ -192,6 +192,8 @@ if __name__ == '__main__': parser.add_argument('--ignore-module', '-I', nargs="*", default=[], help='Ignore the given modules') + parser.add_argument('--force-coming-evt', '-E', action='store_const', const=True, + help='Consider an event coming, whatever calendar says') parser.add_argument('--only-on-coming-evt', '-O', action='store_const', const=True, help='Refresh screen only if there is upcoming event') parser.add_argument('--cache-timeout', '-C', type=int, default=90, @@ -204,6 +206,7 @@ if __name__ == '__main__': main( args.only_on_coming_evt, args.ignore_module, + args.force_coming_evt, cache_timeout=args.cache_timeout, max_cache_timeout=args.max_cache_timeout, ) From 20916e60d1433ba0acb5383d69ed2f3743019577 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 16 Jan 2023 02:27:23 +0100 Subject: [PATCH 3/4] RATP: Keep using ratp.p0m.fr to get schedules --- modules/ratp.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ratp.py b/modules/ratp.py index 73f33f4..b4a0c65 100644 --- a/modules/ratp.py +++ b/modules/ratp.py @@ -92,7 +92,7 @@ class IDFMAPI: cache_file = self._cached_file % ("schedule-" + mode + "-" + line + "-" + hashlib.md5((mode + line + station + way).encode()).hexdigest()) - req = urllib.request.Request(self.baseurl + "/stop-monitoring?MonitoringRef=STIF:StopPoint:Q:" + IDFMAPI.stops[mode][line][station] + ":", headers={'apikey': self.apikey}) + req = urllib.request.Request("https://ratp.p0m.fr/api/schedules/%s/%s/%s/%s" % (mode, line, station, way)) try: with urllib.request.urlopen(req) as f: with open(cache_file, 'wb') as fd: @@ -108,7 +108,7 @@ class IDFMAPI: res = json.load(f) # Convert time to hours - now = datetime.fromisoformat(res["_metadata"]["date"]) + now = datetime.fromisoformat(res["_metadata"]["date"] if len(res["_metadata"]["date"]) <= 25 else res["_metadata"]["date"][0:19] + res["_metadata"]["date"][len(res["_metadata"]["date"])-6:]) for i in range(len(res["result"]["schedules"])): if "message" in res["result"]["schedules"][i]: @@ -294,10 +294,10 @@ class RATPNextStopModule: api = IDFMAPI(config) for stop in stops: - tmp = stop.split("/") + tmp = stop.split("/", 2) mode = tmp[0][0] line = tmp[0][1:] - if 1 < len(tmp) < 3: + if 1 < len(tmp) < 4: prep = {} for s in api.get_schedules(mode, line, *tmp[1:]): if s["destination"] not in prep: From 36068e9d106803c738442fe003d3d546d9685b80 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 16 Jan 2023 02:28:10 +0100 Subject: [PATCH 4/4] RATP: get schedule can return alerts too --- main.py | 3 ++- modules/ratp.py | 71 ++++++++++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/main.py b/main.py index f53e4d6..a1676d5 100644 --- a/main.py +++ b/main.py @@ -85,9 +85,10 @@ def main(only_on_coming_evt=False, ignore_module=[], force_coming_event=True, ** evt_coming = force_coming_event or ical.non_local_event_coming(config) or ical.local_event_ending(config) if evt_coming: from modules.ratp import RATPNextStopModule - nstops = RATPNextStopModule().draw_module(config, ["RB/cite+universitaire", "M7/porte+d'italie"], int(480/1.6), 275) + nstops, nalerts = RATPNextStopModule().draw_module(config, ["RB/cite+universitaire/A", "M7/porte+d'italie/A", "B125/raspail+++jaures/A"], int(480/1.6), 275) image.paste(nstops, (480-int(480/1.6), 255)) occuped_space = nstops.height + alerts += nalerts elif only_on_coming_evt: # stop here in this case return diff --git a/modules/ratp.py b/modules/ratp.py index b4a0c65..1e14c5a 100644 --- a/modules/ratp.py +++ b/modules/ratp.py @@ -287,6 +287,8 @@ class RATPNextStopModule: image = Image.new('RGB', (width, height), '#fff') draw = ImageDraw.Draw(image) + alerts = [] + fnt_R = ImageFont.truetype(IDFMAPI.fnt_R_path, line_height) fnt_B = ImageFont.truetype(IDFMAPI.fnt_RB_path, line_height) @@ -297,47 +299,54 @@ class RATPNextStopModule: tmp = stop.split("/", 2) mode = tmp[0][0] line = tmp[0][1:] - if 1 < len(tmp) < 4: - prep = {} - for s in api.get_schedules(mode, line, *tmp[1:]): - if s["destination"] not in prep: - prep[s["destination"]] = [] - prep[s["destination"]].append(s) + try: + if 1 < len(tmp) < 4: + prep = {} + for s in api.get_schedules(mode, line, *tmp[1:]): + if s["destination"] not in prep: + prep[s["destination"]] = [] + prep[s["destination"]].append(s) - icon = IDFMAPI.get_line_icon(mode, line, int(line_height*(1.5 if len(prep.keys()) > 1 else 1))) - image.paste(icon, (0, align), icon) + icon = IDFMAPI.get_line_icon(mode, line, int(line_height*(1.5 if len(prep.keys()) > 1 else 1))) + image.paste(icon, (0, align), icon) - max_dest = 64 - for dest, msgs in prep.items(): - if len(msgs) == 0: - continue + max_dest = 64 + for dest, msgs in prep.items(): + if len(msgs) == 0: + continue - align_x = line_height * 2 + align_x = line_height * 2 - sz = fnt_B.getsize(dest)[0] - while sz > max_dest: - dest = dest[:-1] sz = fnt_B.getsize(dest)[0] + while sz > max_dest: + dest = dest[:-1] + sz = fnt_B.getsize(dest)[0] - draw.text( - (align_x, align), - dest, - font=fnt_B, anchor="lt", fill="black" - ) - - align_x += max_dest + int(line_height/2.5) - - for msg in [] + msgs + msgs: draw.text( (align_x, align), - msg["message"], - font=fnt_R, anchor="lt", fill="black" + dest, + font=fnt_B, anchor="lt", fill="black" ) - align_x += fnt_R.getsize(msg["message"])[0] + int(line_height/2.5) - align += line_height - align += int(line_height * 0.33) + align_x += max_dest + int(line_height/2.5) + + for msg in [] + msgs + msgs: + draw.text( + (align_x, align), + msg["message"], + font=fnt_R, anchor="lt", fill="black" + ) + align_x += fnt_R.getsize(msg["message"])[0] + int(line_height/2.5) + + align += line_height + align += int(line_height * 0.33) + except Exception as e: + alerts.append({ + "title": "Impossible de récupérer les horaires du " + mode + line + " pour " + tmp[1], + "description": type(e).__name__ + ": " + (e.message if hasattr(e, 'message') else str(e)), + "icon": "wi-earthquake.png", + }) image = image.crop((0,0,width, min(align, height))) - return image + return image, alerts