From 56e57c4d7f81c60c98205dff1712f94ed9415dfc Mon Sep 17 00:00:00 2001 From: dymik739 Date: Sat, 6 May 2023 18:03:01 +0300 Subject: [PATCH] auto-schedule-pro-v2: add new module as a successor of auto-schedule-pro rewritten to utilize ModuleV2 API --- modules/auto-schedule-pro-v2/additions.json | 1 + modules/auto-schedule-pro-v2/main.py | 179 ++++++++++++++++++++ modules/auto-schedule-pro-v2/meta.json | 6 + modules/auto-schedule-pro-v2/schedule.json | 1 + 4 files changed, 187 insertions(+) create mode 120000 modules/auto-schedule-pro-v2/additions.json create mode 100644 modules/auto-schedule-pro-v2/main.py create mode 100644 modules/auto-schedule-pro-v2/meta.json create mode 120000 modules/auto-schedule-pro-v2/schedule.json diff --git a/modules/auto-schedule-pro-v2/additions.json b/modules/auto-schedule-pro-v2/additions.json new file mode 120000 index 0000000..e266c61 --- /dev/null +++ b/modules/auto-schedule-pro-v2/additions.json @@ -0,0 +1 @@ +../auto-schedule-pro/additions.json \ No newline at end of file diff --git a/modules/auto-schedule-pro-v2/main.py b/modules/auto-schedule-pro-v2/main.py new file mode 100644 index 0000000..f287e16 --- /dev/null +++ b/modules/auto-schedule-pro-v2/main.py @@ -0,0 +1,179 @@ +from datetime import datetime +import json + +def readfile(filename): + with open(module_path + filename) as f: + return f.read() + +# global constants +# Accusative - znahidnyj +WEEKDAYS_ACCUSATIVE = ["понедулок", "вівторок", "середу", "четвер", + "п'ятницю", "суботу", "неділю"] +# Genitive - rodovyj +WEEKDAYS_GENITIVE_NEXT = ["наступного понеділка", "наступного вівторка", + "наступної середи", "наступного четверга", + "наступної п'ятниці", "наступної суботи", + "наступної неділі"] + +WEEKDAYS_GENITIVE_THIS = ["цього понеділка", "цього вівторка", + "цієї середи", "цього четверга", + "цієї п'ятниці", "цієї суботи", + "цієї неділі"] + + +# global variables +module_path = "" + +def get_human_readable_date(start_datetime, end_datetime, + current_day, current_week): + human_readable_date = "" + if ((current_day + 2) == int(start_datetime.strftime("%u"))) or ((current_day == 6) and (start_datetime.strftime("%u") == "1")): + human_readable_date += "завтра " + elif current_week != int(start_datetime.strftime("%W")) % 2: + human_readable_date += f"{WEEKDAYS_GENITIVE_NEXT[int(start_datetime.strftime('%u')) - 1]} " + elif current_day != (int(start_datetime.strftime("%u")) - 1): + human_readable_date += f"{WEEKDAYS_GENITIVE_THIS[int(start_datetime.strftime('%u')) - 1]} " + else: + human_readable_date += "сьогодні " + + human_readable_date += "з " + human_readable_date += start_datetime.strftime("%H:%M") + + human_readable_date += " до " + human_readable_date += end_datetime.strftime("%H:%M") + + return human_readable_date + + +def generate_lesson_description(lesson, start_datetime, end_datetime, + current_day, current_week, overrides = {}): + + output_settings = {"name": True, "date": True, "teacher": True, "link": True} + output_settings.update(overrides) + + result = "" + + if output_settings['name']: + result += f"{lesson['name']}\n" + + if output_settings['date']: + human_readable_date = get_human_readable_date(start_datetime, end_datetime, + current_day, current_week) + result += f"Дата: {human_readable_date}\n" + + if output_settings['teacher']: + result += f"Викладач: {lesson['teacher']}\n" + + if output_settings['link']: + result += f"Посилання на пару: {lesson['link']}" + + return result + + +def get_schedule_data_from(filename): + raw_schedule = json.loads(readfile(filename)) + + baked_schedule = {} + + for daynum, lesson_times in enumerate(raw_schedule): + for lesson_time in lesson_times: + timestamp = daynum*86400 + int(lesson_time.split(":")[0])*3600 \ + + int(lesson_time.split(":")[1])*60 + + new_record = dict(raw_schedule[daynum][lesson_time]) + new_record["source"] = filename.split(".json")[0] + baked_schedule[timestamp] = new_record + + return baked_schedule + + +def process_arguments(args, base_day): + selected_day = int(base_day) + preferences = {} + + for arg in args: + if arg[1:].isdigit(): + selected_day += int(arg[1:]) + continue + + if arg[0] == "-": + preferences[arg[1:]] = False + elif arg[0] == "+": + preferences[arg[1:]] = True + + selected_day = selected_day % 14 + + return preferences, selected_day + + +def get_lesson_description(schedule, reference_time, lesson_time, + current_day, current_week, overrides = {}): + lesson_record = schedule[lesson_time] + + lesson_start_datetime = datetime.fromtimestamp(reference_time + lesson_time) + lesson_end_datetime = datetime.fromtimestamp(reference_time + lesson_time + 5400) + + return generate_lesson_description(lesson_record, lesson_start_datetime, lesson_end_datetime, + current_day, current_week, overrides = overrides) + + +def process(message, path): + message_text = message["text"] + full_command = message_text.split() + + # there is no need to check if the full_command list if empty as it + # never will be - Telegram requires all messages to have at least + # one printable symbol, so this is already protected + base_command = full_command[0].lower() + + if base_command not in ["!пара-beta", "!пари-beta"]: + return "" + + global module_path + module_path = path + + schedule = get_schedule_data_from("schedule.json") + schedule.update(get_schedule_data_from("additions.json")) + + current_time = datetime.now() + + current_week = current_time.isocalendar()[1] % 2 + current_day = current_time.weekday() + + current_seconds = current_week*604800 + current_day*86400 \ + + current_time.hour*3600 + current_time.minute*60 \ + + current_time.second + + reference_time = int(current_time.strftime("%s")) - current_seconds + + if base_command == "!пара-beta": + upcoming_lessons = [timestamp for timestamp in schedule if timestamp > current_seconds-5400] + + if len(upcoming_lessons) > 0: + closest_lesson_time = min(upcoming_lessons) + else: + closest_lesson_time = min(schedule) + + return "Актуальна пара: " + get_lesson_description(schedule, reference_time, + closest_lesson_time, current_day, + current_week) + + elif base_command == "!пари-beta": + base_day = current_week*7 + current_day + + if len(full_command) >= 2: + args = [i for i in full_command[1:] if len(i) > 1] + preferences, selected_day = process_arguments(args, base_day) + else: + preferences = {} + selected_day = base_day + + lesson_list = [i for i in schedule if selected_day*86400 <= i < (selected_day+1)*86400] + + lesson_descriptions_list = ["Назва: " + get_lesson_description(schedule, reference_time, + lesson_time, current_day, + current_week, overrides = preferences) + for lesson_time in lesson_list] + + return f"Пари у {WEEKDAYS_ACCUSATIVE[selected_day % 7]}:\n" \ + + "\n\n".join(lesson_descriptions_list) diff --git a/modules/auto-schedule-pro-v2/meta.json b/modules/auto-schedule-pro-v2/meta.json new file mode 100644 index 0000000..158e18f --- /dev/null +++ b/modules/auto-schedule-pro-v2/meta.json @@ -0,0 +1,6 @@ +{ + "version": 2, + "index_file": "main.py", + "start_on_boot": true, + "alias": "auto-schedule-pro-v2" +} diff --git a/modules/auto-schedule-pro-v2/schedule.json b/modules/auto-schedule-pro-v2/schedule.json new file mode 120000 index 0000000..6775074 --- /dev/null +++ b/modules/auto-schedule-pro-v2/schedule.json @@ -0,0 +1 @@ +../auto-schedule-pro/schedule.json \ No newline at end of file