Example #1
0
def language_code_formfield_callback(db_field, **kwargs):
    language_code = getattr(db_field, "_translated_field_language_code", "")
    if language_code:
        kwargs["label"] = keep_lazy_text(lambda s: f"{s} [{language_code}]")(
            capfirst(db_field.verbose_name)
        )
    return db_field.formfield(**kwargs)
Example #2
0
    def __init__(self,
                 model,
                 field,
                 *args,
                 for_country=None,
                 operation=None,
                 **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.fields = forms.fields_for_model(model, [field])

        if for_country and for_country in COUNTRIES_DATA:
            country_data = COUNTRIES_DATA[for_country]
            self.country_regions = CountryRegion.objects.filter(
                country=for_country)
            regions = [(r.iso_code, r.get_display_value_with_esperanto())
                       for r in self.country_regions] + BLANK_CHOICE_DASH
            if len(regions) > 1:
                # Replacing a form field must happen before the `_bound_fields_cache` is populated.
                # Note: the 'chosen' JS addon interferes with normal HTML form functioning (including
                #       showing form validation errors), that is why we keep the field not required.
                # Using a ModelChoiceField here, while more natural, is also more cumbersome, since
                # both the field itself (for labels) and the ModelChoiceIterator (for sorting) must
                # be subclassed.
                RegionChoice = namedtuple('Choice', 'code, label')
                self.fields[field] = forms.ChoiceField(
                    choices=sort_by(['label'],
                                    (RegionChoice(*r) for r in regions)),
                    initial=self.fields[field].initial,
                    required=False,
                    label=self.fields[field].label,
                    help_text=self.fields[field].help_text,
                    error_messages={
                        'invalid_choice':
                        _("Choose from the list. The name provided by you is not known."
                          ),
                    },
                )
            elif for_country in countries_with_mandatory_region():
                # We don't want to raise an error, preventing the user from using the form,
                # but we do want to log it and notify the administrators.
                logging.getLogger('PasportaServo.address').error(
                    "Service misconfigured: Mandatory regions for %s are not defined!"
                    "  (noted when %s)",
                    getattr(for_country, 'code', for_country),
                    operation or "preparing choice field",
                )
            region_type = country_data.get('administrative_area_type')
            if region_type in SUBREGION_TYPES:
                capitalize_lazy = keep_lazy_text(
                    lambda label: label.capitalize())
                self.fields[field].label = capitalize_lazy(
                    SUBREGION_TYPES[region_type])
                self.fields[field].localised_label = True

        self.fields[field].widget.attrs['data-search-threshold'] = 6
Example #3
0
 def get_permission_denied_message(self):
     try:
         countries = [self.country]
     except AttributeError:
         countries = set(self.user.profile.owned_places.filter(
             available=True, deleted=False).values_list('country', flat=True))
         if not countries:
             return _("Only administrators can access this page")
     to_string = lambda item: str(Country(item).name)
     join_lazy = keep_lazy_text(lambda items: ", ".join(map(to_string, items)))
     return format_lazy(self.permission_denied_message, this_country=join_lazy(countries))
Example #4
0
 def get_permission_denied_message(self):
     try:
         countries = [self.country]
     except AttributeError:
         countries = set(
             self.user.profile.owned_places.filter(
                 available=True, deleted=False).values_list('country',
                                                            flat=True))
         if not countries:
             return _("Only administrators can access this page")
     to_string = lambda item: str(Country(item).name)
     join_lazy = keep_lazy_text(
         lambda items: ", ".join(map(to_string, items)))
     return format_lazy(self.permission_denied_message,
                        this_country=join_lazy(countries))
Example #5
0
 def get_permission_denied_message(self, object, context_omitted=False):
     if not context_omitted:
         countries = [self.get_location(object)]
         if not countries[0]:
             countries = self.get_owner(object).owned_places.filter(
                 deleted=False
             ).values_list('country', flat=True).distinct()
         elif not countries[0].name:
             countries = []
     else:
         countries = None
     if not countries:
         return _("Only administrators can access this page")
     to_string = lambda item: str(Country(item).name)
     join_lazy = keep_lazy_text(lambda items: ", ".join(map(to_string, items)))
     return format_lazy(self.permission_denied_message, this_country=join_lazy(countries))
Example #6
0
 def get_permission_denied_message(self, object, context_omitted=False):
     if not context_omitted:
         countries = [self.get_location(object)]
         if not countries[0]:
             countries = self.get_owner(object).owned_places.filter(
                 deleted=False
             ).values_list('country', flat=True).distinct()
         elif not countries[0].name:
             countries = []
     else:
         countries = None
     if not countries:
         return _("Only administrators can access this page")
     to_string = lambda item: str(Country(item).name)
     join_lazy = keep_lazy_text(lambda items: ", ".join(map(to_string, items)))
     return format_lazy(self.permission_denied_message, this_country=join_lazy(countries))
Example #7
0
from django.utils.encoding import force_text
from django.utils.functional import SimpleLazyObject, keep_lazy, keep_lazy_text
from django.utils.safestring import SafeText, mark_safe
from django.utils.six.moves import html_entities
from django.utils.translation import pgettext, ugettext as _, ugettext_lazy

if six.PY2:
    # Import force_unicode even though this module doesn't use it, because some
    # people rely on it being here.
    from django.utils.encoding import force_unicode  # NOQA


# Capitalizes the first letter of a string.
def capfirst(x):
    return x and force_text(x)[0].upper() + force_text(x)[1:]
capfirst = keep_lazy_text(capfirst)

# Set up regular expressions
re_words = re.compile(r'<.*?>|((?:\w[-\w]*|&.*?;)+)', re.U | re.S)
re_chars = re.compile(r'<.*?>|(.)', re.U | re.S)
re_tag = re.compile(r'<(/)?([^ ]+?)(?:(\s*/)| .*?)?>', re.S)
re_newlines = re.compile(r'\r\n|\r')  # Used in normalize_newlines
re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')


@keep_lazy_text
def wrap(text, width):
    """
    A word-wrap function that preserves existing line breaks. Expects that
    existing line breaks are posix newlines.
Example #8
0
class SimpleDonorForm(MetaFieldsMixin, forms.ModelForm):
    meta_fields = ["nationality"]
    button_label = "Je donne {amount}"

    email = forms.EmailField(
        label=_("Votre adresse email"),
        required=True,
        help_text=_(
            "Si vous êtes déjà inscrit⋅e sur la plateforme, utilisez l'adresse avec laquelle vous êtes inscrit⋅e"
        ),
    )

    subscribed = forms.BooleanField(
        label=_(
            "Je souhaite être tenu informé de l'actualité de la France insoumise par email."
        ),
        required=False,
    )

    amount = forms.IntegerField(
        max_value=settings.DONATION_MAXIMUM * 100,
        min_value=settings.DONATION_MINIMUM * 100,
        required=True,
        widget=forms.HiddenInput,
    )

    declaration = forms.BooleanField(
        required=True,
        label=_(
            "Je certifie sur l'honneur être une personne physique et que le réglement de mon don ne provient pas"
            " d'une personne morale (association, société, société civile...) mais de mon compte bancaire"
            " personnel."
        ),
        help_text=keep_lazy_text(mark_safe)(
            'Un reçu, édité par la <abbr title="Commission Nationale des comptes de campagne et des financements'
            ' politiques">CNCCFP</abbr>, me sera adressé, et me permettra de déduire cette somme de mes impôts'
            " dans les limites fixées par la loi."
        ),
    )

    nationality = CountryField(
        blank=False, blank_label=_("Indiquez le pays dont vous êtes citoyen")
    ).formfield(
        label=_("Nationalité"),
        help_text=_(
            "Indiquez France, si vous êtes de double nationalité, dont française."
        ),
    )

    fiscal_resident = forms.BooleanField(
        required=False,
        widget=forms.CheckboxInput(attrs={"disabled": True}),
        label=_("Je certifie être domicilié⋅e fiscalement en France"),
    )

    def __init__(self, *args, amount, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields["amount"].initial = amount

        self.adding = self.instance._state.adding

        if not self.adding:
            del self.fields["email"]

        # we remove the subscribed field for people who are already subscribed
        if not self.adding and self.instance.subscribed:
            del self.fields["subscribed"]

        for f in [
            "first_name",
            "last_name",
            "location_address1",
            "location_zip",
            "location_city",
            "location_country",
            "contact_phone",
        ]:
            self.fields[f].required = True
        self.fields["location_address1"].label = "Adresse"
        self.fields["location_address2"].label = False
        self.fields["contact_phone"].help_text = (
            "Nous sommes dans l'obligation de pouvoir vous contacter en cas "
            "de demande de vérification par la CNCCFP."
        )

        fields = ["amount"]

        if "email" in self.fields:
            fields.append("email")

        fields.extend(["nationality", "fiscal_resident"])
        fields.extend(["first_name", "last_name"])
        fields.extend(
            [
                layout.Field("location_address1", placeholder="Ligne 1"),
                layout.Field("location_address2", placeholder="Ligne 2"),
            ]
        )

        fields.append(
            Row(
                layout.Div("location_zip", css_class="col-md-4"),
                layout.Div("location_city", css_class="col-md-8"),
            )
        )

        fields.append("location_country")

        fields.append("contact_phone")

        fields.append("declaration")

        if "subscribed" in self.fields:
            fields.append("subscribed")

        self.helper = FormHelper()
        self.helper.add_input(
            layout.Submit(
                "valider",
                self.button_label.format(amount=number_format(amount / 100, 2) + " €"),
            )
        )
        self.helper.layout = layout.Layout(*fields)

    def clean(self):
        cleaned_data = super().clean()

        nationality, fiscal_resident, location_country = (
            cleaned_data.get("nationality"),
            cleaned_data.get("fiscal_resident"),
            cleaned_data.get("location_country"),
        )

        if (
            "fiscal_resident" in self.fields
            and nationality != "FR"
            and not fiscal_resident
        ):
            self.add_error(
                "fiscal_resident",
                forms.ValidationError(
                    _(
                        "Les personnes non-françaises doivent être fiscalement domiciliées en France."
                    ),
                    code="not_fiscal_resident",
                ),
            )

        if fiscal_resident and location_country not in FRANCE_COUNTRY_CODES:
            self.add_error(
                "location_country",
                forms.ValidationError(
                    _(
                        "Pour pouvoir donner si vous n'êtes pas français, vous devez être domicilié⋅e fiscalement en"
                        " France et nous indiquer votre adresse fiscale en France."
                    )
                ),
            )

        return cleaned_data

    class Meta:
        model = Person
        fields = (
            "first_name",
            "last_name",
            "location_address1",
            "location_address2",
            "location_zip",
            "location_city",
            "location_country",
            "contact_phone",
            "subscribed",
        )
Example #9
0
from django.utils.safestring import SafeText, mark_safe
from django.utils.six.moves import html_entities
from django.utils.translation import pgettext, ugettext as _, ugettext_lazy

if six.PY2:
    # Import force_unicode even though this module doesn't use it, because some
    # people rely on it being here.
    from django.utils.encoding import force_unicode  # NOQA


# Capitalizes the first letter of a string.
def capfirst(x):
    return x and force_text(x)[0].upper() + force_text(x)[1:]


capfirst = keep_lazy_text(capfirst)

# Set up regular expressions
re_words = re.compile(r'<.*?>|((?:\w[-\w]*|&.*?;)+)', re.U | re.S)
re_chars = re.compile(r'<.*?>|(.)', re.U | re.S)
re_tag = re.compile(r'<(/)?([^ ]+?)(?:(\s*/)| .*?)?>', re.S)
re_newlines = re.compile(r'\r\n|\r')  # Used in normalize_newlines
re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')


@keep_lazy_text
def wrap(text, width):
    """
    A word-wrap function that preserves existing line breaks. Expects that
    existing line breaks are posix newlines.
Example #10
0
from django.conf import settings
from django.utils.encoding import smart_bytes
from django.utils.functional import keep_lazy_text
from django.utils.http import urlencode
from django.utils.text import Truncator

from userena import settings as userena_settings
from userena.compat import SiteProfileNotAvailable


def truncate_words(s, num, end_text="..."):
    truncate = end_text and " %s" % end_text or ""
    return Truncator(s).words(num, truncate=truncate)


truncate_words = keep_lazy_text(truncate_words)


def get_gravatar(email, size=80, default="identicon"):
    """ Get's a Gravatar for a email address.

    :param size:
        The size in pixels of one side of the Gravatar's square image.
        Optional, if not supplied will default to ``80``.

    :param default:
        Defines what should be displayed if no image is found for this user.
        Optional argument which defaults to ``identicon``. The argument can be
        a URI to an image or one of the following options:

            ``404``
Example #11
0
@register.filter
@stringfilter
def title(value):
    '''
    A slightly better title template filter.

    Same as Django's builtin `~django.template.defaultfilters.title` filter,
    but operates on individual words and leaves words unchanged if they already
    have a capital letter or a digit. Actually Django's filter also skips
    words with digits but only for latin letters (or at least not for
    cyrillic ones).
    '''
    return ' '.join([
        any([c.isupper() or c.isdigit() for c in w]) and w or old_title(w)
        for w in value.split()
    ])


title.is_safe = True

try:
    from django.utils.functional import keep_lazy_text
    title = keep_lazy_text(title)
except ImportError:
    # to keep backward (Django < 1.10) compatibility
    from django.utils.functional import lazy
    title = lazy(title, six.text_type)

register.filter('localize', l10n_register.filters['localize'])
register.filter('unlocalize', l10n_register.filters['unlocalize'])
Example #12
0
    """
    Converts AStringInCamelCase to a list of separate words.
    """
    # stackoverflow.com/a/29920015/1019109 -by- stackoverflow.com/u/1157100/200-success
    matches = re.finditer(
        '.+?(?:(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|$)', identifier)
    return [m.group(0) for m in matches]


def _lazy_joiner(sep, items, item_to_string=str):
    return str(sep).join(map(item_to_string, items))


join_lazy = lazy(_lazy_joiner, str)  # noqa:E305

mark_safe_lazy = keep_lazy_text(mark_safe)


def send_mass_html_mail(datatuple,
                        fail_silently=False,
                        user=None,
                        password=None,
                        connection=None):
    """
    Given a datatuple of (subject, text_content, html_content, from_email,
    recipient_list), sends each message to each recipient list. Returns the
    number of emails sent.

    If from_email is None, the DEFAULT_FROM_EMAIL setting is used.
    If auth_user and auth_password are set, they're used to log in.
    If auth_user is None, the EMAIL_HOST_USER setting is used.
Example #13
0
from django.utils.encoding import smart_bytes
from django.utils.functional import keep_lazy_text
from django.utils.http import urlencode
from django.utils.six import text_type
from django.utils.text import Truncator

from userena import settings as userena_settings
from userena.compat import SiteProfileNotAvailable


def truncate_words(s, num, end_text='...'):
    truncate = end_text and ' %s' % end_text or ''
    return Truncator(s).words(num, truncate=truncate)


truncate_words = keep_lazy_text(truncate_words)


def get_gravatar(email, size=80, default='identicon'):
    """ Get's a Gravatar for a email address.

    :param size:
        The size in pixels of one side of the Gravatar's square image.
        Optional, if not supplied will default to ``80``.

    :param default:
        Defines what should be displayed if no image is found for this user.
        Optional argument which defaults to ``identicon``. The argument can be
        a URI to an image or one of the following options:

            ``404``
from string import digits
from datetime import date
import re

from django.core.validators import MinValueValidator, MaxValueValidator
from django.core.exceptions import ValidationError, ImproperlyConfigured
from django.utils.deconstruct import deconstructible
from django.template.defaultfilters import filesizeformat
from django.utils.translation import ugettext_lazy as _

try:
    from django.utils.text import format_lazy  # coming in Django 1.11
except ImportError:
    from django.utils.functional import keep_lazy_text

    format_lazy = keep_lazy_text(lambda s, *args, **kwargs: s.format(*args, **kwargs))

from .utils import split, title_with_particule


def validate_not_all_caps(value):
    """Tries to figure out whether the value is all caps while it shouldn't be.
    Validates until 3 characters and non latin strings.
    """
    if len(value) > 3 and value[-1:].isupper() and value == value.upper():
        message = _("Today is not CapsLock day. Please try with '{correct_value}'.")
        raise ValidationError(format_lazy(message, correct_value=title_with_particule(value)), code="caps")


def validate_not_too_many_caps(value):
    """Tries to figure out whether the value has too many capitals.
Example #15
0
from django import forms
from django.conf import settings
from datetime import date
from django.utils.translation import ugettext_lazy as _
try:
    from django.utils.text import format_lazy  # coming in Django 1.11
except ImportError:
    from django.utils.functional import keep_lazy_text
    format_lazy = keep_lazy_text(lambda s, *args, **kwargs: s.format(*args, **kwargs))
from django.contrib.auth import get_user_model

from .models import Profile, Place, Phone
from .validators import TooNearPastValidator, client_side_validated
from .widgets import ClearableWithPreviewImageInput

User = get_user_model()


@client_side_validated
class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = [
            'title',
            'first_name',
            'last_name',
            'names_inversed',
            'birth_date',
            'description',
            'avatar',
        ]