def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) config = SiteConfiguration.get_solo() self.fields['first_name'].widget.attrs['inputmode'] = 'latin-name' self.fields['last_name'].widget.attrs['inputmode'] = 'latin-name' self.fields['names_inversed'].label = _("Names ordering") field_bd = self.fields['birth_date'] if (hasattr(self, 'instance') and (self.instance.has_places_for_hosting or self.instance.has_places_for_meeting)): if self.instance.has_places_for_hosting: message = _("The minimum age to be allowed hosting is {age:d}.") allowed_age = config.host_min_age else: message = _("The minimum age to be allowed meeting with visitors is {age:d}.") allowed_age = config.meet_min_age message = format_lazy(message, age=allowed_age) field_bd.required = True field_bd.validators.append(TooNearPastValidator(allowed_age)) field_bd.error_messages['max_value'] = message field_bd.widget.attrs['placeholder'] = 'jjjj-mm-tt' field_bd.widget.attrs['data-date-end-date'] = '0d' field_bd.widget.attrs['pattern'] = '[1-2][0-9]{3}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[0-1]))' if hasattr(self, 'instance') and self.instance.has_places_for_book: message = _("This field is required to be printed in the book.") for field in self._validation_meta.book_required_fields: req_field = self.fields[field] req_field.required = True req_field.error_messages['required'] = message req_field.widget.attrs['data-error-required'] = message self.fields['avatar'].widget.attrs['accept'] = 'image/*'
def clean(self): cleaned_data = super().clean() config = SiteConfiguration.get_solo() for_hosting = cleaned_data['available'] for_meeting = cleaned_data['tour_guide'] or cleaned_data['have_a_drink'] if any([for_hosting, for_meeting]): # Verifies that user is of correct age if they want to host or meet visitors. profile = self.profile if hasattr(self, 'profile') else self.instance.owner try: allowed_age = config.host_min_age if for_hosting else config.meet_min_age TooNearPastValidator(allowed_age)(profile.birth_date or date.today()) except forms.ValidationError: if for_hosting: self.add_error('available', "") message = _("The minimum age to be allowed hosting is {age:d}.") else: if cleaned_data['tour_guide']: self.add_error('tour_guide', "") if cleaned_data['have_a_drink']: self.add_error('have_a_drink', "") message = _("The minimum age to be allowed meeting with visitors is {age:d}.") raise forms.ValidationError(format_lazy(message, age=allowed_age)) # Some fields are required if user wants to host or to meet visitors, # or wants their data to be printed in the book. Req = namedtuple('Requirements', 'on, required_fields, form_error, field_error') requirements = [ Req(for_hosting, self._validation_meta.hosting_required_fields, None, forms.ValidationError(_("This field is required if you accept guests."), code='host_condition')), Req(for_meeting, self._validation_meta.meeting_required_fields, None, forms.ValidationError(_("This field is required if you meet visitors."), code='host_condition')), Req(cleaned_data['in_book'], self._validation_meta.book_required_fields, _("You want to be in the printed edition of Pasporta Servo. " "In order to have a quality product, some fields are required. " "If you think there is a problem, please contact us."), forms.ValidationError(_("This field is required to be printed in the book."), code='book_condition')), ] message = [] for cond in requirements: all_filled = all([cleaned_data.get(field, False) for field in cond.required_fields]) if cond.on and not all_filled: for field in cond.required_fields: if not cleaned_data.get(field, False) and not self.has_error(field, cond.field_error.code): self.add_error(field, cond.field_error) if cond.form_error: message += forms.ValidationError(cond.form_error) if message: raise forms.ValidationError(message) return cleaned_data
def get(self, request, *args, **kwargs): config = SiteConfiguration.get_solo() self.token = kwargs.pop('token') s = URLSafeTimedSerializer(settings.SECRET_KEY, salt=config.salt) try: payload = s.loads(self.token, max_age=config.token_max_age) except SignatureExpired: self.template_name = 'links/signature_expired.html' except BadTimeSignature: self.template_name = 'links/bad_time_signature.html' else: return self.redirect(request, payload, *args, **kwargs) return super().get(request, *args, **kwargs)
def get(self, request, *args, **kwargs): config = SiteConfiguration.get_solo() self.token = kwargs.pop('token') s = URLSafeTimedSerializer(settings.SECRET_KEY, salt=config.salt) try: payload = s.loads(self.token, max_age=config.token_max_age) except SignatureExpired: self.template_name = 'links/signature_expired.html' except BadTimeSignature: self.template_name = 'links/bad_time_signature.html' else: return self.redirect(request, payload, *args, **kwargs) return super().get(request, *args, **kwargs)
def clean(self): cleaned_data = super().clean() config = SiteConfiguration.get_solo() # Verifies that user is of correct age if they want to host or meet guests. is_hosting = cleaned_data['available'] is_meeting = cleaned_data['tour_guide'] or cleaned_data['have_a_drink'] if any([is_hosting, is_meeting]): profile = self.profile if hasattr( self, 'profile') else self.instance.owner try: allowed_age = config.host_min_age if is_hosting else config.meet_min_age TooNearPastValidator(allowed_age)(profile.birth_date or date.today()) except forms.ValidationError: if is_hosting: self.add_error('available', "") message = _( "The minimum age to be allowed hosting is {age:d}.") else: if cleaned_data['tour_guide']: self.add_error('tour_guide', "") if cleaned_data['have_a_drink']: self.add_error('have_a_drink', "") message = _( "The minimum age to be allowed meeting with visitors is {age:d}." ) raise forms.ValidationError( format_lazy(message, age=allowed_age)) # Sets some fields as required if user wants their data to be printed in book. required_fields = [ 'address', 'city', 'closest_city', 'country', 'available' ] all_filled = all( [cleaned_data.get(field, False) for field in required_fields]) message = _( "You want to be in the printed edition of Pasporta Servo. " "In order to have a quality product, some fields a required. " "If you think there is a problem, please contact us.") if cleaned_data['in_book'] and not all_filled: for field in required_fields: if not cleaned_data.get(field, False): self.add_error( field, _("This field is required to be printed in the book.")) raise forms.ValidationError(message) return cleaned_data
def geocode(query, country='', private=False, annotations=False, multiple=False): key = SiteConfiguration.get_solo().opencage_api_key lang = settings.LANGUAGE_CODE if not query: return params = {'language': lang} if not annotations: params.update({'no_annotations': int(not annotations)}) if private: params.update({'no_record': int(private)}) if country: params.update({'countrycode': country}) result = geocoder.opencage(query, key=key, params=params, maxRows=15 if multiple else 1) logging.getLogger('PasportaServo.geo').debug( "Query: %s\n\tResult: %s\n\tConfidence: %d", query, result, result.confidence) result.point = Point(result.xy, srid=SRID) if result.xy else None return result
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) config = SiteConfiguration.get_solo() self.helper = FormHelper(self) self.fields['first_name'].widget.attrs['inputmode'] = 'latin-name' self.fields['last_name'].widget.attrs['inputmode'] = 'latin-name' self.fields['names_inversed'].label = _("Names ordering") self.helper['names_inversed'].wrap( InlineRadios, radio_label_class='person-full-name') field_bd = self.fields['birth_date'] if self.instance.has_places_for_hosting or self.instance.has_places_for_meeting: if self.instance.has_places_for_hosting: message = _( "The minimum age to be allowed hosting is {age:d}.") allowed_age = config.host_min_age else: message = _( "The minimum age to be allowed meeting with visitors is {age:d}." ) allowed_age = config.meet_min_age message = format_lazy(message, age=allowed_age) field_bd.required = True field_bd.validators.append(TooNearPastValidator(allowed_age)) # We have to manually create a copy of the error messages dict because Django does not do it: # https://code.djangoproject.com/ticket/30839#ticket field_bd.error_messages = deepcopy(field_bd.error_messages) field_bd.error_messages['max_value'] = message field_bd.widget.attrs['placeholder'] = 'jjjj-mm-tt' field_bd.widget.attrs['data-date-end-date'] = '0d' field_bd.widget.attrs[ 'pattern'] = '[1-2][0-9]{3}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[0-1]))' if self.instance.has_places_for_in_book: message = _("This field is required to be printed in the book.") for field in self._validation_meta.book_required_fields: req_field = self.fields[field] req_field.required = True # We have to manually create a copy of the error messages dict because Django does not do it: # https://code.djangoproject.com/ticket/30839#ticket req_field.error_messages = deepcopy(req_field.error_messages) req_field.error_messages['required'] = message req_field.widget.attrs['data-error-required'] = message self.fields['avatar'].widget.attrs['accept'] = 'image/*'
def send_email(self, user, place): config = SiteConfiguration.get_solo() subject = _("[Pasporta Servo] You received an Authorization") email_template_text = get_template('email/new_authorization.txt') email_template_html = get_template('email/new_authorization.html') email_context = { 'site_name': config.site_name, 'user': user, 'place': place, } send_mail( subject, email_template_text.render(email_context), settings.DEFAULT_FROM_EMAIL, recipient_list=[user.email], html_message=email_template_html.render(email_context), fail_silently=False, )
def get_queryset(self): try: validity_period = SiteConfiguration.get_solo( ).confirmation_validity_period except ProgrammingError: from datetime import timedelta validity_period = timedelta(weeks=42) validity_start = timezone.now() - validity_period return super().get_queryset().annotate( deleted=Case(When(deleted_on__isnull=True, then=False), default=True, output_field=BooleanField()) ).annotate( confirmed=Case(When(confirmed_on__isnull=True, then=False), When(confirmed_on__lt=validity_start, then=False), default=True, output_field=BooleanField())).annotate(checked=Case( When(checked_on__isnull=True, then=False), When(checked_on__lt=validity_start, then=False), default=True, output_field=BooleanField())).select_related()
def get_queryset(self): try: validity_period = SiteConfiguration.get_solo().confirmation_validity_period except ProgrammingError: from datetime import timedelta validity_period = timedelta(weeks=42) validity_start = timezone.now() - validity_period return super().get_queryset().annotate(deleted=Case( When(deleted_on__isnull=True, then=False), default=True, output_field=BooleanField() )).annotate(confirmed=Case( When(confirmed_on__isnull=True, then=False), When(confirmed_on__lt=validity_start, then=False), default=True, output_field=BooleanField() )).annotate(checked=Case( When(checked_on__isnull=True, then=False), When(checked_on__lt=validity_start, then=False), default=True, output_field=BooleanField() )).select_related()
def setUpTestData(cls): cls.host_required_fields = [ 'birth_date', ] cls.book_required_fields = [ 'birth_date', 'gender', 'first_name', 'last_name', ] cls.config = SiteConfiguration.get_solo() cls.faker = Faker._get_faker() TaggedProfile = namedtuple('TaggedProfile', 'obj, tag') cls.profile_with_no_places = TaggedProfile(ProfileFactory(), "simple") cls.profile_with_no_places_deceased = TaggedProfile(ProfileFactory(deceased=True), "deceased") profile = ProfileFactory() cls.profile_hosting = TaggedProfile(profile, "hosting") PlaceFactory(owner=profile, available=True) profile = ProfileFactory() cls.profile_meeting = TaggedProfile(profile, "meeting") PlaceFactory(owner=profile, available=False, have_a_drink=True) profile = ProfileFactory() cls.profile_hosting_and_meeting = TaggedProfile(profile, "hosting & meeting") PlaceFactory(owner=profile, available=True) PlaceFactory(owner=profile, available=False, tour_guide=True) profile = ProfileFactory() cls.profile_in_book = TaggedProfile(profile, "in book (simple)") PlaceFactory(owner=profile, available=True, in_book=True) profile = ProfileFactory() cls.profile_in_book_complex = TaggedProfile(profile, "in book (complex)") PlaceFactory(owner=profile, available=True, in_book=True) PlaceFactory(owner=profile, available=True, in_book=False) PlaceFactory(owner=profile, available=False, have_a_drink=True, in_book=False)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) config = SiteConfiguration.get_solo() self.fields['first_name'].widget.attrs['inputmode'] = 'latin-name' self.fields['last_name'].widget.attrs['inputmode'] = 'latin-name' self.fields['names_inversed'].label = _("Names ordering") field_bd = self.fields['birth_date'] if (hasattr(self, 'instance') and (self.instance.has_places_for_hosting or self.instance.has_places_for_meeting)): if self.instance.has_places_for_hosting: message = _( "The minimum age to be allowed hosting is {age:d}.") allowed_age = config.host_min_age else: message = _( "The minimum age to be allowed meeting with visitors is {age:d}." ) allowed_age = config.meet_min_age message = format_lazy(message, age=allowed_age) field_bd.required = True field_bd.validators.append(TooNearPastValidator(allowed_age)) field_bd.error_messages['max_value'] = message field_bd.widget.attrs['placeholder'] = 'jjjj-mm-tt' field_bd.widget.attrs['data-date-end-date'] = '0d' field_bd.widget.attrs[ 'pattern'] = '[1-2][0-9]{3}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[0-1]))' if hasattr(self, 'instance') and self.instance.has_places_for_book: message = _("This field is required to be printed in the book.") for field in self._validation_meta.book_required_fields: req_field = self.fields[field] req_field.required = True req_field.error_messages['required'] = message req_field.widget.attrs['data-error-required'] = message self.fields['avatar'].widget.attrs['accept'] = 'image/*'
def send_email(self, user, place): config = SiteConfiguration.get_solo() email_template_subject = get_template( 'email/new_authorization_subject.txt') email_template_text = get_template('email/new_authorization.txt') email_template_html = get_template('email/new_authorization.html') # TODO : Unsubscribe link in the email email_context = { 'site_name': config.site_name, 'ENV': settings.ENVIRONMENT, 'subject_prefix': settings.EMAIL_SUBJECT_PREFIX_FULL, 'user': user, 'place': place, } # TODO : send mail only if the user chose to receive this type send_mail( ''.join(email_template_subject.render(email_context).splitlines()), email_template_text.render(email_context), settings.DEFAULT_FROM_EMAIL, recipient_list=[user.email], html_message=email_template_html.render(email_context), fail_silently=False, )
def clean(self): cleaned_data = super().clean() config = SiteConfiguration.get_solo() # Verifies that user is of correct age if they want to host or meet guests. for_hosting = cleaned_data['available'] for_meeting = cleaned_data['tour_guide'] or cleaned_data['have_a_drink'] if any([for_hosting, for_meeting]): profile = self.profile if hasattr(self, 'profile') else self.instance.owner try: allowed_age = config.host_min_age if for_hosting else config.meet_min_age TooNearPastValidator(allowed_age)(profile.birth_date or date.today()) except forms.ValidationError: if for_hosting: self.add_error('available', "") message = _("The minimum age to be allowed hosting is {age:d}.") else: if cleaned_data['tour_guide']: self.add_error('tour_guide', "") if cleaned_data['have_a_drink']: self.add_error('have_a_drink', "") message = _("The minimum age to be allowed meeting with visitors is {age:d}.") raise forms.ValidationError(format_lazy(message, age=allowed_age)) # Sets some fields as required if user wants their data to be printed in book. all_filled = all([cleaned_data.get(field, False) for field in self._validation_meta.book_required_fields]) message = _("You want to be in the printed edition of Pasporta Servo. " "In order to have a quality product, some fields are required. " "If you think there is a problem, please contact us.") if cleaned_data['in_book'] and not all_filled: for field in self._validation_meta.book_required_fields: if not cleaned_data.get(field, False): self.add_error(field, _("This field is required to be printed in the book.")) raise forms.ValidationError(message) return cleaned_data
def setUpTestData(cls): cls.config = SiteConfiguration.get_solo() cls.faker = Faker._get_faker() cls.all_countries = Countries().countries.keys() cls.expected_fields = [ 'country', 'type', 'number', 'comments', ] cls.profile_one = ProfileFactory() cls.phone1_valid = PhoneFactory(profile=cls.profile_one) cls.phone2_valid = PhoneFactory(profile=cls.profile_one) cls.phone3_deleted = PhoneFactory( profile=cls.profile_one, deleted_on=make_aware(cls.faker.date_time_this_decade())) cls.profile_two = ProfileFactory() cls.phone4_valid = PhoneFactory(profile=cls.profile_two) cls.phone5_deleted = PhoneFactory( profile=cls.profile_two, deleted_on=make_aware(cls.faker.date_time_this_decade()))
def create_unique_url(payload, salt=None): config = SiteConfiguration.get_solo() salt = config.salt if salt is None else salt s = URLSafeTimedSerializer(settings.SECRET_KEY, salt=salt) token = s.dumps(payload) return reverse('unique_link', kwargs={'token': token})
def get_context_data(self, **kwargs): return { 'key': SiteConfiguration.get_solo().openmaptiles_api_key, 'lang': settings.LANGUAGE_CODE, }
def create_unique_url(payload, salt=None): config = SiteConfiguration.get_solo() salt = config.salt if salt is None else salt s = URLSafeTimedSerializer(settings.SECRET_KEY, salt=salt) token = s.dumps(payload) return reverse('unique_link', kwargs={'token': token}), token