parent
27ceac1e46
commit
91907be984
@ -16,6 +16,7 @@ from django.forms import (
|
|||||||
)
|
)
|
||||||
from django_better_admin_arrayfield.forms.widgets import DynamicArrayWidget
|
from django_better_admin_arrayfield.forms.widgets import DynamicArrayWidget
|
||||||
|
|
||||||
|
from .utils import PlaceGuesser
|
||||||
from .models import (
|
from .models import (
|
||||||
Event,
|
Event,
|
||||||
RecurrentImport,
|
RecurrentImport,
|
||||||
@ -741,13 +742,17 @@ class PlaceForm(ModelForm):
|
|||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {"location": TextInput()}
|
widgets = {"location": TextInput()}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.force_adjust = kwargs.pop("force_adjust", None)
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def as_grid(self):
|
def as_grid(self):
|
||||||
return mark_safe(
|
result = ('<div class="grid"><div>'
|
||||||
'<div class="grid"><div>'
|
|
||||||
+ super().as_p()
|
+ super().as_p()
|
||||||
+ '</div><div><div class="map-widget">'
|
+ '</div><div><div class="map-widget">'
|
||||||
+ '<div id="map_location" style="width: 100%; aspect-ratio: 16/9"></div><p>Cliquez pour ajuster la position GPS</p></div></div></div>'
|
+ '<div id="map_location" style="width: 100%; aspect-ratio: 16/9"></div><p>Cliquez pour ajuster la position GPS</p></div></div></div>')
|
||||||
)
|
|
||||||
|
return mark_safe(result)
|
||||||
|
|
||||||
def apply(self):
|
def apply(self):
|
||||||
return self.cleaned_data.get("apply_to_all")
|
return self.cleaned_data.get("apply_to_all")
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<article>
|
<article>
|
||||||
{% if event %}
|
{% if event %}
|
||||||
<p>Création d'un lieu depuis l'événement « {{ event }} » (voir en bas de page le détail de l'événement).</p>
|
<p>Création d'un lieu depuis l'événement « {{ event }} » (voir en bas de page le détail de l'événement).</p>
|
||||||
|
<p><strong>Remarque :</strong> les champs ont été pré-remplis à partir de la description sous forme libre et n'est probablement pas parfaite.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<form method="post">{% csrf_token %}
|
<form method="post">{% csrf_token %}
|
||||||
{{ form.as_grid }}
|
{{ form.as_grid }}
|
||||||
|
114
src/agenda_culturel/utils.py
Normal file
114
src/agenda_culturel/utils.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
from agenda_culturel.models import ReferenceLocation
|
||||||
|
import re
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
|
|
||||||
|
class PlaceGuesser:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.__citynames = list(ReferenceLocation.objects.values_list("name__lower__unaccent", "name")) + [("clermont-fd", "Clermont-Ferrand"), ("aurillac", "Aurillac"), ("montlucon", "Montluçon"), ("montferrand", "Clermont-Ferrand")]
|
||||||
|
self.__citynames = [(x[0].replace("-", " "), x[1]) for x in self.__citynames]
|
||||||
|
|
||||||
|
def __remove_accents(self, input_str):
|
||||||
|
if input_str is None:
|
||||||
|
return None
|
||||||
|
nfkd_form = unicodedata.normalize("NFKD", input_str)
|
||||||
|
return "".join([c for c in nfkd_form if not unicodedata.combining(c)])
|
||||||
|
|
||||||
|
|
||||||
|
def __guess_is_address(self, part):
|
||||||
|
toponyms = ["bd", "rue", "avenue", "place", "boulevard", "allee", ]
|
||||||
|
part = part.strip()
|
||||||
|
if re.match(r'^[0-9]', part):
|
||||||
|
return True
|
||||||
|
|
||||||
|
elems = part.split(" ")
|
||||||
|
return any([self.__remove_accents(e.lower()) in toponyms for e in elems])
|
||||||
|
|
||||||
|
|
||||||
|
def __clean_address(self, addr):
|
||||||
|
toponyms = ["bd", "rue", "avenue", "place", "boulevard", "allée", "bis", "ter", "ZI"]
|
||||||
|
for t in toponyms:
|
||||||
|
addr = re.sub(" " + t + " ", " " + t + " ", addr, flags=re.IGNORECASE)
|
||||||
|
return addr
|
||||||
|
|
||||||
|
def __guess_city_name(self, part):
|
||||||
|
part = part.strip().replace(" - ", "-")
|
||||||
|
if len(part) == 0:
|
||||||
|
return None
|
||||||
|
part = self.__remove_accents(part.lower()).replace("-", " ")
|
||||||
|
match = [x[1] for x in self.__citynames if x[0] == part]
|
||||||
|
if len(match) > 0:
|
||||||
|
return match[0]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __guess_city_name_postcode(self, part):
|
||||||
|
with_pc = re.search(r'^(.*)(([0-9][ ]*){5})(.*)$', part)
|
||||||
|
if with_pc:
|
||||||
|
p1 = self.__guess_city_name(with_pc.group(1).strip())
|
||||||
|
postcode = with_pc.group(2).replace(" ", "")
|
||||||
|
p2 = self.__guess_city_name(with_pc.group(4).strip())
|
||||||
|
return postcode, p2, p1
|
||||||
|
else:
|
||||||
|
return None, self.__guess_city_name(part), None
|
||||||
|
|
||||||
|
def __guess_name_address(self, part):
|
||||||
|
with_num = re.search(r'^(([^0-9])+)([0-9]+)(.*)', part)
|
||||||
|
if with_num:
|
||||||
|
name = with_num.group(1)
|
||||||
|
return name, part[len(name):]
|
||||||
|
else:
|
||||||
|
return "", part
|
||||||
|
|
||||||
|
def guess_address_elements(self, alias):
|
||||||
|
parts = re.split(r'[,/à]', alias)
|
||||||
|
parts = [p1 for p1 in [p.strip() for p in parts] if p1 != "" and p1.lower() != "france"]
|
||||||
|
|
||||||
|
name = ""
|
||||||
|
address = ""
|
||||||
|
postcode = ""
|
||||||
|
city = ""
|
||||||
|
possible_city = ""
|
||||||
|
|
||||||
|
oparts = []
|
||||||
|
for part in parts:
|
||||||
|
p, c, possible_c = self.__guess_city_name_postcode(part)
|
||||||
|
if not possible_c is None:
|
||||||
|
possible_city = possible_c
|
||||||
|
if not c is None and city == "":
|
||||||
|
city = c
|
||||||
|
if not p is None and postcode == "":
|
||||||
|
postcode = p
|
||||||
|
if p is None and c is None:
|
||||||
|
oparts.append(part)
|
||||||
|
|
||||||
|
if city == "" and possible_city != "":
|
||||||
|
city = possible_city
|
||||||
|
else:
|
||||||
|
if len(oparts) == 0 and not possible_city != "":
|
||||||
|
oparts = [possible_city]
|
||||||
|
|
||||||
|
if city == "":
|
||||||
|
alias_simple = self.__remove_accents(alias.lower()).replace("-", " ")
|
||||||
|
mc = [x[1] for x in self.__citynames if alias_simple.endswith(" " + x[0])]
|
||||||
|
if len(mc) == 1:
|
||||||
|
city = mc[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if len(oparts) > 0:
|
||||||
|
if not self.__guess_is_address(oparts[0]):
|
||||||
|
name = oparts[0]
|
||||||
|
address = ", ".join(oparts[1:])
|
||||||
|
else:
|
||||||
|
name, address = self.__guess_name_address(", ".join(oparts))
|
||||||
|
|
||||||
|
address = self.__clean_address(address)
|
||||||
|
|
||||||
|
if name == "" and possible_city != "" and possible_city != city:
|
||||||
|
name = possible_city
|
||||||
|
|
||||||
|
return name, address, postcode, city
|
||||||
|
|
@ -12,6 +12,7 @@ from django.contrib.postgres.search import SearchQuery, SearchHeadline
|
|||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from honeypot.decorators import check_honeypot
|
from honeypot.decorators import check_honeypot
|
||||||
|
from .utils import PlaceGuesser
|
||||||
|
|
||||||
|
|
||||||
from django.contrib.gis.geos import Point
|
from django.contrib.gis.geos import Point
|
||||||
@ -1864,16 +1865,30 @@ class UnknownPlaceAddView(PermissionRequiredMixin, SuccessMessageMixin, UpdateVi
|
|||||||
|
|
||||||
|
|
||||||
class PlaceFromEventCreateView(PlaceCreateView):
|
class PlaceFromEventCreateView(PlaceCreateView):
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context["event"] = self.event
|
context["event"] = self.event
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
if self.event.location and "add" in self.request.GET:
|
||||||
|
kwargs["force_adjust"] = True
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
def get_initial(self, *args, **kwargs):
|
def get_initial(self, *args, **kwargs):
|
||||||
initial = super().get_initial(**kwargs)
|
initial = super().get_initial(**kwargs)
|
||||||
self.event = get_object_or_404(Event, pk=self.kwargs["pk"])
|
self.event = get_object_or_404(Event, pk=self.kwargs["pk"])
|
||||||
if self.event.location and "add" in self.request.GET:
|
if self.event.location and "add" in self.request.GET:
|
||||||
initial["aliases"] = [self.event.location]
|
initial["aliases"] = [self.event.location]
|
||||||
|
guesser = PlaceGuesser()
|
||||||
|
name, address, postcode, city = guesser.guess_address_elements(self.event.location)
|
||||||
|
initial["name"] = name
|
||||||
|
initial["address"] = address
|
||||||
|
initial["city"] = city
|
||||||
|
|
||||||
return initial
|
return initial
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
Loading…
Reference in New Issue
Block a user