From 2d00832fc216df36d665d05a16732030ee48f641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Mon, 11 Jan 2021 21:31:40 +0100 Subject: [PATCH] trivial: apply black --- combo_plugin_gnm/__init__.py | 2 + .../commands/gnm_clean_autotiles.py | 6 +- .../management/commands/gnm_create_places.py | 29 +- .../management/commands/gnm_reporting.py | 13 +- combo_plugin_gnm/templatetags/gnm.py | 205 +-- combo_plugin_gnm/views.py | 19 +- debian/50gnm.py | 1138 +++++++---------- setup.py | 20 +- tests/test_as_opening_hours.py | 128 +- tests/test_get_mairie_opening_hours.py | 74 +- 10 files changed, 776 insertions(+), 858 deletions(-) diff --git a/combo_plugin_gnm/__init__.py b/combo_plugin_gnm/__init__.py index 4524f52..039e26c 100644 --- a/combo_plugin_gnm/__init__.py +++ b/combo_plugin_gnm/__init__.py @@ -29,6 +29,8 @@ class AppConfig(django.apps.AppConfig): def get_before_urls(self): from . import urls + return urls.urlpatterns + default_app_config = __name__ + '.AppConfig' diff --git a/combo_plugin_gnm/management/commands/gnm_clean_autotiles.py b/combo_plugin_gnm/management/commands/gnm_clean_autotiles.py index c6d2277..3367485 100644 --- a/combo_plugin_gnm/management/commands/gnm_clean_autotiles.py +++ b/combo_plugin_gnm/management/commands/gnm_clean_autotiles.py @@ -19,7 +19,9 @@ from django.utils.timezone import now, timedelta from combo.data.models import ConfigJsonCell + class Command(BaseCommand): def handle(self, *args, **options): - ConfigJsonCell.objects.filter(placeholder='_auto_tile', - last_update_timestamp__lte=now() - timedelta(days=2)).delete() + ConfigJsonCell.objects.filter( + placeholder='_auto_tile', last_update_timestamp__lte=now() - timedelta(days=2) + ).delete() diff --git a/combo_plugin_gnm/management/commands/gnm_create_places.py b/combo_plugin_gnm/management/commands/gnm_create_places.py index 1690f89..c8c320d 100644 --- a/combo_plugin_gnm/management/commands/gnm_create_places.py +++ b/combo_plugin_gnm/management/commands/gnm_create_places.py @@ -34,13 +34,14 @@ class Command(BaseCommand): continue cell_form_keys = [x['varname'] for x in json_cell_type.get('form')] parent_page, created = Page.objects.get_or_create( - parent__id=places_page.id, - slug=layer.slug, - defaults={ - 'title': layer.label, - 'redirect_url': '..', - 'parent': places_page, - }) + parent__id=places_page.id, + slug=layer.slug, + defaults={ + 'title': layer.label, + 'redirect_url': '..', + 'parent': places_page, + }, + ) parent_page.title = layer.label parent_page.save() layer.properties = None # get all properties @@ -50,18 +51,18 @@ class Command(BaseCommand): self.stderr.write('error in layer %s: %r\n' % (layer, resp['features'])) continue for feature in resp['features']: - cell_parameters = dict([ - (x, feature['properties'][x]) for x in feature['properties'] if x in cell_form_keys]) + cell_parameters = dict( + [(x, feature['properties'][x]) for x in feature['properties'] if x in cell_form_keys] + ) try: cell = ConfigJsonCell.objects.get( - key=layer.slug, - parameters=cell_parameters, - page__template_name='place') + key=layer.slug, parameters=cell_parameters, page__template_name='place' + ) except ConfigJsonCell.DoesNotExist: page = Page() page_title_template = json_cell_type.get( - 'toodego:page-title-template', - '{{ properties.nom|safe }}') + 'toodego:page-title-template', '{{ properties.nom|safe }}' + ) ctx = Context({'properties': feature['properties']}) page.title = Template(page_title_template).render(ctx) if not page.title: diff --git a/combo_plugin_gnm/management/commands/gnm_reporting.py b/combo_plugin_gnm/management/commands/gnm_reporting.py index 031b353..7198798 100644 --- a/combo_plugin_gnm/management/commands/gnm_reporting.py +++ b/combo_plugin_gnm/management/commands/gnm_reporting.py @@ -42,13 +42,20 @@ class Command(BaseCommand): sheets = [] for url in re.findall('href="(.*?)"', cell.text): url = html.unescape(url) - url = re.sub(r'/backoffice/management/([a-z0-9_-]+)(/[a-z0-9_-]+)?/?(\?)?', r'/api/forms/\1/ods\2\3', url) + url = re.sub( + r'/backoffice/management/([a-z0-9_-]+)(/[a-z0-9_-]+)?/?(\?)?', + r'/api/forms/\1/ods\2\3', + url, + ) resp = requests.get(url, remote_service='auto', user=reporting_user) if not resp.ok: continue zipf = zipfile.ZipFile(BytesIO(resp.content)) - sheets.append(ET.parse(zipf.open('content.xml')).findall( - './/{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table')[0]) + sheets.append( + ET.parse(zipf.open('content.xml')).findall( + './/{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table' + )[0] + ) if sheets: if not os.path.exists(default_storage.path('reporting')): os.mkdir(default_storage.path('reporting')) diff --git a/combo_plugin_gnm/templatetags/gnm.py b/combo_plugin_gnm/templatetags/gnm.py index c8ce485..9f7b08d 100644 --- a/combo_plugin_gnm/templatetags/gnm.py +++ b/combo_plugin_gnm/templatetags/gnm.py @@ -46,15 +46,17 @@ from combo.utils import requests register = template.Library() FR_WEEKDAYS = ['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'] -EN_ABBREV_WEEKDAYS = OrderedDict([ - ('mo', 'Monday'), - ('tu', 'Tuesday'), - ('we', 'Wednesday'), - ('th', 'Thursday'), - ('fr', 'Friday'), - ('sa', 'Saturday'), - ('su', 'Sunday') -]) +EN_ABBREV_WEEKDAYS = OrderedDict( + [ + ('mo', 'Monday'), + ('tu', 'Tuesday'), + ('we', 'Wednesday'), + ('th', 'Thursday'), + ('fr', 'Friday'), + ('sa', 'Saturday'), + ('su', 'Sunday'), + ] +) EN_ABBREV_WEEKDAYS_LIST = list(EN_ABBREV_WEEKDAYS.keys()) EN_FULL_WEEKDAYS_LIST = list(EN_ABBREV_WEEKDAYS.values()) FR_ABBREV_WEEKDAYS_LIST = OrderedDict(zip(EN_ABBREV_WEEKDAYS_LIST, FR_WEEKDAYS)) @@ -79,7 +81,7 @@ def openinghours_to_datetime(day_number, hour, minute, base_datetime): """ day_number = day_number % 7 # ease operations using this parameter - #get next weekday + # get next weekday days = (7 + day_number - base_datetime.weekday()) % 7 datetime_obj = base_datetime + datetime.timedelta(days=days) if is_naive(datetime_obj): @@ -107,8 +109,13 @@ def get_slot(day_number, time_table, base_datetime): # hours may belongs on next day end_day_number = day_number - if (end_hour < start_hour or end_hour == start_hour and end_minute < start_minute - or end_hour == start_hour == 0 and end_minute == start_minute == 0): # 24h/24 + if ( + end_hour < start_hour + or end_hour == start_hour + and end_minute < start_minute + or end_hour == start_hour == 0 + and end_minute == start_minute == 0 + ): # 24h/24 end_day_number += 1 end = openinghours_to_datetime(end_day_number, end_hour, end_minute, base_datetime) @@ -123,8 +130,7 @@ def get_slot(day_number, time_table, base_datetime): def get_time_table_from_specification(specification): - """Parse an openinghoursspecification data block - """ + """Parse an openinghoursspecification data block""" if not isinstance(specification['dayOfWeek'], str): raise ValueError day_of_week = specification.get('dayOfWeek') @@ -141,8 +147,7 @@ def get_time_table_from_specification(specification): def get_period_from_data(time_table): - """Return am or pm and all_day_hours from opening_time and closing_time - """ + """Return am or pm and all_day_hours from opening_time and closing_time""" start_hour = int(time_table['start_hour']) start_minute = int(time_table['start_minute']) end_hour = int(time_table['end_hour']) @@ -155,8 +160,7 @@ def get_period_from_data(time_table): opening_time = datetime.time(hour=start_hour, minute=start_minute) all_day_hours = False - if (opening_time < closing_time # closing_time may last on the night - and closing_time.hour <= 12): + if opening_time < closing_time and closing_time.hour <= 12: # closing_time may last on the night period = 'am' elif opening_time.hour <= 12: period = 'am' @@ -206,34 +210,48 @@ def get_slots_from_mdr_format(data, base_datetime): def parse_opening_hours_data(mairie_data): - """Parse every known openinghours data formats - """ + """Parse every known openinghours data formats""" for openinghours in mairie_data.get('openinghours', []): # format is comma-separated days and/or intervals, or only one day try: - groups = re.match(r'(\w\w(?:(?:,|\-)?\w\w)*) (\d\d?):(\d\d?)-(\d\d?):(\d\d?)', openinghours).groups() + groups = re.match( + r'(\w\w(?:(?:,|\-)?\w\w)*) (\d\d?):(\d\d?)-(\d\d?):(\d\d?)', openinghours + ).groups() except AttributeError: # invalid input data continue for day in groups[0].split(','): if '-' in day: # interval parts = re.match(r'(\w\w)-(\w\w)', day).groups() + groups[1:] - time_table = dict(zip(('start_day', 'end_day', 'start_hour', 'start_minute', 'end_hour', 'end_minute'), parts)) + time_table = dict( + zip( + ('start_day', 'end_day', 'start_hour', 'start_minute', 'end_hour', 'end_minute'), + parts, + ) + ) days_list = EN_ABBREV_WEEKDAYS_LIST[ - EN_ABBREV_WEEKDAYS_LIST.index(time_table['start_day'].lower()): - EN_ABBREV_WEEKDAYS_LIST.index(time_table['end_day'].lower()) + 1] + EN_ABBREV_WEEKDAYS_LIST.index( + time_table['start_day'].lower() + ) : EN_ABBREV_WEEKDAYS_LIST.index(time_table['end_day'].lower()) + + 1 + ] else: # one day - time_table = dict(zip(('start_day', 'start_hour', 'start_minute', 'end_hour', 'end_minute'), (day,) + groups[1:])) - days_list = [EN_ABBREV_WEEKDAYS_LIST[ - EN_ABBREV_WEEKDAYS_LIST.index(time_table['start_day'].lower())]] + time_table = dict( + zip( + ('start_day', 'start_hour', 'start_minute', 'end_hour', 'end_minute'), + (day,) + groups[1:], + ) + ) + days_list = [ + EN_ABBREV_WEEKDAYS_LIST[EN_ABBREV_WEEKDAYS_LIST.index(time_table['start_day'].lower())] + ] 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 - """ + """Process mairie json and return slots the opening hours in chronological order beginning today""" if 'properties' in data: data = data['properties'] @@ -276,8 +294,10 @@ def get_slots_from_mairie_format(data, base_datetime): # order slots and cycle the list beginning with 'base_datetime' slots = sorted(slots, key=operator.attrgetter('start')) if len(slots): + def timedelta_key_func(slot): return slot.start - base_datetime + nearest_slot_index = slots.index(min(slots, key=timedelta_key_func)) slots = slots[nearest_slot_index:] + slots[:nearest_slot_index] return (slots, exclusion_slots, known_format) @@ -293,14 +313,15 @@ def parse_valid_from(spec): def parse_valid_through(spec): valid_through = parse_datetime(spec.get('validThrough')) or parse_date(spec.get('validThrough')) if not isinstance(valid_through, datetime.datetime): - valid_through = make_aware(datetime.datetime(valid_through.year, valid_through.month, valid_through.day, 23, 59)) + valid_through = make_aware( + datetime.datetime(valid_through.year, valid_through.month, valid_through.day, 23, 59) + ) return valid_through @register.simple_tag def get_mairie_opening_hours(mairie_data): - """Process Mairie Geojson to extract data of each day's opening hours - """ + """Process Mairie Geojson to extract data of each day's opening hours""" if not mairie_data: return '' @@ -309,17 +330,20 @@ def get_mairie_opening_hours(mairie_data): base_datetime = now() days_list = [] - opening_hours_dict = OrderedDict(zip(EN_ABBREV_WEEKDAYS_LIST, [{ - 'am': None, 'pm': None - } for i in range(7)])) + opening_hours_dict = OrderedDict( + zip(EN_ABBREV_WEEKDAYS_LIST, [{'am': None, 'pm': None} for i in range(7)]) + ) def update_opening_hours(weekday, time_table): period, all_day_hours = get_period_from_data(time_table) if all_day_hours and period == 'am': - opening_hours_dict[weekday]['pm'] = '' # empty string to avoid displaying fermé + opening_hours_dict[weekday]['pm'] = '' # empty string to avoid displaying fermé opening_hours_dict[weekday][period] = "%sh%s-%sh%s" % ( - time_table['start_hour'], time_table['start_minute'], - time_table['end_hour'], time_table['end_minute']) + time_table['start_hour'], + time_table['start_minute'], + time_table['end_hour'], + time_table['end_minute'], + ) known_format = False for days_list, time_table in parse_opening_hours_data(mairie_data): @@ -348,8 +372,10 @@ def get_mairie_opening_hours(mairie_data): weekday = EN_ABBREV_WEEKDAYS_LIST[day_number] update_opening_hours(weekday, time_table) - if not (any([x['am'] for x in opening_hours_dict.values()]) or - any([x['pm'] for x in opening_hours_dict.values()])): + if not ( + any([x['am'] for x in opening_hours_dict.values()]) + or any([x['pm'] for x in opening_hours_dict.values()]) + ): # always closed, returns None if the format is unknown so it can be # displayed as "unavailable". if not known_format: @@ -358,9 +384,10 @@ def get_mairie_opening_hours(mairie_data): return [(weekday, {'am': None, 'pm': ''}) for weekday in FR_WEEKDAYS] return [ - (FR_ABBREV_WEEKDAYS_LIST[weekday], hours) for weekday, hours in opening_hours_dict.items() - if not (weekday in ['sa', 'su'] and not hours['am'] and not hours['pm']) - ] + (FR_ABBREV_WEEKDAYS_LIST[weekday], hours) + for weekday, hours in opening_hours_dict.items() + if not (weekday in ['sa', 'su'] and not hours['am'] and not hours['pm']) + ] @register.filter @@ -455,9 +482,8 @@ def onlymoov_duration(string): def place_page(cell): try: fixed_place_cell = ConfigJsonCell.objects.get( - key=cell.key, - parameters=cell.parameters, - page__template_name='place') + key=cell.key, parameters=cell.parameters, page__template_name='place' + ) except ConfigJsonCell.DoesNotExist: return None return fixed_place_cell.page @@ -510,7 +536,7 @@ def as_producer(slug, default_slug=None): slug = slug.get('site_slug') producer = None - if ':' in slug: # formdef_reference + if ':' in slug: # formdef_reference slug = slug.split(':')[0] if slug.startswith('_'): @@ -524,8 +550,7 @@ def as_producer(slug, default_slug=None): # variable. producer = settings.TEMPLATE_VARS.get('gnm_commune', 'grandlyon') if producer and settings.TEMPLATE_VARS.get('gnm_commune_name'): - return {'slug': producer, - 'label': settings.TEMPLATE_VARS.get('gnm_commune_name')} + return {'slug': producer, 'label': settings.TEMPLATE_VARS.get('gnm_commune_name')} try: producer = re.search(r'(^|\W)producer-([\w-]*)(\W|$)', producer).group(2).strip() @@ -538,11 +563,17 @@ def as_producer(slug, default_slug=None): producer_slug = slugify(producer) if settings.KNOWN_SERVICES['hobo'].get('hobo-%s' % producer): - return {'slug': producer, - 'label': settings.KNOWN_SERVICES['hobo'].get('hobo-%s' % producer, {'title': ''})['title']} + return { + 'slug': producer, + 'label': settings.KNOWN_SERVICES['hobo'].get('hobo-%s' % producer, {'title': ''})['title'], + } elif settings.KNOWN_SERVICES['hobo'].get('_interco_hobo-%s' % producer): - return {'slug': producer, - 'label': settings.KNOWN_SERVICES['hobo'].get('_interco_hobo-%s' % producer, {'title': ''})['title']} + return { + 'slug': producer, + 'label': settings.KNOWN_SERVICES['hobo'].get('_interco_hobo-%s' % producer, {'title': ''})[ + 'title' + ], + } elif producer in settings.PRODUCER_LABELS: return {'slug': producer, 'label': settings.PRODUCER_LABELS[producer]} elif producer in settings.COLLECTIVITY_LABELS.values(): @@ -556,6 +587,7 @@ def as_producer(slug, default_slug=None): else: return {'slug': 'toodego', 'label': 'Toodego'} + @register.filter def as_commune(user_data): if not user_data: @@ -583,8 +615,9 @@ def as_commune(user_data): 'gnm': True, } # if not found look in mairie pages - pages = Page.objects.filter(parent__slug='mairie', - slug__icontains=slugify(city)).exclude(slug__icontains='annexe') + pages = Page.objects.filter(parent__slug='mairie', slug__icontains=slugify(city)).exclude( + slug__icontains='annexe' + ) if pages.exists(): return { 'label': city, @@ -630,8 +663,9 @@ def get_suggestions(request, user_data, places_data): # get commune tile for the user city maplayer = MapLayer.objects.get(slug='mairie') try: - data_result = requests.get(maplayer.geojson_url, timeout=2, - without_user=True, cache_duration=300).json() + data_result = requests.get( + maplayer.geojson_url, timeout=2, without_user=True, cache_duration=300 + ).json() except RequestException: pass else: @@ -663,11 +697,12 @@ def get_suggestions(request, user_data, places_data): if address: nominatim_url = settings.COMBO_GEOCODING_SERVICE url = '%s/search?q=%s&accept-language=fr&format=json' % ( - nominatim_url, quote(address.encode('utf-8'))) + nominatim_url, + quote(address.encode('utf-8')), + ) search_result = None try: - search_result = requests.get(url, timeout=2, without_user=True, - cache_duration=300).json() + search_result = requests.get(url, timeout=2, without_user=True, cache_duration=300).json() except RequestException: pass if search_result: @@ -682,8 +717,7 @@ def get_suggestions(request, user_data, places_data): for maplayer in MapLayer.objects.filter(slug__in=('velov', 'piscine', 'tcl', 'bibliotheque', 'mdr')): url = maplayer.geojson_url + '&BBOX=%s,%s,%s,%s' % (lat1, lon1, lat2, lon2) try: - data_result = requests.get(url, timeout=2, without_user=True, - cache_duration=300).json() + data_result = requests.get(url, timeout=2, without_user=True, cache_duration=300).json() except RequestException: continue features = data_result.get('features') @@ -691,10 +725,11 @@ def get_suggestions(request, user_data, places_data): continue for feature in features: feature['distance'] = geod.inv( - float(coords['lon']), - float(coords['lat']), - float(feature['geometry']['coordinates'][0]), - float(feature['geometry']['coordinates'][1]))[2] + float(coords['lon']), + float(coords['lat']), + float(feature['geometry']['coordinates'][0]), + float(feature['geometry']['coordinates'][1]), + )[2] features.sort(key=lambda x: x['distance']) # take closest feature if features: @@ -717,33 +752,34 @@ def get_suggestions(request, user_data, places_data): for i, tile_data in enumerate(tiles): if 'properties' in tile_data: - cell_form_keys = [x['varname'] for x in settings.JSON_CELL_TYPES[tile_data['key']].get('form') or {}] + cell_form_keys = [ + x['varname'] for x in settings.JSON_CELL_TYPES[tile_data['key']].get('form') or {} + ] tile_data['parameters'] = {} for key in cell_form_keys: tile_data['parameters'][key] = tile_data['properties'].get(key) cell = ConfigJsonCell( - key=tile_data['key'], - parameters=tile_data.get('parameters', {}), - order=0, - page_id=dashboard.page_id, - placeholder='_suggested_tile') + key=tile_data['key'], + parameters=tile_data.get('parameters', {}), + order=0, + page_id=dashboard.page_id, + placeholder='_suggested_tile', + ) cell.save() - tile = Tile( - dashboard=dashboard, - cell=cell, - user=request.user, - order=i+1) + tile = Tile(dashboard=dashboard, cell=cell, user=request.user, order=i + 1) tile.save() return tiles + @register.simple_tag def get_gnm_portal_url(): if '_interco_portal' in settings.KNOWN_SERVICES['combo']: return settings.KNOWN_SERVICES['combo']['_interco_portal'].get('url') return settings.KNOWN_SERVICES['combo']['portal'].get('url') + @register.simple_tag def get_gnm_collectivities(): collectivities = [] @@ -753,13 +789,14 @@ def get_gnm_collectivities(): matching_hobo = settings.KNOWN_SERVICES['hobo'].get(key.split('_portal')[0][1:]) if not matching_hobo: continue - if matching_hobo['title'] in ('SAU', 'Villeurbanne'): # blacklist + if matching_hobo['title'] in ('SAU', 'Villeurbanne'): # blacklist continue service = settings.KNOWN_SERVICES['combo'][key] collectivities.append({'url': service.get('url'), 'label': matching_hobo['title']}) collectivities.sort(key=lambda x: x['label']) return collectivities + @register.inclusion_tag('combo/gnm/place_map.html') def gnm_place_map(lat, lng): map_cell = Map() @@ -771,6 +808,7 @@ def gnm_place_map(lat, lng): context['init_lng'] = lng return context + @register.inclusion_tag('combo/gnm/airquality_map.html', takes_context=True) def gnm_airquality_map(context): map_cell = Map() @@ -781,20 +819,20 @@ def gnm_airquality_map(context): context.push(map_cell.get_cell_extra_context({})) return context + _json_script_escapes = { ord('>'): '\\u003E', ord('<'): '\\u003C', ord('&'): '\\u0026', } + @register.filter(is_safe=True) def json_script(value, element_id): json_str = json.dumps(value, cls=DjangoJSONEncoder) json_str = json_str.replace('>', '\\u003E').replace('<', '\\u003C').replace('&', '\\u0026') - return format_html( - '', - element_id, mark_safe(json_str) - ) + return format_html('', element_id, mark_safe(json_str)) + @register.simple_tag def get_goto_cell(page, request): @@ -811,16 +849,19 @@ def get_goto_cell(page, request): cell.save() return cell + @register.simple_tag def get_collectivity_slugs(): return list(settings.COLLECTIVITY_LABELS.keys()) + @register.filter def indice_values(indices): for key in ('indice_j-1', 'indice_j', 'indice_j+1'): if indices.get(key): yield indices.get(key) + @register.filter def airquality_hack(cell, request): if cell.key == 'airquality' and not cell.parameters: diff --git a/combo_plugin_gnm/views.py b/combo_plugin_gnm/views.py index bc8d021..bec9a9e 100644 --- a/combo_plugin_gnm/views.py +++ b/combo_plugin_gnm/views.py @@ -27,6 +27,7 @@ from combo.apps.dashboard.models import Tile from combo.data.models import ConfigJsonCell from combo.utils import requests, get_templated_url + def plusone(request, *args, **kwargs): # add reference to a jsondatastore with slug "plus1" reference = request.GET.get('ref') @@ -37,11 +38,14 @@ def plusone(request, *args, **kwargs): passerelle_url += '?name_id=[user_nameid]' passerelle_url = get_templated_url(passerelle_url, context) headers = {'content-type': 'application/json'} - requests.post(passerelle_url, remote_service='auto', - without_user=True, - headers={'Accept': 'application/json'}, - json={'reference': reference}, - timeout=2) + requests.post( + passerelle_url, + remote_service='auto', + without_user=True, + headers={'Accept': 'application/json'}, + json={'reference': reference}, + timeout=2, + ) messages.info(request, u'Merci, votre confirmation nous est utile.') if request.user and request.user.is_authenticated(): @@ -49,6 +53,7 @@ def plusone(request, *args, **kwargs): else: return HttpResponseRedirect('/services/') + def share(request, *args, **kwargs): subject_template = 'gnm/share_email_subject.txt' text_body_template = 'gnm/share_email_body.txt' @@ -130,7 +135,9 @@ def cartads_unsubscribe(request, *args, **kwargs): if numero_dossier: context = RequestContext(request, {'request': request}) context.update(cell.get_cell_extra_context(context)) - action_url = get_templated_url(settings.JSON_CELL_TYPES['cartads-dossiers']['actions']['unsubscribe']['url'], context) + action_url = get_templated_url( + settings.JSON_CELL_TYPES['cartads-dossiers']['actions']['unsubscribe']['url'], context + ) action_url += '&dossier_number=' + numero_dossier response = requests.get(action_url, remote_service='auto', without_user=True) if response.ok: diff --git a/debian/50gnm.py b/debian/50gnm.py index 5123316..486b1bf 100644 --- a/debian/50gnm.py +++ b/debian/50gnm.py @@ -16,677 +16,462 @@ COMBO_DASHBOARD_NEW_TILE_POSITION = 'first' COMBO_MAP_DEFAULT_POSITION = {'lat': '45.7577', 'lng': '4.8320'} COMBO_MAP_MAX_BOUNDS = { "corner1": {"lat": 45.9134, "lng": 4.6733}, - "corner2": {"lat": 45.5583, "lng": 5.1574} + "corner2": {"lat": 45.5583, "lng": 5.1574}, } -COMBO_PUBLIC_TEMPLATES.update({ - "blank": { - "name": u"Blanc", - "template": "combo/page_template_blank.html", - }, - "dashboard": { - "name": u"Tableau de bord", - "template": "combo/page_template_dashboard.html", - }, - "iconbar": { - "name": u"Barre d'icônes", - "template": "combo/page_template_iconbar.html", - }, - "iconbar-left-sidebar": { - "name": u"Barre d'icônes + barre à gauche", - "template": "combo/page_template_iconbar_left_sidebar.html", - }, - "search": { - "name": u"Recherche", - "template": "combo/page_template_search.html", - }, - "banner-two-columns": { - "name": "Deux colonnes + bandeau", - "template": "combo/page_template_banner_2cols.html", - }, - "banner-one-column": { - "name": u"Une colonne + bandeau", - "template": "combo/page_template_banner.html", - }, - "banner-two-columns-sidebar": { - "name": u"Deux colonnes et une barre latérale + bandeau", - "template": "combo/page_template_banner_2cols_sidebar.html", - }, - "place": { - "name": u"Lieu", - "template": "combo/page_template_place.html", - }, - "goto": { - "name": u"M'y rendre", - "template": "combo/page_template_goto.html", - }, -}) +COMBO_PUBLIC_TEMPLATES.update( + { + "blank": { + "name": u"Blanc", + "template": "combo/page_template_blank.html", + }, + "dashboard": { + "name": u"Tableau de bord", + "template": "combo/page_template_dashboard.html", + }, + "iconbar": { + "name": u"Barre d'icônes", + "template": "combo/page_template_iconbar.html", + }, + "iconbar-left-sidebar": { + "name": u"Barre d'icônes + barre à gauche", + "template": "combo/page_template_iconbar_left_sidebar.html", + }, + "search": { + "name": u"Recherche", + "template": "combo/page_template_search.html", + }, + "banner-two-columns": { + "name": "Deux colonnes + bandeau", + "template": "combo/page_template_banner_2cols.html", + }, + "banner-one-column": { + "name": u"Une colonne + bandeau", + "template": "combo/page_template_banner.html", + }, + "banner-two-columns-sidebar": { + "name": u"Deux colonnes et une barre latérale + bandeau", + "template": "combo/page_template_banner_2cols_sidebar.html", + }, + "place": { + "name": u"Lieu", + "template": "combo/page_template_place.html", + }, + "goto": { + "name": u"M'y rendre", + "template": "combo/page_template_goto.html", + }, + } +) JSON_CELL_TYPES = { - "velov": { - "url": "https://%(data_username)s:%(data_password)s@download.data.grandlyon.com/ws/rdata/jcd_jcdecaux.jcdvelov/all.json?field=gid&value=[gid]" % DATA_CREDENTIALS, - "name": u"Velov", - "cache_duration": 60, - "force_async": False, - "auto_refresh": 90, - "form": [ - { - "varname": "gid", - "type": "string", - "label": "GID de la station" - } - ] - }, - "taxi": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/taxi/?property:gid={{gid}}", - "name": u"Station de taxi", - "cache_duration": 86400, - "force_async": False, - "form": [ - { - "varname": "gid", - "type": "string", - "label": "GID de la station" - } - ] - }, - "mdr": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/mdr/?property:identifiant={{identifiant}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Maison de la Métropole de Lyon", - "toodego:page": True, - "form": [ - { - "varname": "identifiant", - "type": "string", - "label": "Identifiant" - } - ] - }, - "piscine": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/piscine/?property:identifiant={{identifiant}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Piscine de la Métropole de Lyon", - "toodego:page": True, - "form": [ - { - "varname": "identifiant", - "type": "string", - "label": "Identifiant" - } - ] - }, - "mairie": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/mairie/?property:identifiant={{identifiant}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Mairie", - "toodego:page": True, - "form": [ - { - "varname": "identifiant", - "type": "string", - "label": "Identifiant" - } - ] - }, - "decheterie": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/decheterie/?property:identifiant={{identifiant}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Déchèterie", - "toodego:page": True, - "toodego:page-title-template": "Déchèterie {{properties.nom}}", - "form": [ - { - "varname": "identifiant", - "type": "string", - "label": "Identifiant" - } - ] - }, - "donnerie": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/donnerie/?property:identifiant={{identifiant}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Donnerie", - "toodego:page": True, - "toodego:page-title-template": "Donnerie {{properties.nom}}", - "form": [ - { - "varname": "identifiant", - "type": "string", - "label": "Identifiant" - } - ] - }, - "bibliotheque": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/bibliotheque/?property:identifiant={{identifiant}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Bibliothèque", - "toodego:page": True, - "form": [ - { - "varname": "identifiant", - "type": "string", - "label": "Identifiant" - } - ] - }, - "aire-de-covoiturage": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/aire-de-covoiturage/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Aire de covoiturage", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "Identifiant" - } - ] - }, - "airquality": { - "url": "{% if q_lat or lat %}http://api.atmo-aura.fr/partenaires/indice_request?api_token=6df2b0b505cc73c5545467758827458e&longitude={% firstof q_lon lon %}&latitude={% firstof q_lat lat %}{% endif %}", - "cache_duration": 300, - "force_async": False, - "name": u"Qualité de l'air", - "form": [ - { - "varname": "lat", - "type": "string", - "label": "Latitude", - "required": False, - }, - { - "varname": "lon", - "type": "string", - "label": "Longitude", - "required": False, - } - ], - "additional-data": [ - { - "key": "air2go", - "url": "{% if q_lat or lat %}http://api.atmo-aura.fr/partenaires/indice_request?api_token=6df2b0b505cc73c5545467758827458e&longitude={% firstof q_lon lon %}&latitude={% firstof q_lat lat %}{% endif %}" - }, - { - "key": "nominatim", - "url": "{% if q_lat or lat %}{{passerelle_url}}base-adresse/nominatim/reverse?lat={% firstof q_lat lat %}&lon={% firstof q_lon lon %}&format=json{% endif %}", - "cache_duration": 3600, - }, - { - "key": "places", - "url": "{% if user_nameid %}{{ passerelle_url }}jsondatastore/lieux-favoris/data/?name_id={{user_nameid}}{% endif %}", - }, - { - "key": "place_geoloc", - "url": "{% if places %}{{ passerelle_url }}base-adresse/nominatim/search?q={{ places.data.0.text }}&format=json{% endif %}", - "cache_duration": 3600, - }, - { - "key": "place2_geoloc", - "url": "{% if places|length > 1 %}{{ passerelle_url }}base-adresse/nominatim/search?q={{ places.data.1.text }}&format=json{% endif %}", - "cache_duration": 3600, - }, - ], - "actions": { - "geocode": { - "url": "{{ passerelle_url }}base-adresse/nominatim/search?q={{ q }}&format=json", - "method": "get", - "response": "raw" - } - } - }, - "pollen": { - "url": "https://download.data.grandlyon.com/ws/rdata/rnsa_reseau_aerobio.rnsabulletin/all.json", - "cache_duration": 300, - "force_async": False, - "name": u"Info Pollen", - "additional-data": [ - {"key": "syntheses", - "url": "https://download.data.grandlyon.com/ws/rdata/rnsa_reseau_aerobio.rnsabulletin/all.json?field=type&value=Synthese" - } - ] - }, - "places": { - "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/?name_id={{user_nameid}}", - "name": u"Lieux favoris", - "force_async": False, - "cache_duration": 600, - "additional-data": [ - { - "key": "userdata", - "url": "{{idp_url}}api/users/{{user_nameid}}" - } - ], - "actions": { - "create": { - "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/create?name_id={{user_nameid}}" - }, - "update": { - "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/{{id}}/?name_id={{user_nameid}}" - }, - "delete": { - "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/{{id}}/delete?name_id={{user_nameid}}" - } - } - }, - "silo-a-verre": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/silo-a-verre/?property:identifiant={{identifiant}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Silo à verre", - "form": [ - { - "varname": "identifiant", - "type": "string", - "label": "Identifiant" - } - ] - }, - "tcl": { - "url": "{{passerelle_url}}tcl/tcl/stop/{{id}}", - "auto_refresh": 25, - "cache_duration": 10, - "force_async": False, - "name": u"Arrêt TCL", - "form": [ - { - "varname": "id", - "type": "string", - "label": "Identifiant" - } - ] - }, - "goto": { - "url": "{% if lat1 %}{{cityway_api_url}}api/journeyplanner/opt/PlanTrips/json?DepartureType=COORDINATES&DepartureLatitude={{lat1}}&DepartureLongitude={{lng1}}&ArrivalType=COORDINATES&ArrivalLatitude={{lat2}}&ArrivalLongitude={{lng2}}&Date={{date}}&DateType=DEPARTURE&TripModes={{tripmode}}&Algorithm=FASTEST&BikeSecurityLevel=None&BikeSpeed=12&WalkSpeed=4&MaxCarDistance=100&MaxBikeDistance=100&MaxWalkDistance=3000&AvoidDisruptions=1&StopToPlaceCar=1&SpecificOptions=GetOn;3|GetOff;4|TinyDistance;300|VLS;0|CARSHARING;0&user_key={{cityway_api_userkey}}{% endif %}", - "cache_duration": 60, - "force_async": False, - "name": u"M'y rendre", - "loading-message": u'Calcul…', - "varnames": ["lat1", "lng1", "lat2", "lng2", "date", "to"], - "form": [ - { - "varname": "tripmode", - "type": "string", - "label": "Mode de transport (WALK, BIKE, PT, CAR)" - } - ] - }, - "cut-profile": { - "url": "{{idp_url}}api/users/{{user_nameid}}/", - "name": "Profil CUT", - "auto_refresh": 60, - }, - "profile-info": { - "url": "{{idp_url}}api/users/{{user_nameid}}/", - "name": "Infos de profil" - }, - "suggestions": { - "name": "Suggestions", - "url": "{{idp_url}}api/users/{{user_nameid}}", - "force_async": True, - "loading-message": "Assemblage en cours, quelques secondes…", - "additional-data": [ - {"key": "places", - "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/?name_id={{user_nameid}}" - } - ] - }, - "alerte-qualite-de-l-air": { - "url": "{{passerelle_url}}feeds/alertes-qualite-de-lair/json", - "cache_duration": 600, - "force_async": True, - "name": u"Alerte qualité de l'air" - }, - "mairie-usager": { - "name": "Mairie de l'usager", - "url": "{{idp_url}}api/users/{{user_nameid}}/", - "form": [ - { - "varname": "text", - "type": "text", - "label": "Texte" - } - ] - }, - "group-title": { - "name": "Intertitre", - "url": "{{}}", - "form": [ - { - "varname": "text", - "type": "text", - "label": "Texte" - } - ] - }, - "stats": { - "name": "Statistiques tuiles", - "url": "{{portal_url}}gnm/stats/", - }, - "parkingtr": { - "url": "https://%(data_username)s:%(data_password)s@download.data.grandlyon.com/wfs/rdata?SERVICE=WFS&VERSION=2.0.0&outputformat=GEOJSON&request=GetFeature&typename=pvo_patrimoine_voirie.pvoparkingtr&filter=pkgid[pkgid]" % DATA_CREDENTIALS, - "cache_duration": 86400, - "force_async": False, - "name": u"Parking", - "form": [ - { - "varname": "pkgid", - "type": "string", - "label": "Identifiant" - } - ] - }, - "parc-velo": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/parc-velo/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Parc de stationnement vélos", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "Identifiant" - } - ] - }, - "autopartage": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/autopartage/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Autopartage", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "Identifiant" - } - ] - }, - "stationnement-pmr": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/stationnement-pmr/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Stationnement réglementé pour les PMR", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "Identifiant" - } - ] - }, - "toilette": { - "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/toilette/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": u"Toilette publique", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "evenement-routier": { - "url": "https://%(data_username)s:%(data_password)s@download.data.grandlyon.com/wfs/rdata?SERVICE=WFS&VERSION=2.0.0&outputformat=GEOJSON&request=GetFeature&typename=pvo_patrimoine_voirie.pvoevenement&filter=id[id]" % DATA_CREDENTIALS, - "cache_duration": 86400, - "force_async": False, - "name": u"Evenement routier", - "form": [ - { - "varname": "id", - "type": "string", - "label": "Identifiant" - } - ] - }, - "cartads-dossiers": { - "url": "{{passerelle_url}}grandlyon-cartads-cs/{{slug}}/files?name_id={{user_nameid}}", - "cache_duration": 0, - "force_async": True, - "name": u"Dossiers Cart@DS", - "form": [ - { - "varname": "slug", - "type": "string", - "label": "Slug du connecteur" - } - ], - "actions": { - "unsubscribe": { - "url": "{{passerelle_url}}grandlyon-cartads-cs/{{slug}}/unsubscribe?name_id={{user_nameid}}", - }, - } - }, - "urgence-sanitaire-soins": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/urgence-sanitaire-soins/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Urgence sanitaire Covid 19 - Accès aux soins", - "toodego:page": True, - "template-name": "combo/json/urgence-sanitaire.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "urgence-sanitaire-alimentation": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/urgence-sanitaire-alimentation/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Urgence sanitaire Covid 19 - Alimentation", - "toodego:page": True, - "template-name": "combo/json/urgence-sanitaire.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "urgence-sanitaire-hebergement": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/urgence-sanitaire-hebergement/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Urgence sanitaire Covid 19 - Hébergement", - "toodego:page": True, - "template-name": "combo/json/urgence-sanitaire.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "urgence-sanitaire-quotidien": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/urgence-sanitaire-quotidien/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Urgence sanitaire Covid 19 - Services au quotidien", - "toodego:page": True, - "template-name": "combo/json/urgence-sanitaire.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-animaux-jardin-bricolage": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-animaux-jardin-bricolage/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Animaux jardin bricolage", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-autres-activites": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-autres-activites/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Autres activités", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-deco-meubles": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-deco-meubles/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Déco meubles", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-fleuriste": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-fleuriste/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Fleuriste", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-jeux-jouets": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-jeux-jouets/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Jeux jouets", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-librairie": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-librairie/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Librairie", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-mode": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-mode/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Mode", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-restauration": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-restauration/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Restauration", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-soins-institut-beaute": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-soins-institut-beaute/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Soins institut beauté", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, - "commerce-sport-loisirs": { - "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-sport-loisirs/?property:gid={{gid}}", - "cache_duration": 86400, - "force_async": False, - "name": "Commerce - Sport loisirs", - "toodego:page": True, - "template-name": "combo/json/commerce.html", - "form": [ - { - "varname": "gid", - "type": "string", - "label": "gid" - } - ] - }, + "velov": { + "url": "https://%(data_username)s:%(data_password)s@download.data.grandlyon.com/ws/rdata/jcd_jcdecaux.jcdvelov/all.json?field=gid&value=[gid]" + % DATA_CREDENTIALS, + "name": u"Velov", + "cache_duration": 60, + "force_async": False, + "auto_refresh": 90, + "form": [{"varname": "gid", "type": "string", "label": "GID de la station"}], + }, + "taxi": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/taxi/?property:gid={{gid}}", + "name": u"Station de taxi", + "cache_duration": 86400, + "force_async": False, + "form": [{"varname": "gid", "type": "string", "label": "GID de la station"}], + }, + "mdr": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/mdr/?property:identifiant={{identifiant}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Maison de la Métropole de Lyon", + "toodego:page": True, + "form": [{"varname": "identifiant", "type": "string", "label": "Identifiant"}], + }, + "piscine": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/piscine/?property:identifiant={{identifiant}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Piscine de la Métropole de Lyon", + "toodego:page": True, + "form": [{"varname": "identifiant", "type": "string", "label": "Identifiant"}], + }, + "mairie": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/mairie/?property:identifiant={{identifiant}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Mairie", + "toodego:page": True, + "form": [{"varname": "identifiant", "type": "string", "label": "Identifiant"}], + }, + "decheterie": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/decheterie/?property:identifiant={{identifiant}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Déchèterie", + "toodego:page": True, + "toodego:page-title-template": "Déchèterie {{properties.nom}}", + "form": [{"varname": "identifiant", "type": "string", "label": "Identifiant"}], + }, + "donnerie": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/donnerie/?property:identifiant={{identifiant}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Donnerie", + "toodego:page": True, + "toodego:page-title-template": "Donnerie {{properties.nom}}", + "form": [{"varname": "identifiant", "type": "string", "label": "Identifiant"}], + }, + "bibliotheque": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/bibliotheque/?property:identifiant={{identifiant}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Bibliothèque", + "toodego:page": True, + "form": [{"varname": "identifiant", "type": "string", "label": "Identifiant"}], + }, + "aire-de-covoiturage": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/aire-de-covoiturage/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Aire de covoiturage", + "form": [{"varname": "gid", "type": "string", "label": "Identifiant"}], + }, + "airquality": { + "url": "{% if q_lat or lat %}http://api.atmo-aura.fr/partenaires/indice_request?api_token=6df2b0b505cc73c5545467758827458e&longitude={% firstof q_lon lon %}&latitude={% firstof q_lat lat %}{% endif %}", + "cache_duration": 300, + "force_async": False, + "name": u"Qualité de l'air", + "form": [ + { + "varname": "lat", + "type": "string", + "label": "Latitude", + "required": False, + }, + { + "varname": "lon", + "type": "string", + "label": "Longitude", + "required": False, + }, + ], + "additional-data": [ + { + "key": "air2go", + "url": "{% if q_lat or lat %}http://api.atmo-aura.fr/partenaires/indice_request?api_token=6df2b0b505cc73c5545467758827458e&longitude={% firstof q_lon lon %}&latitude={% firstof q_lat lat %}{% endif %}", + }, + { + "key": "nominatim", + "url": "{% if q_lat or lat %}{{passerelle_url}}base-adresse/nominatim/reverse?lat={% firstof q_lat lat %}&lon={% firstof q_lon lon %}&format=json{% endif %}", + "cache_duration": 3600, + }, + { + "key": "places", + "url": "{% if user_nameid %}{{ passerelle_url }}jsondatastore/lieux-favoris/data/?name_id={{user_nameid}}{% endif %}", + }, + { + "key": "place_geoloc", + "url": "{% if places %}{{ passerelle_url }}base-adresse/nominatim/search?q={{ places.data.0.text }}&format=json{% endif %}", + "cache_duration": 3600, + }, + { + "key": "place2_geoloc", + "url": "{% if places|length > 1 %}{{ passerelle_url }}base-adresse/nominatim/search?q={{ places.data.1.text }}&format=json{% endif %}", + "cache_duration": 3600, + }, + ], + "actions": { + "geocode": { + "url": "{{ passerelle_url }}base-adresse/nominatim/search?q={{ q }}&format=json", + "method": "get", + "response": "raw", + } + }, + }, + "pollen": { + "url": "https://download.data.grandlyon.com/ws/rdata/rnsa_reseau_aerobio.rnsabulletin/all.json", + "cache_duration": 300, + "force_async": False, + "name": u"Info Pollen", + "additional-data": [ + { + "key": "syntheses", + "url": "https://download.data.grandlyon.com/ws/rdata/rnsa_reseau_aerobio.rnsabulletin/all.json?field=type&value=Synthese", + } + ], + }, + "places": { + "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/?name_id={{user_nameid}}", + "name": u"Lieux favoris", + "force_async": False, + "cache_duration": 600, + "additional-data": [{"key": "userdata", "url": "{{idp_url}}api/users/{{user_nameid}}"}], + "actions": { + "create": { + "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/create?name_id={{user_nameid}}" + }, + "update": { + "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/{{id}}/?name_id={{user_nameid}}" + }, + "delete": { + "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/{{id}}/delete?name_id={{user_nameid}}" + }, + }, + }, + "silo-a-verre": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/silo-a-verre/?property:identifiant={{identifiant}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Silo à verre", + "form": [{"varname": "identifiant", "type": "string", "label": "Identifiant"}], + }, + "tcl": { + "url": "{{passerelle_url}}tcl/tcl/stop/{{id}}", + "auto_refresh": 25, + "cache_duration": 10, + "force_async": False, + "name": u"Arrêt TCL", + "form": [{"varname": "id", "type": "string", "label": "Identifiant"}], + }, + "goto": { + "url": "{% if lat1 %}{{cityway_api_url}}api/journeyplanner/opt/PlanTrips/json?DepartureType=COORDINATES&DepartureLatitude={{lat1}}&DepartureLongitude={{lng1}}&ArrivalType=COORDINATES&ArrivalLatitude={{lat2}}&ArrivalLongitude={{lng2}}&Date={{date}}&DateType=DEPARTURE&TripModes={{tripmode}}&Algorithm=FASTEST&BikeSecurityLevel=None&BikeSpeed=12&WalkSpeed=4&MaxCarDistance=100&MaxBikeDistance=100&MaxWalkDistance=3000&AvoidDisruptions=1&StopToPlaceCar=1&SpecificOptions=GetOn;3|GetOff;4|TinyDistance;300|VLS;0|CARSHARING;0&user_key={{cityway_api_userkey}}{% endif %}", + "cache_duration": 60, + "force_async": False, + "name": u"M'y rendre", + "loading-message": u'Calcul…', + "varnames": ["lat1", "lng1", "lat2", "lng2", "date", "to"], + "form": [ + {"varname": "tripmode", "type": "string", "label": "Mode de transport (WALK, BIKE, PT, CAR)"} + ], + }, + "cut-profile": { + "url": "{{idp_url}}api/users/{{user_nameid}}/", + "name": "Profil CUT", + "auto_refresh": 60, + }, + "profile-info": {"url": "{{idp_url}}api/users/{{user_nameid}}/", "name": "Infos de profil"}, + "suggestions": { + "name": "Suggestions", + "url": "{{idp_url}}api/users/{{user_nameid}}", + "force_async": True, + "loading-message": "Assemblage en cours, quelques secondes…", + "additional-data": [ + { + "key": "places", + "url": "{{passerelle_url}}jsondatastore/lieux-favoris/data/?name_id={{user_nameid}}", + } + ], + }, + "alerte-qualite-de-l-air": { + "url": "{{passerelle_url}}feeds/alertes-qualite-de-lair/json", + "cache_duration": 600, + "force_async": True, + "name": u"Alerte qualité de l'air", + }, + "mairie-usager": { + "name": "Mairie de l'usager", + "url": "{{idp_url}}api/users/{{user_nameid}}/", + "form": [{"varname": "text", "type": "text", "label": "Texte"}], + }, + "group-title": { + "name": "Intertitre", + "url": "{{}}", + "form": [{"varname": "text", "type": "text", "label": "Texte"}], + }, + "stats": { + "name": "Statistiques tuiles", + "url": "{{portal_url}}gnm/stats/", + }, + "parkingtr": { + "url": "https://%(data_username)s:%(data_password)s@download.data.grandlyon.com/wfs/rdata?SERVICE=WFS&VERSION=2.0.0&outputformat=GEOJSON&request=GetFeature&typename=pvo_patrimoine_voirie.pvoparkingtr&filter=pkgid[pkgid]" + % DATA_CREDENTIALS, + "cache_duration": 86400, + "force_async": False, + "name": u"Parking", + "form": [{"varname": "pkgid", "type": "string", "label": "Identifiant"}], + }, + "parc-velo": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/parc-velo/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Parc de stationnement vélos", + "form": [{"varname": "gid", "type": "string", "label": "Identifiant"}], + }, + "autopartage": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/autopartage/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Autopartage", + "form": [{"varname": "gid", "type": "string", "label": "Identifiant"}], + }, + "stationnement-pmr": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/stationnement-pmr/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Stationnement réglementé pour les PMR", + "form": [{"varname": "gid", "type": "string", "label": "Identifiant"}], + }, + "toilette": { + "url": "{{passerelle_url}}opengis/data-grandlyon-general/query/toilette/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": u"Toilette publique", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "evenement-routier": { + "url": "https://%(data_username)s:%(data_password)s@download.data.grandlyon.com/wfs/rdata?SERVICE=WFS&VERSION=2.0.0&outputformat=GEOJSON&request=GetFeature&typename=pvo_patrimoine_voirie.pvoevenement&filter=id[id]" + % DATA_CREDENTIALS, + "cache_duration": 86400, + "force_async": False, + "name": u"Evenement routier", + "form": [{"varname": "id", "type": "string", "label": "Identifiant"}], + }, + "cartads-dossiers": { + "url": "{{passerelle_url}}grandlyon-cartads-cs/{{slug}}/files?name_id={{user_nameid}}", + "cache_duration": 0, + "force_async": True, + "name": u"Dossiers Cart@DS", + "form": [{"varname": "slug", "type": "string", "label": "Slug du connecteur"}], + "actions": { + "unsubscribe": { + "url": "{{passerelle_url}}grandlyon-cartads-cs/{{slug}}/unsubscribe?name_id={{user_nameid}}", + }, + }, + }, + "urgence-sanitaire-soins": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/urgence-sanitaire-soins/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Urgence sanitaire Covid 19 - Accès aux soins", + "toodego:page": True, + "template-name": "combo/json/urgence-sanitaire.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "urgence-sanitaire-alimentation": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/urgence-sanitaire-alimentation/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Urgence sanitaire Covid 19 - Alimentation", + "toodego:page": True, + "template-name": "combo/json/urgence-sanitaire.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "urgence-sanitaire-hebergement": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/urgence-sanitaire-hebergement/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Urgence sanitaire Covid 19 - Hébergement", + "toodego:page": True, + "template-name": "combo/json/urgence-sanitaire.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "urgence-sanitaire-quotidien": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/urgence-sanitaire-quotidien/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Urgence sanitaire Covid 19 - Services au quotidien", + "toodego:page": True, + "template-name": "combo/json/urgence-sanitaire.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-animaux-jardin-bricolage": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-animaux-jardin-bricolage/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Animaux jardin bricolage", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-autres-activites": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-autres-activites/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Autres activités", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-deco-meubles": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-deco-meubles/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Déco meubles", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-fleuriste": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-fleuriste/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Fleuriste", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-jeux-jouets": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-jeux-jouets/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Jeux jouets", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-librairie": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-librairie/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Librairie", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-mode": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-mode/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Mode", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-restauration": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-restauration/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Restauration", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-soins-institut-beaute": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-soins-institut-beaute/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Soins institut beauté", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, + "commerce-sport-loisirs": { + "url": "{{passerelle_url}}opengis/data-grandlyon-rdata/query/commerce-sport-loisirs/?property:gid={{gid}}", + "cache_duration": 86400, + "force_async": False, + "name": "Commerce - Sport loisirs", + "toodego:page": True, + "template-name": "combo/json/commerce.html", + "form": [{"varname": "gid", "type": "string", "label": "gid"}], + }, } COMBO_ASSET_SLOTS = { - "banner:cut": { - "label": u"Logo bandeau pour Grand Lyon Connect" - }, - "commune:banner": { - "label": u"Bandeau communal" - }, - "passerelle:cartads:dossier": { - "label": u"Image tuile dossier urbanisme" - }, + "banner:cut": {"label": u"Logo bandeau pour Grand Lyon Connect"}, + "commune:banner": {"label": u"Bandeau communal"}, + "passerelle:cartads:dossier": {"label": u"Image tuile dossier urbanisme"}, } PRODUCER_LABELS = { @@ -776,9 +561,7 @@ COLLECTIVITY_LABELS = { PRODUCER_LABELS.update(COLLECTIVITY_LABELS) for producer, producer_label in PRODUCER_LABELS.items(): - COMBO_ASSET_SLOTS['logo:%s' % producer] = { - 'label': u'Logo %s' % producer_label - } + COMBO_ASSET_SLOTS['logo:%s' % producer] = {'label': u'Logo %s' % producer_label} # add lyon as used by cart@ds for arrondissement in ['1er'] + ['%seme' % x for x in range(2, 10)]: @@ -823,24 +606,14 @@ tiles = [ ] for tile, tile_label in tiles: - COMBO_ASSET_SLOTS['picture:%s' % tile] = { - 'label': u'Photographie %s' % tile_label - } + COMBO_ASSET_SLOTS['picture:%s' % tile] = {'label': u'Photographie %s' % tile_label} if tile not in ('taxi', 'tcl', 'velov'): - COMBO_ASSET_SLOTS['picture:banner:%s' % tile] = { - 'label': u'Photographie/bannière %s' % tile_label - } + COMBO_ASSET_SLOTS['picture:banner:%s' % tile] = {'label': u'Photographie/bannière %s' % tile_label} WCS_FORM_ASSET_SLOTS = { - "picture": { - "prefix": u"Photographie" - }, - "picture:banner": { - "prefix": u"Photographie/bannière" - }, - "logo": { - "prefix": u"Picto" - }, + "picture": {"prefix": u"Photographie"}, + "picture:banner": {"prefix": u"Photographie/bannière"}, + "logo": {"prefix": u"Picto"}, } COMBO_MAP_LAYER_ASSET_SLOTS = { @@ -850,6 +623,7 @@ COMBO_MAP_LAYER_ASSET_SLOTS = { } import memcache + memcache.SERVER_MAX_VALUE_LENGTH = 10 * 1024 * 1024 SESSION_EXPIRE_AT_BROWSER_CLOSE = False diff --git a/setup.py b/setup.py index bb0071c..11d8988 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,7 @@ from distutils.command.sdist import sdist from distutils.cmd import Command from setuptools import setup, find_packages + class eo_sdist(sdist): def run(self): if os.path.exists('VERSION'): @@ -24,26 +25,28 @@ class eo_sdist(sdist): if os.path.exists('VERSION'): os.remove('VERSION') + def get_version(): if os.path.exists('VERSION'): with open('VERSION', 'r') as v: return v.read() if os.path.exists('.git'): - p = subprocess.Popen(['git','describe','--dirty=.dirty','--match=v*'], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p = subprocess.Popen( + ['git', 'describe', '--dirty=.dirty', '--match=v*'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) result = p.communicate()[0] if p.returncode == 0: - result = result.decode('ascii').strip()[1:] # strip spaces/newlines and initial v - if '-' in result: # not a tagged version + result = result.decode('ascii').strip()[1:] # strip spaces/newlines and initial v + if '-' in result: # not a tagged version real_number, commit_count, commit_hash = result.split('-', 2) version = '%s.post%s+%s' % (real_number, commit_count, commit_hash) else: version = result return version else: - return '0.0.post%s' % len( - subprocess.check_output( - ['git', 'rev-list', 'HEAD']).splitlines()) + return '0.0.post%s' % len(subprocess.check_output(['git', 'rev-list', 'HEAD']).splitlines()) return '0.0' @@ -60,6 +63,7 @@ class compile_translations(Command): def run(self): try: from django.core.management import call_command + for path, dirs, files in os.walk('combo_plugin_gnm'): if 'locale' not in dirs: continue @@ -113,5 +117,5 @@ setup( 'compile_translations': compile_translations, 'install_lib': install_lib, 'sdist': eo_sdist, - } + }, ) diff --git a/tests/test_as_opening_hours.py b/tests/test_as_opening_hours.py index e4d84f6..b29175c 100644 --- a/tests/test_as_opening_hours.py +++ b/tests/test_as_opening_hours.py @@ -9,14 +9,14 @@ from combo_plugin_gnm.templatetags.gnm import as_opening_hours_badge BASE_DIR = os.path.dirname(os.path.dirname(__file__)) -GEOJSON = json.load(open(os.path.join( - BASE_DIR, 'tests/data/mairie-geojson.json')))['features'] -MDR_GEOJSON = json.load(open(os.path.join( - BASE_DIR, 'tests/data/mdr-geojson.json')))['features'] +GEOJSON = json.load(open(os.path.join(BASE_DIR, 'tests/data/mairie-geojson.json')))['features'] +MDR_GEOJSON = json.load(open(os.path.join(BASE_DIR, 'tests/data/mdr-geojson.json')))['features'] TZOFFSETS = {"Europe/Paris": 3600} -@pytest.mark.freeze_time("2018-03-04 23:00:00",) +@pytest.mark.freeze_time( + "2018-03-04 23:00:00", +) def test_every_mairie_closed(): """every mairie is closed at mignight""" opening_hours = [as_opening_hours_badge(x) for x in GEOJSON] @@ -25,8 +25,11 @@ def test_every_mairie_closed(): def test_all_mairie_data_parsed_correct(): """everything got parsed correctly""" - opening_hours = [as_opening_hours_badge(x) for x in GEOJSON - if x['properties'].get('openinghours') or x['properties'].get('openinghoursspecification')] + opening_hours = [ + as_opening_hours_badge(x) + for x in GEOJSON + if x['properties'].get('openinghours') or x['properties'].get('openinghoursspecification') + ] assert opening_hours.count('') == 0 @@ -88,7 +91,9 @@ def test_mairie_bron_saturday(): @pytest.mark.freeze_time("2018-03-05 09:59:13") def test_jonage_open(): "Jonage is defined only by openinghoursspecification data" - test_html = [as_opening_hours_badge(x) for x in GEOJSON if x['properties']['nom'] == 'Mairie de Jonage'][0] + test_html = [as_opening_hours_badge(x) for x in GEOJSON if x['properties']['nom'] == 'Mairie de Jonage'][ + 0 + ] klass, label = 'open', u"Ouvert jusqu'à 12h30" assert test_html == mark_safe(u'
%s
' % (klass, label)) @@ -96,7 +101,9 @@ def test_jonage_open(): @pytest.mark.freeze_time("2018-03-05 11:32:00") def test_jonage_soon_to_be_closed(): "Jonage is defined only by openinghoursspecification data" - test_html = [as_opening_hours_badge(x) for x in GEOJSON if x['properties']['nom'] == 'Mairie de Jonage'][0] + test_html = [as_opening_hours_badge(x) for x in GEOJSON if x['properties']['nom'] == 'Mairie de Jonage'][ + 0 + ] klass, label = 'soon-to-be-closed', u"Ouvert jusqu'à 12h30" assert test_html == mark_safe(u'
%s
' % (klass, label)) @@ -104,7 +111,9 @@ def test_jonage_soon_to_be_closed(): @pytest.mark.freeze_time("2018-03-10 17:30:00") def test_jonage_closed(): "Jonage is defined only by openinghoursspecification data" - test_html = [as_opening_hours_badge(x) for x in GEOJSON if x['properties']['nom'] == 'Mairie de Jonage'][0] + test_html = [as_opening_hours_badge(x) for x in GEOJSON if x['properties']['nom'] == 'Mairie de Jonage'][ + 0 + ] klass, label = 'closed', u"Réouvre lundi à 8h30" assert test_html == mark_safe(u'
%s
' % (klass, label)) @@ -168,18 +177,21 @@ def test_mairie_holiday(): @pytest.mark.freeze_time("2018-03-05 00:30:00") -@pytest.mark.parametrize('day, hours, badge, text', [ - ('mercredi_pm', '14h30-17h45', 'closed', 'Réouvre mercredi à 14h30'), - ('mercredi_pm', '00h00-24h00', 'closed', 'Réouvre mercredi 24h/24'), - ('mardi_pm', '14h30-17h45', 'closed', 'Réouvre demain à 14h30'), - ('mardi_pm', '14h30-00h15', 'closed', 'Réouvre demain à 14h30'), - ('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', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), - ('lundi_am', '00h15-24h00', 'open', "Ouvert jusqu'à minuit"), - ('lundi_am', '00h00-24h00', 'open', "Ouvert 24h/24"), -]) +@pytest.mark.parametrize( + 'day, hours, badge, text', + [ + ('mercredi_pm', '14h30-17h45', 'closed', 'Réouvre mercredi à 14h30'), + ('mercredi_pm', '00h00-24h00', 'closed', 'Réouvre mercredi 24h/24'), + ('mardi_pm', '14h30-17h45', 'closed', 'Réouvre demain à 14h30'), + ('mardi_pm', '14h30-00h15', 'closed', 'Réouvre demain à 14h30'), + ('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', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), + ('lundi_am', '00h15-24h00', 'open', "Ouvert jusqu'à minuit"), + ('lundi_am', '00h00-24h00', 'open', "Ouvert 24h/24"), + ], +) def test_mdr_format(day, hours, badge, text): geojson = """ { @@ -187,49 +199,61 @@ def test_mdr_format(day, hours, badge, text): "%s" : "%s" } } -""" % (day, hours) +""" % ( + day, + hours, + ) html = as_opening_hours_badge(json.loads(geojson)) assert html == '
%s
' % (badge, text) @pytest.mark.freeze_time("2018-03-05 00:30:00") -@pytest.mark.parametrize('openinghour, badge, text', [ - ('We 14:30-17:45', 'closed', 'Réouvre mercredi à 14h30'), - ('We 00:00-24:00', 'closed', 'Réouvre mercredi 24h/24'), - ('Tu 14:30-17:45', 'closed', 'Réouvre demain à 14h30'), - ('Tu 14:30-00:15', 'closed', 'Réouvre demain à 14h30'), - ('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', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), - ('Mo 00:15-24:00', 'open', "Ouvert jusqu'à minuit"), - ('Mo 00:00-24:00', 'open', "Ouvert 24h/24"), -]) +@pytest.mark.parametrize( + 'openinghour, badge, text', + [ + ('We 14:30-17:45', 'closed', 'Réouvre mercredi à 14h30'), + ('We 00:00-24:00', 'closed', 'Réouvre mercredi 24h/24'), + ('Tu 14:30-17:45', 'closed', 'Réouvre demain à 14h30'), + ('Tu 14:30-00:15', 'closed', 'Réouvre demain à 14h30'), + ('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', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), + ('Mo 00:15-24:00', 'open', "Ouvert jusqu'à minuit"), + ('Mo 00:00-24:00', 'open', "Ouvert 24h/24"), + ], +) def test_mairie_format_openinghours(openinghour, badge, text): - geojson = """ + geojson = ( + """ { "properties": { "openinghours": ["%s"] } } -""" % openinghour +""" + % openinghour + ) html = as_opening_hours_badge(json.loads(geojson)) assert html == '
%s
' % (badge, text) @pytest.mark.freeze_time("2018-03-05 00:30:00") -@pytest.mark.parametrize('day, opens, closes, badge, text', [ - ('Wednesday', '14:30', '17:45', 'closed', 'Réouvre mercredi à 14h30'), - ('Wednesday', '00:00', '24:00', 'closed', 'Réouvre mercredi 24h/24'), - ('Tuesday', '14:30', '17:45', 'closed', 'Réouvre demain à 14h30'), - ('Tuesday', '14:30', '00:15', 'closed', 'Réouvre demain à 14h30'), - ('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', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), - ('Monday', '00:15', '24:00', 'open', "Ouvert jusqu'à minuit"), - ('Monday', '00:00', '24:00', 'open', "Ouvert 24h/24"), -]) +@pytest.mark.parametrize( + 'day, opens, closes, badge, text', + [ + ('Wednesday', '14:30', '17:45', 'closed', 'Réouvre mercredi à 14h30'), + ('Wednesday', '00:00', '24:00', 'closed', 'Réouvre mercredi 24h/24'), + ('Tuesday', '14:30', '17:45', 'closed', 'Réouvre demain à 14h30'), + ('Tuesday', '14:30', '00:15', 'closed', 'Réouvre demain à 14h30'), + ('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', 'soon-to-be-closed', "Ouvert jusqu'à 0h45"), + ('Monday', '00:15', '24:00', 'open', "Ouvert jusqu'à minuit"), + ('Monday', '00:00', '24:00', 'open', "Ouvert 24h/24"), + ], +) def test_mairie_format_openinghoursspecification(day, opens, closes, badge, text): geojson = """ { @@ -243,6 +267,10 @@ def test_mairie_format_openinghoursspecification(day, opens, closes, badge, text }] } } -""" % (opens, closes, day) +""" % ( + opens, + closes, + day, + ) html = as_opening_hours_badge(json.loads(geojson)) assert html == '
%s
' % (badge, text) diff --git a/tests/test_get_mairie_opening_hours.py b/tests/test_get_mairie_opening_hours.py index 31d5f2b..87c8abe 100644 --- a/tests/test_get_mairie_opening_hours.py +++ b/tests/test_get_mairie_opening_hours.py @@ -8,8 +8,7 @@ from combo_plugin_gnm.templatetags.gnm import get_mairie_opening_hours BASE_DIR = os.path.dirname(os.path.dirname(__file__)) -GEOJSON = json.load(open(os.path.join( - BASE_DIR, 'tests/data/mairie-geojson.json')))['features'] +GEOJSON = json.load(open(os.path.join(BASE_DIR, 'tests/data/mairie-geojson.json')))['features'] TZOFFSETS = {"Europe/Paris": 3600} @@ -30,15 +29,35 @@ def test_mairie_hours_special_data(): for x in GEOJSON: if x['properties']['identifiant'] == 'S1376': # La Mulatière - assert get_mairie_opening_hours(x) == [('lundi', {'am': u'08h30-12h00', 'pm': None}), ('mardi', {'am': u'08h30-12h30', 'pm': u'13h30-17h00'}), ('mercredi', {'am': u'08h30-12h30', 'pm': u'13h30-17h00'}), ('jeudi', {'am': u'08h30-12h30', 'pm': u'13h30-17h00'}), ('vendredi', {'am': u'08h30-12h30', 'pm': u'13h30-17h00'}), ('samedi', {'am': u'09h00-11h45', 'pm': None})] + assert get_mairie_opening_hours(x) == [ + ('lundi', {'am': u'08h30-12h00', 'pm': None}), + ('mardi', {'am': u'08h30-12h30', 'pm': u'13h30-17h00'}), + ('mercredi', {'am': u'08h30-12h30', 'pm': u'13h30-17h00'}), + ('jeudi', {'am': u'08h30-12h30', 'pm': u'13h30-17h00'}), + ('vendredi', {'am': u'08h30-12h30', 'pm': u'13h30-17h00'}), + ('samedi', {'am': u'09h00-11h45', 'pm': None}), + ] if x['properties']['identifiant'] == 'S1437': # special openinghours format with days intervals, comma-separated list and one day definition with a saturday - assert get_mairie_opening_hours(x) == [('lundi', {'am': u'08h45-12h30', 'pm': u'14h00-16h45'}), ('mardi', {'am': u'08h45-16h45', 'pm': ''}), ('mercredi', {'am': u'08h45-16h45', 'pm': ''}), ('jeudi', {'am': u'08h45-18h00', 'pm': ''}), ('vendredi', {'am': u'08h45-16h45', 'pm': ''}), ('samedi', {'am': u'09h00-12h00', 'pm': None})] + assert get_mairie_opening_hours(x) == [ + ('lundi', {'am': u'08h45-12h30', 'pm': u'14h00-16h45'}), + ('mardi', {'am': u'08h45-16h45', 'pm': ''}), + ('mercredi', {'am': u'08h45-16h45', 'pm': ''}), + ('jeudi', {'am': u'08h45-18h00', 'pm': ''}), + ('vendredi', {'am': u'08h45-16h45', 'pm': ''}), + ('samedi', {'am': u'09h00-12h00', 'pm': None}), + ] if x['properties']['identifiant'] == 'S5564': # classic openinghours days interval for am and pm - assert get_mairie_opening_hours(x) == [('lundi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), ('mardi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), ('mercredi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), ('jeudi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), ('vendredi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'})] + assert get_mairie_opening_hours(x) == [ + ('lundi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), + ('mardi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), + ('mercredi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), + ('jeudi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), + ('vendredi', {'am': u'08h30-12h15', 'pm': u'13h15-17h00'}), + ] @pytest.mark.freeze_time("2018-03-05 15:59:00") @@ -46,7 +65,14 @@ def test_mairie_openinghoursspecification_period_valid(): """Test valid periods of openinghoursspecification timetables""" for x in GEOJSON: if x['properties']['nom'] == 'Mairie de Jonage': - assert get_mairie_opening_hours(x) == [('lundi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), ('mardi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), ('mercredi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), ('jeudi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), ('vendredi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), ('samedi', {'am': '09h00-12h00', 'pm': '14h00-17h00'})] + assert get_mairie_opening_hours(x) == [ + ('lundi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), + ('mardi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), + ('mercredi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), + ('jeudi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), + ('vendredi', {'am': '08h30-12h30', 'pm': '14h00-17h00'}), + ('samedi', {'am': '09h00-12h00', 'pm': '14h00-17h00'}), + ] return @@ -55,20 +81,46 @@ def test_mairie_openinghoursspecification_period_all_closed(): # display known format but no opening hours as all closed for x in GEOJSON: if x['properties']['nom'] == 'Mairie de Jonage': - assert get_mairie_opening_hours(x) == [('lundi', {'am': None, 'pm': ''}), ('mardi', {'am': None, 'pm': ''}), ('mercredi', {'am': None, 'pm': ''}), ('jeudi', {'am': None, 'pm': ''}), ('vendredi', {'am': None, 'pm': ''}), ('samedi', {'am': None, 'pm': ''}), ('dimanche', {'am': None, 'pm': ''})] + assert get_mairie_opening_hours(x) == [ + ('lundi', {'am': None, 'pm': ''}), + ('mardi', {'am': None, 'pm': ''}), + ('mercredi', {'am': None, 'pm': ''}), + ('jeudi', {'am': None, 'pm': ''}), + ('vendredi', {'am': None, 'pm': ''}), + ('samedi', {'am': None, 'pm': ''}), + ('dimanche', {'am': None, 'pm': ''}), + ] return def test_mairie_sathonay_timetable(): """Sathonay-Village S1415""" - test_time_table = [get_mairie_opening_hours(x) for x in GEOJSON if x['properties']['identifiant'] == 'S1415'][0] - assert test_time_table == [('lundi', {'am': u'08h30-12h00', 'pm': u'14h00-17h00'}), ('mardi', {'am': u'08h30-12h00', 'pm': u'13h30-17h00'}), ('mercredi', {'am': u'08h30-12h00', 'pm': u'14h00-17h00'}), ('jeudi', {'am': u'08h30-12h00', 'pm': u'14h00-17h00'}), ('vendredi', {'am': u'08h30-12h00', 'pm': u'14h00-17h00'}), ('samedi', {'am': u'08h30-12h00', 'pm': None})] + test_time_table = [ + get_mairie_opening_hours(x) for x in GEOJSON if x['properties']['identifiant'] == 'S1415' + ][0] + assert test_time_table == [ + ('lundi', {'am': u'08h30-12h00', 'pm': u'14h00-17h00'}), + ('mardi', {'am': u'08h30-12h00', 'pm': u'13h30-17h00'}), + ('mercredi', {'am': u'08h30-12h00', 'pm': u'14h00-17h00'}), + ('jeudi', {'am': u'08h30-12h00', 'pm': u'14h00-17h00'}), + ('vendredi', {'am': u'08h30-12h00', 'pm': u'14h00-17h00'}), + ('samedi', {'am': u'08h30-12h00', 'pm': None}), + ] def test_mairie_saint_priest(): "S1406" - test_time_table = [get_mairie_opening_hours(x) for x in GEOJSON if x['properties']['identifiant'] == 'S1406'][0] - assert test_time_table == [('lundi', {'am': u'08h15-12h15', 'pm': u'13h30-17h30'}), ('mardi', {'am': u'08h15-12h15', 'pm': u'13h30-17h30'}), ('mercredi', {'am': u'08h15-12h15', 'pm': u'13h30-17h30'}), ('jeudi', {'am': u'08h15-11h15', 'pm': u'13h30-17h30'}), ('vendredi', {'am': u'08h15-12h15', 'pm': u'13h30-17h30'}), ('samedi', {'am': u'09h00-11h30', 'pm': None})] + test_time_table = [ + get_mairie_opening_hours(x) for x in GEOJSON if x['properties']['identifiant'] == 'S1406' + ][0] + assert test_time_table == [ + ('lundi', {'am': u'08h15-12h15', 'pm': u'13h30-17h30'}), + ('mardi', {'am': u'08h15-12h15', 'pm': u'13h30-17h30'}), + ('mercredi', {'am': u'08h15-12h15', 'pm': u'13h30-17h30'}), + ('jeudi', {'am': u'08h15-11h15', 'pm': u'13h30-17h30'}), + ('vendredi', {'am': u'08h15-12h15', 'pm': u'13h30-17h30'}), + ('samedi', {'am': u'09h00-11h30', 'pm': None}), + ] def test_mairie_format_openinghours():