forked from CGM_Public/pretix_original
Add support for GeoIP data (#3230)
This commit is contained in:
@@ -45,6 +45,7 @@ import pytz
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.gis.geoip2 import GeoIP2
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.core.validators import (
|
||||
@@ -91,6 +92,7 @@ from pretix.helpers.countries import (
|
||||
CachedCountries, get_phone_prefixes_sorted_and_localized,
|
||||
)
|
||||
from pretix.helpers.escapejson import escapejson_attr
|
||||
from pretix.helpers.http import get_client_ip
|
||||
from pretix.helpers.i18n import get_format_without_seconds
|
||||
from pretix.presale.signals import question_form_fields
|
||||
|
||||
@@ -351,6 +353,15 @@ class WrappedPhoneNumberPrefixWidget(PhoneNumberPrefixWidget):
|
||||
return ""
|
||||
|
||||
|
||||
def guess_country_from_request(request, event):
|
||||
if settings.HAS_GEOIP:
|
||||
g = GeoIP2()
|
||||
res = g.country(get_client_ip(request))
|
||||
if res['country_code'] and len(res['country_code']) == 2:
|
||||
return Country(res['country_code'])
|
||||
return guess_country(event)
|
||||
|
||||
|
||||
def guess_country(event):
|
||||
# Try to guess the initial country from either the country of the merchant
|
||||
# or the locale. This will hopefully save at least some users some scrolling :)
|
||||
@@ -382,6 +393,12 @@ def guess_phone_prefix(event):
|
||||
return get_phone_prefix(country)
|
||||
|
||||
|
||||
def guess_phone_prefix_from_request(request, event):
|
||||
with language(get_babel_locale()):
|
||||
country = str(guess_country_from_request(request, event))
|
||||
return get_phone_prefix(country)
|
||||
|
||||
|
||||
def get_phone_prefix(country):
|
||||
for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items():
|
||||
if country in values:
|
||||
@@ -564,6 +581,7 @@ class BaseQuestionsForm(forms.Form):
|
||||
:param cartpos: The cart position the form should be for
|
||||
:param event: The event this belongs to
|
||||
"""
|
||||
request = kwargs.pop('request', None)
|
||||
cartpos = self.cartpos = kwargs.pop('cartpos', None)
|
||||
orderpos = self.orderpos = kwargs.pop('orderpos', None)
|
||||
pos = cartpos or orderpos
|
||||
@@ -661,7 +679,7 @@ class BaseQuestionsForm(forms.Form):
|
||||
'autocomplete': 'address-level2',
|
||||
}),
|
||||
)
|
||||
country = (cartpos.country if cartpos else orderpos.country) or guess_country(event)
|
||||
country = (cartpos.country if cartpos else orderpos.country) or guess_country_from_request(request, event)
|
||||
add_fields['country'] = CountryField(
|
||||
countries=CachedCountries
|
||||
).formfield(
|
||||
@@ -768,7 +786,7 @@ class BaseQuestionsForm(forms.Form):
|
||||
help_text=help_text,
|
||||
widget=forms.Select,
|
||||
empty_label=' ',
|
||||
initial=initial.answer if initial else (guess_country(event) if required else None),
|
||||
initial=initial.answer if initial else (guess_country_from_request(request, event) if required else None),
|
||||
)
|
||||
elif q.type == Question.TYPE_CHOICE:
|
||||
field = forms.ModelChoiceField(
|
||||
@@ -856,7 +874,7 @@ class BaseQuestionsForm(forms.Form):
|
||||
initial = None
|
||||
|
||||
if not initial:
|
||||
phone_prefix = guess_phone_prefix(event)
|
||||
phone_prefix = guess_phone_prefix_from_request(request, event)
|
||||
if phone_prefix:
|
||||
initial = "+{}.".format(phone_prefix)
|
||||
|
||||
@@ -992,7 +1010,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
||||
|
||||
kwargs.setdefault('initial', {})
|
||||
if not kwargs.get('instance') or not kwargs['instance'].country:
|
||||
kwargs['initial']['country'] = guess_country(self.event)
|
||||
kwargs['initial']['country'] = guess_country_from_request(self.request, self.event)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
if not event.settings.invoice_address_vatid:
|
||||
|
||||
@@ -71,6 +71,7 @@ class BaseQuestionsViewMixin:
|
||||
kwargs = self.question_form_kwargs(cr)
|
||||
form = self.form_class(event=self.request.event,
|
||||
prefix=cr.id,
|
||||
request=self.request,
|
||||
cartpos=cartpos,
|
||||
orderpos=orderpos,
|
||||
all_optional=self.all_optional,
|
||||
|
||||
@@ -45,7 +45,7 @@ from phonenumber_field.formfields import PhoneNumberField
|
||||
|
||||
from pretix.base.forms.questions import (
|
||||
BaseInvoiceAddressForm, BaseQuestionsForm, WrappedPhoneNumberPrefixWidget,
|
||||
guess_phone_prefix,
|
||||
guess_phone_prefix_from_request,
|
||||
)
|
||||
from pretix.base.templatetags.rich_text import rich_text
|
||||
from pretix.base.validators import EmailBanlistValidator
|
||||
@@ -73,7 +73,7 @@ class ContactForm(forms.Form):
|
||||
|
||||
if self.event.settings.order_phone_asked:
|
||||
if not self.initial.get('phone'):
|
||||
phone_prefix = guess_phone_prefix(self.event)
|
||||
phone_prefix = guess_phone_prefix_from_request(self.request, self.event)
|
||||
if phone_prefix:
|
||||
# We now exploit an implementation detail in PhoneNumberPrefixWidget to allow us to pass just
|
||||
# a country code but no number as an initial value. It's a bit hacky, but should be stable for
|
||||
|
||||
@@ -25,7 +25,8 @@ from django.utils.translation import gettext_lazy as _
|
||||
from phonenumber_field.formfields import PhoneNumberField
|
||||
|
||||
from pretix.base.forms.questions import (
|
||||
NamePartsFormField, WrappedPhoneNumberPrefixWidget, guess_phone_prefix,
|
||||
NamePartsFormField, WrappedPhoneNumberPrefixWidget,
|
||||
guess_phone_prefix_from_request,
|
||||
)
|
||||
from pretix.base.models import Quota, WaitingListEntry
|
||||
from pretix.base.templatetags.rich_text import rich_text
|
||||
@@ -40,6 +41,7 @@ class WaitingListForm(forms.ModelForm):
|
||||
fields = ('name_parts', 'email', 'phone')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
request = kwargs.pop('request')
|
||||
self.event = kwargs.pop('event')
|
||||
self.channel = kwargs.pop('channel')
|
||||
customer = kwargs.pop('customer')
|
||||
@@ -93,7 +95,7 @@ class WaitingListForm(forms.ModelForm):
|
||||
|
||||
if event.settings.waiting_list_phones_asked:
|
||||
if not self.initial.get('phone'):
|
||||
phone_prefix = guess_phone_prefix(event)
|
||||
phone_prefix = guess_phone_prefix_from_request(request, event)
|
||||
if phone_prefix:
|
||||
self.initial['phone'] = "+{}.".format(phone_prefix)
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ class WaitingView(EventViewMixin, FormView):
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs['request'] = self.request
|
||||
kwargs['event'] = self.request.event
|
||||
kwargs['instance'] = WaitingListEntry(
|
||||
event=self.request.event, locale=get_language_without_region(),
|
||||
|
||||
@@ -330,6 +330,12 @@ ENTROPY = {
|
||||
'giftcard_secret': config.getint('entropy', 'giftcard_secret', fallback=12),
|
||||
}
|
||||
|
||||
HAS_GEOIP = False
|
||||
if config.has_option('geoip', 'path'):
|
||||
HAS_GEOIP = True
|
||||
GEOIP_PATH = config.get('geoip', 'path')
|
||||
GEOIP_COUNTRY = config.get('geoip', 'filename_country', fallback='GeoLite2-Country.mmdb')
|
||||
|
||||
# Internal settings
|
||||
PRETIX_EMAIL_NONE_VALUE = 'none@well-known.pretix.eu'
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ filterwarnings =
|
||||
ignore:django.contrib.staticfiles.templatetags.static:DeprecationWarning
|
||||
ignore::django.utils.deprecation.RemovedInDjango41Warning:
|
||||
ignore::DeprecationWarning:compressor
|
||||
ignore:pkg_resources is deprecated as an API:
|
||||
|
||||
|
||||
[coverage:run]
|
||||
|
||||
@@ -191,6 +191,7 @@ setup(
|
||||
'djangorestframework==3.14.*',
|
||||
'dnspython==2.2.*',
|
||||
'drf_ujson2==1.7.*',
|
||||
'geoip2==4.*',
|
||||
'isoweek',
|
||||
'jsonschema',
|
||||
'kombu==5.2.*',
|
||||
|
||||
Reference in New Issue
Block a user