compute initial content for dashboard (#32064)
This commit is contained in:
parent
82e5f6ee74
commit
8d97d2d908
|
@ -27,9 +27,6 @@ class AppConfig(django.apps.AppConfig):
|
|||
name = __name__
|
||||
verbose_name = _('GNM Extension')
|
||||
|
||||
def ready(self):
|
||||
from . import signals
|
||||
|
||||
def get_before_urls(self):
|
||||
from . import urls
|
||||
return urls.urlpatterns
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# combo-plugin-gnm - Combo GNM plugin
|
||||
# Copyright (C) 2017-2019 Entr'ouvert
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
from combo.middleware import get_request
|
||||
from combo.profile.models import Profile
|
||||
|
||||
@receiver(post_save, sender=Profile)
|
||||
def new_profile(sender, instance=None, created=False, **kwargs):
|
||||
if not created:
|
||||
return
|
||||
request = get_request()
|
||||
saml_info = request.session.get('mellon_session', {})
|
||||
if False:
|
||||
# if profile has an address push it to the favourite places datastore
|
||||
saml_info['address'][0]
|
||||
|
||||
# fill dashboard with suggestions
|
|
@ -24,6 +24,7 @@ import random
|
|||
import re
|
||||
|
||||
from dateutil.parser import parse as dateutil_parse
|
||||
from pyproj import Geod
|
||||
from requests import RequestException
|
||||
|
||||
from django import template
|
||||
|
@ -37,7 +38,7 @@ from django.utils.text import slugify
|
|||
from django.utils.timezone import is_naive, make_aware
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from combo.apps.dashboard.models import DashboardCell
|
||||
from combo.apps.dashboard.models import DashboardCell, Tile
|
||||
from combo.apps.maps.models import Map, MapLayer
|
||||
from combo.data.models import Page, CellBase, ConfigJsonCell
|
||||
from combo.public.views import render_cell
|
||||
|
@ -509,8 +510,29 @@ def as_commune(user_data):
|
|||
|
||||
|
||||
@register.assignment_tag
|
||||
def get_suggestions(request, cell, user_data, places_data):
|
||||
tile_data = []
|
||||
def get_suggestions(request, user_data, places_data):
|
||||
# fill initial dashboard based on this layout:
|
||||
## au quotidien
|
||||
# mairie tile
|
||||
# closest velov/tcl/swimming pool/etc. tiles
|
||||
## environnement
|
||||
# air quality
|
||||
# pollen
|
||||
|
||||
if not getattr(request, 'user', None) or not request.user.is_authenticated():
|
||||
# no user
|
||||
return ['no user']
|
||||
|
||||
dashboard = DashboardCell.objects.all().filter(page__snapshot__isnull=True)[0]
|
||||
if Tile.objects.filter(dashboard=dashboard, user=request.user).exists():
|
||||
# dashboard already filled
|
||||
return ['already filled']
|
||||
|
||||
mairie_tile = None
|
||||
service_tiles = []
|
||||
airquality_tile = {'key': 'airquality', 'parameters': settings.COMBO_MAP_DEFAULT_POSITION}
|
||||
pollen_tile = {'key': 'pollen'}
|
||||
|
||||
addresses = []
|
||||
city = user_data.get('city') or user_data.get('address_city')
|
||||
if city:
|
||||
|
@ -528,42 +550,38 @@ def get_suggestions(request, cell, user_data, places_data):
|
|||
if 'Annexe' in feature['properties']['nom']:
|
||||
continue
|
||||
if city_slug in slugify(feature['properties']['nom']):
|
||||
tile_data.append({'key': maplayer.slug,
|
||||
'properties': feature['properties']})
|
||||
mairie_tile = {'key': maplayer.slug, 'properties': feature['properties']}
|
||||
break
|
||||
|
||||
if random.random() < 0.3:
|
||||
tile_data.append({'key': 'airquality'})
|
||||
if random.random() < 0.1:
|
||||
tile_data.append({'key': 'pollen'})
|
||||
|
||||
if user_data.get('address_street'):
|
||||
address = None
|
||||
if places_data and places_data.get('data'):
|
||||
place_data = places_data['data'][0]
|
||||
address = u'%(adresse)s, %(ville)s, France' % place_data['content']
|
||||
elif user_data.get('address_street'):
|
||||
if not user_data.get('address_number'):
|
||||
user_data['address_number'] = ''
|
||||
addresses.append(u'%(address_number)s %(address_street)s, %(address_city)s, France' % user_data)
|
||||
address = u'%(address_number)s %(address_street)s, %(address_city)s, France' % user_data
|
||||
|
||||
if places_data:
|
||||
for place_data in places_data.get('data'):
|
||||
addresses.append(u'%(adresse)s, %(ville)s, France' % place_data['content'])
|
||||
|
||||
coords = []
|
||||
nominatim_url = 'https://nominatim.entrouvert.org'
|
||||
for address in addresses:
|
||||
coords = None
|
||||
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')))
|
||||
try:
|
||||
search_result = requests.get(url, timeout=2, without_user=True,
|
||||
cache_duration=300).json()
|
||||
except RequestException:
|
||||
continue
|
||||
if not search_result:
|
||||
continue
|
||||
coords.append({'lon': search_result[0]['lon'], 'lat': search_result[0]['lat']})
|
||||
pass
|
||||
if search_result:
|
||||
coords = {'lon': search_result[0]['lon'], 'lat': search_result[0]['lat']}
|
||||
|
||||
for coord in coords:
|
||||
lat1, lat2 = float(coord['lat']) - 0.008, float(coord['lat']) + 0.008
|
||||
lon1, lon2 = float(coord['lon']) - 0.006, float(coord['lon']) + 0.006
|
||||
for maplayer in MapLayer.objects.filter(slug__in=('velov', 'piscine', 'tcl')):
|
||||
if coords:
|
||||
airquality_tile = {'key': 'airquality', 'parameters': coords}
|
||||
|
||||
lat1, lat2 = float(coords['lat']) - 0.008, float(coords['lat']) + 0.008
|
||||
lon1, lon2 = float(coords['lon']) - 0.006, float(coords['lon']) + 0.006
|
||||
geod = Geod(ellps='WGS84')
|
||||
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,
|
||||
|
@ -574,34 +592,54 @@ def get_suggestions(request, cell, user_data, places_data):
|
|||
if not features:
|
||||
continue
|
||||
for feature in features:
|
||||
# thanks to the flat earth society
|
||||
feature['distance'] = math.sqrt(
|
||||
(float(coord['lon']) - feature['geometry']['coordinates'][0])**2 +
|
||||
(float(coord['lat']) - feature['geometry']['coordinates'][1])**2)
|
||||
feature['distance'] = geod.inv(
|
||||
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 two closest features
|
||||
for feature in features[:2]:
|
||||
tile_data.append({'key': maplayer.slug, 'properties': feature['properties']})
|
||||
# take closest feature
|
||||
if features:
|
||||
service_tiles.append({'key': maplayer.slug, 'properties': features[0]['properties']})
|
||||
|
||||
dashboard = DashboardCell.objects.all()[0]
|
||||
cells = []
|
||||
seen = {}
|
||||
for data in tile_data:
|
||||
cell = ConfigJsonCell(key=data['key'], order=1,
|
||||
page_id=cell.page_id, placeholder='_auto_tile')
|
||||
cell_form_keys = [x['varname'] for x in settings.JSON_CELL_TYPES[cell.key].get('form') or {}]
|
||||
cell.parameters = {}
|
||||
for key in cell_form_keys:
|
||||
cell.parameters[key] = data['properties'].get(key)
|
||||
cell_uid = repr((data['key'], cell.parameters))
|
||||
if cell_uid in seen:
|
||||
continue
|
||||
seen[cell_uid] = True
|
||||
tiles = []
|
||||
if mairie_tile or service_tiles:
|
||||
tiles.append({'key': 'group-title', 'parameters': {'text': 'Au quotidien'}})
|
||||
if mairie_tile:
|
||||
tiles.append(mairie_tile)
|
||||
if service_tiles:
|
||||
random.shuffle(service_tiles)
|
||||
tiles.extend(service_tiles)
|
||||
|
||||
if airquality_tile or pollen_tile:
|
||||
tiles.append({'key': 'group-title', 'parameters': {'text': 'Environnement'}})
|
||||
if airquality_tile:
|
||||
tiles.append(airquality_tile)
|
||||
if pollen_tile:
|
||||
tiles.append(pollen_tile)
|
||||
|
||||
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 {}]
|
||||
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')
|
||||
cell.save()
|
||||
cells.append(render_cell(request, cell=cell).content)
|
||||
tile = Tile(
|
||||
dashboard=dashboard,
|
||||
cell=cell,
|
||||
user=request.user,
|
||||
order=i+1)
|
||||
tile.save()
|
||||
|
||||
random.shuffle(cells)
|
||||
return cells[:5]
|
||||
return tiles
|
||||
|
||||
@register.assignment_tag
|
||||
def get_gnm_portal_url():
|
||||
|
|
|
@ -8,6 +8,7 @@ MELLON_ADD_AUTHNREQUEST_NEXT_URL_EXTENSION = True
|
|||
|
||||
COMBO_MAP_TILE_URLTEMPLATE = "https://tiles.entrouvert.org/hdm/{z}/{x}/{y}.png"
|
||||
COMBO_MAP_ATTRIBUTION = "© <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>"
|
||||
COMBO_GEOCODING_SERVICE = 'https://nominatim.entrouvert.org'
|
||||
|
||||
COMBO_DASHBOARD_ENABLED = True
|
||||
COMBO_DASHBOARD_NEW_TILE_POSITION = 'first'
|
||||
|
@ -248,6 +249,12 @@ JSON_CELL_TYPES = {
|
|||
"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]"
|
||||
|
@ -314,7 +321,8 @@ JSON_CELL_TYPES = {
|
|||
"suggestions": {
|
||||
"name": "Suggestions",
|
||||
"url": "[idp_url]api/users/[user_nameid]/",
|
||||
"loading-message": "Recherche de suggestions…",
|
||||
"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]"
|
||||
|
|
Loading…
Reference in New Issue