From 116511fc314a3ccfbd60776087b4b6aae44c7dcf Mon Sep 17 00:00:00 2001 From: Nicolas ROCHE Date: Thu, 21 Jan 2021 18:01:47 +0100 Subject: [PATCH] templatetags: factorize formats parser for badges and opening hours (#50419) --- combo_plugin_gnm/templatetags/gnm.py | 127 +++++++++++++-------------- 1 file changed, 59 insertions(+), 68 deletions(-) diff --git a/combo_plugin_gnm/templatetags/gnm.py b/combo_plugin_gnm/templatetags/gnm.py index 82c5087..4eb0469 100644 --- a/combo_plugin_gnm/templatetags/gnm.py +++ b/combo_plugin_gnm/templatetags/gnm.py @@ -250,53 +250,41 @@ def parse_opening_hours_data(mairie_data): yield (days_list, time_table) -def get_slots_from_mairie_format(data, base_datetime): - """Process mairie json and return slots the opening hours in chronological order beginning today""" +def parse_mairie_formats(data, base_datetime, oh_add, ohs_add, ohs_del): if 'properties' in data: data = data['properties'] known_format = False - slots = [] - exclusion_slots = [] previous_week = base_datetime - datetime.timedelta(7) next_week = base_datetime + datetime.timedelta(7) - if len(data.get('openinghoursspecification', [])) > 0: - # prepare annual opening exclusions - for specification in data.get('openinghoursspecification', []): - valid_from, valid_through = previous_week, next_week - if specification.get('validFrom'): - valid_from = parse_valid_from(specification) - if specification.get('validThrough'): - valid_through = parse_valid_through(specification) - if not valid_from or not valid_through: - continue - if specification.get('opens') and specification.get('closes'): - # case when opening periods are defined - if valid_from <= base_datetime < valid_through: - known_format = True - try: - day_number, time_table = get_time_table_from_specification(specification) - except ValueError: - continue - timeslot = get_slot(day_number, time_table, base_datetime) - slots.append(timeslot) - else: - # case when exclusions are defined - exclusion_slots.append(TimeSlot(valid_from, valid_through)) + for specification in data.get('openinghoursspecification', []): + valid_from, valid_through = previous_week, next_week + if specification.get('validFrom'): + valid_from = parse_valid_from(specification) + if specification.get('validThrough'): + valid_through = parse_valid_through(specification) + if not valid_from or not valid_through: + continue + if specification.get('opens') and specification.get('closes'): + known_format = True + # case when opening periods are defined + if valid_from <= base_datetime < valid_through: + # parse specification only for the current period relative to utcnow() + try: + day_number, time_table = get_time_table_from_specification(specification) + except ValueError: + continue + ohs_add(day_number, time_table) + else: + # case when exclusions are defined + ohs_del(valid_from, valid_through) - if not known_format and len(data.get('openinghours', [])) > 0: + if not known_format: + # some mairie may only have opening periods defined into openinghours (e.g. Bron) for days_list, time_table in parse_opening_hours_data(data): known_format = True - for weekday in days_list: - day_number = EN_ABBREV_WEEKDAYS_LIST.index(weekday) - timeslot = get_slot(day_number, time_table, base_datetime) - # add to slots the opening hours in chronological order beginning from today - slots.append(timeslot) - - # order slots and cycle the list beginning with 'base_datetime' - slots.sort(key=operator.attrgetter('start')) - - return (slots, exclusion_slots, known_format) + oh_add(days_list, time_table) + return known_format def parse_valid_from(spec): @@ -318,14 +306,11 @@ def parse_valid_through(spec): @register.simple_tag def get_mairie_opening_hours(mairie_data): """Process Mairie Geojson to extract data of each day's opening hours""" + if not mairie_data: return '' - if 'properties' in mairie_data: - mairie_data = mairie_data['properties'] - base_datetime = now() - days_list = [] opening_hours_dict = OrderedDict( zip(EN_ABBREV_WEEKDAYS_LIST, [{'am': None, 'pm': None} for i in range(7)]) ) @@ -341,32 +326,18 @@ def get_mairie_opening_hours(mairie_data): time_table['end_minute'], ) - known_format = False - previous_week = base_datetime - datetime.timedelta(7) - next_week = base_datetime + datetime.timedelta(7) - for specification in mairie_data.get('openinghoursspecification', []): - valid_from, valid_through = previous_week, next_week - if specification.get('validFrom'): - valid_from = parse_valid_from(specification) - if specification.get('validThrough'): - valid_through = parse_valid_through(specification) - if not valid_from or not valid_through: - continue - # case when opening periods are defined - if 'opens' in specification and 'closes' in specification: - known_format = True - # parse specification only for the current period relative to utcnow() - if valid_from < base_datetime < valid_through: - day_number, time_table = get_time_table_from_specification(specification) - weekday = EN_ABBREV_WEEKDAYS_LIST[day_number] - update_opening_hours(weekday, time_table) + def oh_add(days_list, time_table): + for weekday in days_list: + update_opening_hours(weekday, time_table) - if not known_format: - # some mairie may only have opening periods defined into openinghours (e.g. Bron) - for days_list, time_table in parse_opening_hours_data(mairie_data): - known_format = True - for weekday in days_list: - update_opening_hours(weekday, time_table) + def ohs_add(day_number, time_table): + weekday = EN_ABBREV_WEEKDAYS_LIST[day_number] + update_opening_hours(weekday, time_table) + + def ohs_del(valid_from, valid_through): + pass + + known_format = parse_mairie_formats(mairie_data, base_datetime, oh_add, ohs_add, ohs_del) if not ( any([x['am'] for x in opening_hours_dict.values()]) @@ -392,11 +363,31 @@ def as_opening_hours_badge(data): return '' base_datetime = now() + slots = [] exclusion_slots = [] today = base_datetime.date() (slots, known_format) = get_slots_from_mdr_format(data, base_datetime) + + def oh_add(days_list, time_table): + for weekday in days_list: + day_number = EN_ABBREV_WEEKDAYS_LIST.index(weekday) + timeslot = get_slot(day_number, time_table, base_datetime) + # add to slots the opening hours in chronological order beginning from today + slots.append(timeslot) + + def ohs_add(day_number, time_table): + timeslot = get_slot(day_number, time_table, base_datetime) + slots.append(timeslot) + + def ohs_del(valid_from, valid_through): + exclusion_slots.append(TimeSlot(valid_from, valid_through)) + if not known_format: - (slots, exclusion_slots, known_format) = get_slots_from_mairie_format(data, base_datetime) + # Process mairie json and return slots the opening hours + # in chronological order beginning today + known_format = parse_mairie_formats(data, base_datetime, oh_add, ohs_add, ohs_del) + # order slots and cycle the list beginning with 'base_datetime' + slots.sort(key=operator.attrgetter('start')) if not known_format: return ''