@@ -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 )