From 3e8fd2843d9b113047e62c3348eaec5316418573 Mon Sep 17 00:00:00 2001 From: Nicolas ROCHE Date: Tue, 1 Dec 2020 16:34:54 +0100 Subject: [PATCH] templatetags: get badges from night hours (#48919) --- combo_plugin_gnm/templatetags/gnm.py | 64 ++++++++++++++++++++++------ tests/test_as_opening_hours.py | 6 +-- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/combo_plugin_gnm/templatetags/gnm.py b/combo_plugin_gnm/templatetags/gnm.py index 3541c7a..96147ce 100644 --- a/combo_plugin_gnm/templatetags/gnm.py +++ b/combo_plugin_gnm/templatetags/gnm.py @@ -83,11 +83,26 @@ def get_open_close_from_specification(specification, valid_from, base_datetime): if not isinstance(specification['dayOfWeek'], str): raise ValueError() day_number = EN_FULL_WEEKDAYS_LIST.index(specification['dayOfWeek'].split('/')[-1]) - opening_time = opening_time + datetime.timedelta( + start = opening_time + datetime.timedelta( days=(7 + (day_number - opening_time.weekday())) % 7) - closing_time = closing_time + datetime.timedelta( + end = closing_time + datetime.timedelta( days=(7 + (day_number - closing_time.weekday())) % 7) - return (opening_time, closing_time, day_number) + + # hours may belongs on next day + if end < start: + day_number += 1 + end = closing_time + datetime.timedelta( + days=(7 + (day_number - closing_time.weekday())) % 7) + if end < start: + # end time may be find this week whereas start time is picked on next week, + # this occure if we are now past 24:00, on next day. + # Above + (day_number - opening_time.weekday())) % 7 computation, + # which acts as openinghours_to_datetime (return the next date and time after now()) + # can't return a coherent start time. + # in this case we compute start date relative to end date + opening_time = datetime.datetime.combine(end, dateutil_parse(specification['opens']).time()) + start = opening_time - datetime.timedelta(days=1) + return (start, end, day_number) def get_time_table_from_specification(specification): @@ -158,7 +173,9 @@ def get_slots_from_mdr_format(data, today): mdr_weekdays_format = ['%s_am' % day for day in FR_WEEKDAYS] + ['%s_pm' % day for day in FR_WEEKDAYS] if any([re.search('|'.join(mdr_weekdays_format), data_key) is not None for data_key in data.keys()]): known_format = True + today -= datetime.timedelta(days=1) # add yesterday night hours for i in range(7): + tomorrow = today + datetime.timedelta(days=1) for period in ('am', 'pm'): hours = data.get('%s_%s' % (FR_WEEKDAYS[today.weekday()], period)) if not hours: @@ -168,12 +185,19 @@ def get_slots_from_mdr_format(data, today): except AttributeError: continue # add to slots the opening hours in chronological order beginning from today - slots.append(TimeSlot( - datetime.datetime(today.year, today.month, today.day, int(parts[0]), int(parts[1]), tzinfo=today.tzinfo), - datetime.datetime(today.year, today.month, today.day, int(parts[2]), int(parts[3]), tzinfo=today.tzinfo) - )) + start = datetime.datetime(today.year, today.month, today.day, + int(parts[0]), int(parts[1]), tzinfo=today.tzinfo) + end = datetime.datetime(today.year, today.month, today.day, + int(parts[2]), int(parts[3]), tzinfo=today.tzinfo) - today = today + datetime.timedelta(days=1) + # hours may belongs on next day + if end < start: + end = datetime.datetime( + tomorrow.year, tomorrow.month, tomorrow.day, + int(parts[2]), int(parts[3]), tzinfo=tomorrow.tzinfo) + slots.append(TimeSlot(start, end)) + + today = tomorrow return (slots, known_format) @@ -241,10 +265,26 @@ def get_slots_from_mairie_format(data, base_datetime): for days_list, time_table in parse_opening_hours_data(data): for weekday in days_list: - timeslot = TimeSlot( - openinghours_to_datetime(weekday, int(time_table['start_hour']), int(time_table['start_minute'])), - openinghours_to_datetime(weekday, int(time_table['end_hour']), int(time_table['end_minute'])) - ) + start = openinghours_to_datetime( + weekday, int(time_table['start_hour']), int(time_table['start_minute'])) + end = openinghours_to_datetime( + weekday, int(time_table['end_hour']), int(time_table['end_minute'])) + + # hours may belongs on next day + if end < start: + day_number = EN_ABBREV_WEEKDAYS_LIST.index(weekday) + tomorrow = EN_ABBREV_WEEKDAYS_LIST[(day_number + 1) % 7] + end = openinghours_to_datetime( + tomorrow, int(time_table['end_hour']), int(time_table['end_minute'])) + if end < start: + # end time may be find this week whereas start time is picked on next week, + # this occure if we are now past 24:00, on next day. + # openinghours_to_datetime (return the next date and time after now()) + # can't return a coherent start time. + # in this case we thrink the slot to the next day part. + start = openinghours_to_datetime(tomorrow, 0, 0) + + timeslot = TimeSlot(start, end) # add to slots the opening hours in chronological order beginning from today slots.append(timeslot) diff --git a/tests/test_as_opening_hours.py b/tests/test_as_opening_hours.py index 677f326..08f1d00 100644 --- a/tests/test_as_opening_hours.py +++ b/tests/test_as_opening_hours.py @@ -174,7 +174,7 @@ def test_mairie_holiday(): ('lundi_pm', '14h30-17h45', 'closed', 'Réouvre à 14h30'), ('lundi_am', '08h30-11h45', 'closed', 'Ouvre à 8h30'), ('lundi_am', '00h00-00h45', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), - ('dimanche_pm', '20h30-00h45', 'closed', 'Réouvre dimanche à 20h30'), # wrong + ('dimanche_pm', '20h30-00h45', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), ]) def test_mdr_format(day, hours, badge, text): geojson = """ @@ -195,7 +195,7 @@ def test_mdr_format(day, hours, badge, text): ('Mo 14:30-17:45', 'closed', 'Réouvre à 14h30'), ('Mo 08:30-11:45', 'closed', 'Ouvre à 8h30'), ('Mo 00:00-00:45', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), - ('Su 20:30-00:45', 'closed', 'Réouvre dimanche à 20h30'), # wrong + ('Su 20:30-00:45', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), ]) def test_mairie_format_openinghours(openinghour, badge, text): geojson = """ @@ -216,7 +216,7 @@ def test_mairie_format_openinghours(openinghour, badge, text): ('Monday', '14:30', '17:45', 'closed', 'Réouvre à 14h30'), ('Monday', '08:30', '11:45', 'closed', 'Ouvre à 8h30'), ('Monday', '00:00', '00:45', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), - ('Sunday', '20:30', '00:45', 'closed', 'Réouvre dimanche à 20h30'), # wrong + ('Sunday', '20:30', '00:45', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), ]) def test_mairie_format_openinghoursspecification(day, opens, closes, badge, text): geojson = """