Пример #1
0
    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/*'
Пример #2
0
    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
Пример #3
0
 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)
Пример #4
0
 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)
Пример #5
0
    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
Пример #6
0
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
Пример #7
0
    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/*'
Пример #8
0
 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,
     )
Пример #9
0
 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()
Пример #10
0
 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()
Пример #11
0
    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)
Пример #12
0
    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/*'
Пример #13
0
 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,
     )
Пример #14
0
    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
Пример #15
0
    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()))
Пример #16
0
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})
Пример #17
0
 def get_context_data(self, **kwargs):
     return {
         'key': SiteConfiguration.get_solo().openmaptiles_api_key,
         'lang': settings.LANGUAGE_CODE,
     }
Пример #18
0
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