modular-bot-framework-for-t.../modules/auto-schedule-pro-v2/main.py

174 lines
6.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 day_number, lesson_times in enumerate(raw_schedule):
for lesson_time in lesson_times:
timestamp = day_number * 86400 + int(lesson_time.split(":")[0]) * 3600 \
+ int(lesson_time.split(":")[1]) * 60
new_record = dict(raw_schedule[day_number][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[0] == "-":
if arg[1:].isdigit():
selected_day -= int(arg[1:])
else:
preferences[arg[1:]] = False
elif arg[0] == "+":
if arg[1:].isdigit():
selected_day += int(arg[1:])
else:
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 ["!пара", "!пари"]:
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 == "!пара":
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 == "!пари":
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)