diff --git a/Dockerfile b/Dockerfile index 127dc22c..b3ff0a95 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ RUN mkdir /mediaroot WORKDIR /code COPY requirements.txt requirements_dev.txt /code/ RUN pip install -r requirements_dev.txt -RUN pip install psycopg2-binary==2.8.4 +RUN pip install "psycopg[binary]==3.1.8" COPY . /code/ COPY pytition/pytition/settings/config_example.py /config/docker_config.py RUN touch /config/__init__.py diff --git a/Jenkinsfile b/Jenkinsfile index 6f208f06..dd56a4bd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ node { sh ''' cd $WORKSPACE -rm -rf venv && virtualenv -p python3 venv +rm -rf venv && python3 -m venv venv . venv/bin/activate pip3 install -r requirements_dev.txt cat < my.cnf diff --git a/README.md b/README.md index bb3c7524..e5268414 100644 --- a/README.md +++ b/README.md @@ -54,14 +54,14 @@ Those are external projects that are needed and used by Pytition, but included i ## Dependencies -* Python 3 -* Django 2.2.x -* django-tinymce 2.8.0 -* django-colorfield 0.1.15 +* Python 3.8 up to 3.11 +* Django 4.2.x +* django-tinymce 3.5.0 +* django-colorfield 0.8.0 * requests 2.20.x -* mysqlclient 1.3.13 +* mysqlclient 2.0.1 * beautifulsoup4 4.6.3 -* django-formtools 2.1 +* django-formtools 2.2 * bcrypt ## Translations diff --git a/dev/INSTALL.md b/dev/INSTALL.md index 4e542f24..9dceab4e 100644 --- a/dev/INSTALL.md +++ b/dev/INSTALL.md @@ -24,9 +24,8 @@ In a production environment you should modify the following settings: ### Setup your customization -You can customize the TinyMCE variables: +You can customize the TinyMCE editor via this variable: -* TINYMCE_JS_URL * TINYMCE_DEFAULT_CONFIG ### Setup mysql credentials diff --git a/doc/configuration.rst b/doc/configuration.rst index 147e4fc3..5948cc05 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -13,8 +13,6 @@ You **must** set the following variables: .. automodule:: pytition.settings.config_example :members: -.. warning:: The ``TINYMCE_JS_URL`` setting must be present in your config file if you modified the ``STATIC_URL`` setting from its default value (``/static/``), either before of after the ``DO NOT EDIT AFTER THIS BANNER``. It is already present in the config_example.py file. - Not mandatory but important settings ==================================== diff --git a/doc/installation.rst b/doc/installation.rst index e2d78d0a..24bf2723 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -125,8 +125,6 @@ Those are: * DATABASES * ALLOWED_HOSTS -.. warning:: If you do not use the ``config_example.py`` sample file as a base for your config, do NOT forget to also set ``TINYMCE_JS_URL``. Most likely you will just need to set it to ``STATIC_URL + TINYMCE_JS_PATH`` - .. note:: Do not forget to put a correct path to your `my.cnf` MySQL credential file in your config `DATABASES` setting. Initialize Pytition project database. Pay attention to be in your virtualenv to enter the following commands: diff --git a/doc/multi-domain-install.rst b/doc/multi-domain-install.rst index 06046d3b..aa4b8a09 100644 --- a/doc/multi-domain-install.rst +++ b/doc/multi-domain-install.rst @@ -125,8 +125,6 @@ Those are: * DATABASES * ALLOWED_HOSTS -.. warning:: If you do not use the ``config_example.py`` sample file as a base for your config, do NOT forget to also set ``TINYMCE_JS_URL``. Most likely you will just need to set it to ``STATIC_URL + TINYMCE_JS_PATH`` - .. warning:: Pay attention to the following config values: .. code-block:: none diff --git a/pytition/locale/fr_FR/LC_MESSAGES/django.po b/pytition/locale/fr_FR/LC_MESSAGES/django.po index 500f1a27..dcb6574c 100644 --- a/pytition/locale/fr_FR/LC_MESSAGES/django.po +++ b/pytition/locale/fr_FR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: Pytition\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-08-15 21:12+0200\n" -"PO-Revision-Date: 2022-08-15 21:15+0200\n" +"PO-Revision-Date: 2023-10-14 11:18+0200\n" "Last-Translator: Yann Sionneau \n" "Language-Team: French (France) \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Poedit 2.3\n" +"X-Generator: Poedit 3.0.1\n" #: pytition/petition/admin.py:21 pytition/petition/models.py:87 #: pytition/petition/models.py:502 @@ -638,7 +638,7 @@ msgstr "Utilisateur lié à ces permissions" #: pytition/petition/models.py:655 msgid "message" -msgstr "Message" +msgstr "message" #: pytition/petition/templates/layouts/base.html:12 msgid "Homepage" @@ -2073,7 +2073,7 @@ msgstr "" #: pytition/petition/views.py:1724 msgid "Petition successfully transfered!" -msgstr "Permissions transférée avec succès !" +msgstr "Pétition transférée avec succès !" #: pytition/petition/views.py:1727 msgid "Something went wrong while transferring this petition." diff --git a/pytition/petition/admin.py b/pytition/petition/admin.py index b600c34a..d900a1e4 100644 --- a/pytition/petition/admin.py +++ b/pytition/petition/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin from django.forms import ModelForm -from django.utils.translation import ugettext_lazy +from django.utils.translation import gettext_lazy from django.contrib import messages from django.core.exceptions import ValidationError from django import forms @@ -18,7 +18,7 @@ class PytitionUserAdmin(admin.ModelAdmin): def name(self, pu): return pu - name.description = ugettext_lazy("Name") + name.description = gettext_lazy("Name") @admin.register(SlugModel) @@ -36,8 +36,8 @@ def petition_num(self, org): def user_num(self, org): return org.members.count() - petition_num.description = ugettext_lazy('Number of petitions') - user_num.description = ugettext_lazy('Number of members') + petition_num.description = gettext_lazy('Number of petitions') + user_num.description = gettext_lazy('Number of members') def confirm(modeladmin, request, queryset): @@ -46,7 +46,7 @@ def confirm(modeladmin, request, queryset): signature.confirm() signature.save() except ValidationError as e: - messages.error(request, ugettext_lazy("Error: {}").format(e.message)) + messages.error(request, gettext_lazy("Error: {}").format(e.message)) def resend_confirmation_mail(modeladmin, request, queryset): @@ -54,8 +54,8 @@ def resend_confirmation_mail(modeladmin, request, queryset): send_confirmation_email(request, signature) -confirm.short_description = ugettext_lazy("Confirm the signatures") -resend_confirmation_mail.short_description = ugettext_lazy("Send the confirmation email once again") +confirm.short_description = gettext_lazy("Confirm the signatures") +resend_confirmation_mail.short_description = gettext_lazy("Send the confirmation email once again") @admin.register(Signature) @@ -82,14 +82,14 @@ class Meta: #inlines = (SlugInlineAdmin, ) exclude = ('slugs', ) help_texts = { - 'linear_gradient_direction': ugettext_lazy('This is a gradient color. If selected, the background color will be a gradient color. If not, the background color will be a monochrome background color.'), - 'gradient_to': ugettext_lazy('Only used if gradient is selected'), - 'gradient_from': ugettext_lazy('Only used if gradient is selected'), - 'footer_links': ugettext_lazy('Put a bullet point list of links, it will appear horizontally in the page footer'), - 'twitter_description': ugettext_lazy('This is the description of the petition, it will be displayed in Twitter/Facebook cards when the link is posted to social networks. To be tested via https://cards-dev.twitter.com/validator and https://developers.facebook.com/tools/debug/'), - 'twitter_image': ugettext_lazy('Picture displayed in Twitter/Facebook cards when the link is posted to social networks. To be tested via https://cards-dev.twitter.com/validator and https://developers.facebook.com/tools/debug/'), - 'has_newsletter': ugettext_lazy('Allow to chose whether the newsletter subscription checkbox is shown or not'), - 'newsletter_subscribe_http_data': ugettext_lazy("""Only in case subscription to the newsletter via HTTP POST or GET methods. Put here data to be sent, using Python dictionary syntax. e.g.:
+ 'linear_gradient_direction': gettext_lazy('This is a gradient color. If selected, the background color will be a gradient color. If not, the background color will be a monochrome background color.'), + 'gradient_to': gettext_lazy('Only used if gradient is selected'), + 'gradient_from': gettext_lazy('Only used if gradient is selected'), + 'footer_links': gettext_lazy('Put a bullet point list of links, it will appear horizontally in the page footer'), + 'twitter_description': gettext_lazy('This is the description of the petition, it will be displayed in Twitter/Facebook cards when the link is posted to social networks. To be tested via https://cards-dev.twitter.com/validator and https://developers.facebook.com/tools/debug/'), + 'twitter_image': gettext_lazy('Picture displayed in Twitter/Facebook cards when the link is posted to social networks. To be tested via https://cards-dev.twitter.com/validator and https://developers.facebook.com/tools/debug/'), + 'has_newsletter': gettext_lazy('Allow to chose whether the newsletter subscription checkbox is shown or not'), + 'newsletter_subscribe_http_data': gettext_lazy("""Only in case subscription to the newsletter via HTTP POST or GET methods. Put here data to be sent, using Python dictionary syntax. e.g.:
{\'_wpcf7\': 21,
\'_wpcf7_version\': \'4.9\',
\'_wpcf7_locale\': \'fr_FR\',
@@ -97,60 +97,60 @@ class Meta: \'_wpcf7_container_post': \'5398\',
\'your-email\': \'\'
}"""), - 'newsletter_subscribe_http_mailfield': ugettext_lazy('Only when HTTP POST or GET subscription method is used. Name of the field to send via GET or POST, containing the email address to subscribe. Following the example of preceding form field, that would be \'your-email\''), - 'newsletter_subscribe_http_url': ugettext_lazy('Only when HTTP POST or GET subscription method is used. Adresse HTTP à requêter via GET ou POST pour enregistrer quelqu\'un sur la newsletter'), - 'newsletter_subscribe_mail_subject': ugettext_lazy('Only when EMAIL subscription method is used. Inscrire ici la syntaxe de sujet du mail qui permet d\'inscrire quelqu\'un à la newsletter. Indiquez {} à la place où le mail du signataire doit être inséré. Ex: \'ADD NOM_LISTE {} NOM_SIGNATAIRE\''), - 'newsletter_subscribe_mail_from': ugettext_lazy('Only when EMAIL subscription method is used. L\'expéditeur du mail qui permet d\'enregistrer quelqu\'un à la newsletter. Il s\'agit généralement d\'une adresse qui est administratrice de la liste SYMPA ou MAILMAN'), - 'newsletter_subscribe_mail_to': ugettext_lazy('Only when EMAIL subscription method is used. Adresse email d\'administration de la liste, ex : sympa@NOM_LISTE.listes.vox.coop'), - 'newsletter_subscribe_method': ugettext_lazy('This selects the newsletter subscription method. It is either HTTP GET or POST or via sending EMAIL to the newsletter admin address'), - 'published': ugettext_lazy('If checked, the petition is published and accessible on the website by everybody. If not checked, the petition is only accessible by logged in users, others will get a 404 error.'), - 'newsletter_text': ugettext_lazy('E.g.: I want to receive updates or informations from this organization.'), - 'sign_form_footer': ugettext_lazy('E.g.: Your data will stay strictly confidential and will not be sold, given away or exchanged with third parties. Informations about this campaign as well as other news about this organization will be sent to you if you checked the checkbox. You can unsubscribe at any moment.'), - 'org_twitter_handle': ugettext_lazy('The twitter account handle of the organization, starting with the \'@\' symbol. E.g.: @RAP_Asso. This is necessary in order to attribute the \'Twitter Card\' to the correct account. See https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary'), - 'use_custom_email_settings': ugettext_lazy('Check if you want to use your own E-Mail SMTP account.'), - 'confirmation_email_reply': ugettext_lazy('e.g.: petition@mydomain.tld'), - 'newsletter_subscribe_mail_smtp_host': ugettext_lazy('If you don\'t have a real email account, leave \'localhost\'.'), - 'newsletter_subscribe_mail_smtp_port': ugettext_lazy('25 for cleartext connection, 587 for STARTTLS, 465 for TLS. Prefer TLS if the email server supports it.'), - 'newsletter_subscribe_mail_smtp_user': ugettext_lazy('Leave empty if you don\'t use any account autentication.'), - 'newsletter_subscribe_mail_smtp_password': ugettext_lazy('Leave empty if you don\'t use any account autentication.'), - 'newsletter_subscribe_mail_smtp_tls': ugettext_lazy('SMTP connection encrypted via TLS, prefer this rather than STARTTLS if possible. Don\'t check both. The 2 settings are mutually exclusive.'), - 'newsletter_subscribe_mail_smtp_starttls': ugettext_lazy('Connexion SMTP chiffrée via STARTTLS, préférez TLS à ce réglage. Ne pas cocher les 2. Les 2 réglages sont mutuellement exclusifs.'), + 'newsletter_subscribe_http_mailfield': gettext_lazy('Only when HTTP POST or GET subscription method is used. Name of the field to send via GET or POST, containing the email address to subscribe. Following the example of preceding form field, that would be \'your-email\''), + 'newsletter_subscribe_http_url': gettext_lazy('Only when HTTP POST or GET subscription method is used. Adresse HTTP à requêter via GET ou POST pour enregistrer quelqu\'un sur la newsletter'), + 'newsletter_subscribe_mail_subject': gettext_lazy('Only when EMAIL subscription method is used. Inscrire ici la syntaxe de sujet du mail qui permet d\'inscrire quelqu\'un à la newsletter. Indiquez {} à la place où le mail du signataire doit être inséré. Ex: \'ADD NOM_LISTE {} NOM_SIGNATAIRE\''), + 'newsletter_subscribe_mail_from': gettext_lazy('Only when EMAIL subscription method is used. L\'expéditeur du mail qui permet d\'enregistrer quelqu\'un à la newsletter. Il s\'agit généralement d\'une adresse qui est administratrice de la liste SYMPA ou MAILMAN'), + 'newsletter_subscribe_mail_to': gettext_lazy('Only when EMAIL subscription method is used. Adresse email d\'administration de la liste, ex : sympa@NOM_LISTE.listes.vox.coop'), + 'newsletter_subscribe_method': gettext_lazy('This selects the newsletter subscription method. It is either HTTP GET or POST or via sending EMAIL to the newsletter admin address'), + 'published': gettext_lazy('If checked, the petition is published and accessible on the website by everybody. If not checked, the petition is only accessible by logged in users, others will get a 404 error.'), + 'newsletter_text': gettext_lazy('E.g.: I want to receive updates or informations from this organization.'), + 'sign_form_footer': gettext_lazy('E.g.: Your data will stay strictly confidential and will not be sold, given away or exchanged with third parties. Informations about this campaign as well as other news about this organization will be sent to you if you checked the checkbox. You can unsubscribe at any moment.'), + 'org_twitter_handle': gettext_lazy('The twitter account handle of the organization, starting with the \'@\' symbol. E.g.: @RAP_Asso. This is necessary in order to attribute the \'Twitter Card\' to the correct account. See https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary'), + 'use_custom_email_settings': gettext_lazy('Check if you want to use your own E-Mail SMTP account.'), + 'confirmation_email_reply': gettext_lazy('e.g.: petition@mydomain.tld'), + 'newsletter_subscribe_mail_smtp_host': gettext_lazy('If you don\'t have a real email account, leave \'localhost\'.'), + 'newsletter_subscribe_mail_smtp_port': gettext_lazy('25 for cleartext connection, 587 for STARTTLS, 465 for TLS. Prefer TLS if the email server supports it.'), + 'newsletter_subscribe_mail_smtp_user': gettext_lazy('Leave empty if you don\'t use any account autentication.'), + 'newsletter_subscribe_mail_smtp_password': gettext_lazy('Leave empty if you don\'t use any account autentication.'), + 'newsletter_subscribe_mail_smtp_tls': gettext_lazy('SMTP connection encrypted via TLS, prefer this rather than STARTTLS if possible. Don\'t check both. The 2 settings are mutually exclusive.'), + 'newsletter_subscribe_mail_smtp_starttls': gettext_lazy('Connexion SMTP chiffrée via STARTTLS, préférez TLS à ce réglage. Ne pas cocher les 2. Les 2 réglages sont mutuellement exclusifs.'), } labels = { - 'title': ugettext_lazy('Petition title'), - 'text': ugettext_lazy('Petition text'), - 'side_text': ugettext_lazy('Side text, on top of form'), - 'target': ugettext_lazy('Signature target number'), - 'paper_signatures': ugettext_lazy('Number of paper (or other external medium) signatures'), - 'paper_signatures_enabled': ugettext_lazy('Enable paper signatures accounting'), - 'linear_gradient_direction': ugettext_lazy('Direction of linear gradient for background color'), - 'gradient_from': ugettext_lazy('Source color for linear gradient'), - 'gradient_to': ugettext_lazy('Destinatoin color for linear gradient'), - 'bgcolor': ugettext_lazy('Color for monochrome background color'), - 'footer_text': ugettext_lazy('Footer text'), - 'footer_links': ugettext_lazy('Footer links'), - 'twitter_description': ugettext_lazy('Description for Twitter/Facebook cards'), - 'twitter_image': ugettext_lazy('Picture for Twitter/Facebook cards'), - 'has_newsletter': ugettext_lazy('Is the petition associated with a newsletter?'), - 'newsletter_subscribe_http_data': ugettext_lazy('Data structure to be sent in order to subscribe someone to the newsletter in case of HTTP method'), - 'newsletter_subscribe_http_mailfield': ugettext_lazy('Name of the field which should contain the email value in the PHP data structure'), - 'newsletter_subscribe_http_url': ugettext_lazy('HTTP URL for newsletter subscription'), - 'newsletter_subscribe_mail_subject': ugettext_lazy('Email subject for newsletter subscription command'), - 'newsletter_subscribe_mail_from': ugettext_lazy('FROM field for newsletter subscription command'), - 'newsletter_subscribe_mail_to': ugettext_lazy('TO field for newsletter subscription command'), - 'newsletter_subscribe_method': ugettext_lazy('Newsletter subscription method'), - 'published': ugettext_lazy('Puslibhed'), - 'newsletter_text': ugettext_lazy('Form label text of newsletter subscription checkbox'), - 'sign_form_footer': ugettext_lazy('Sign form footer text'), - 'org_twitter_handle': ugettext_lazy('Organization Twitter handle'), - 'use_custom_email_settings': ugettext_lazy('Use custom e-mail settings?'), - 'confirmation_email_reply': ugettext_lazy('Confirmation email Reply-to address'), - 'newsletter_subscribe_mail_smtp_host': ugettext_lazy('SMTP server hostname'), - 'newsletter_subscribe_mail_smtp_port': ugettext_lazy('SMTP port'), - 'newsletter_subscribe_mail_smtp_user': ugettext_lazy('SMTP username'), - 'newsletter_subscribe_mail_smtp_password': ugettext_lazy('SMTP password'), - 'newsletter_subscribe_mail_smtp_tls': ugettext_lazy('SMTP via TLS?'), - 'newsletter_subscribe_mail_smtp_starttls': ugettext_lazy('SMTP via STARTTLS?'), + 'title': gettext_lazy('Petition title'), + 'text': gettext_lazy('Petition text'), + 'side_text': gettext_lazy('Side text, on top of form'), + 'target': gettext_lazy('Signature target number'), + 'paper_signatures': gettext_lazy('Number of paper (or other external medium) signatures'), + 'paper_signatures_enabled': gettext_lazy('Enable paper signatures accounting'), + 'linear_gradient_direction': gettext_lazy('Direction of linear gradient for background color'), + 'gradient_from': gettext_lazy('Source color for linear gradient'), + 'gradient_to': gettext_lazy('Destinatoin color for linear gradient'), + 'bgcolor': gettext_lazy('Color for monochrome background color'), + 'footer_text': gettext_lazy('Footer text'), + 'footer_links': gettext_lazy('Footer links'), + 'twitter_description': gettext_lazy('Description for Twitter/Facebook cards'), + 'twitter_image': gettext_lazy('Picture for Twitter/Facebook cards'), + 'has_newsletter': gettext_lazy('Is the petition associated with a newsletter?'), + 'newsletter_subscribe_http_data': gettext_lazy('Data structure to be sent in order to subscribe someone to the newsletter in case of HTTP method'), + 'newsletter_subscribe_http_mailfield': gettext_lazy('Name of the field which should contain the email value in the PHP data structure'), + 'newsletter_subscribe_http_url': gettext_lazy('HTTP URL for newsletter subscription'), + 'newsletter_subscribe_mail_subject': gettext_lazy('Email subject for newsletter subscription command'), + 'newsletter_subscribe_mail_from': gettext_lazy('FROM field for newsletter subscription command'), + 'newsletter_subscribe_mail_to': gettext_lazy('TO field for newsletter subscription command'), + 'newsletter_subscribe_method': gettext_lazy('Newsletter subscription method'), + 'published': gettext_lazy('Puslibhed'), + 'newsletter_text': gettext_lazy('Form label text of newsletter subscription checkbox'), + 'sign_form_footer': gettext_lazy('Sign form footer text'), + 'org_twitter_handle': gettext_lazy('Organization Twitter handle'), + 'use_custom_email_settings': gettext_lazy('Use custom e-mail settings?'), + 'confirmation_email_reply': gettext_lazy('Confirmation email Reply-to address'), + 'newsletter_subscribe_mail_smtp_host': gettext_lazy('SMTP server hostname'), + 'newsletter_subscribe_mail_smtp_port': gettext_lazy('SMTP port'), + 'newsletter_subscribe_mail_smtp_user': gettext_lazy('SMTP username'), + 'newsletter_subscribe_mail_smtp_password': gettext_lazy('SMTP password'), + 'newsletter_subscribe_mail_smtp_tls': gettext_lazy('SMTP via TLS?'), + 'newsletter_subscribe_mail_smtp_starttls': gettext_lazy('SMTP via STARTTLS?'), } @@ -161,23 +161,23 @@ class PetitionAdmin(admin.ModelAdmin): search_fields = ('title', ) list_display = ('title', 'non_confirmed_signature_number', 'confirmed_signature_number') fieldsets = ( - (ugettext_lazy('To whom is this petition?'), + (gettext_lazy('To whom is this petition?'), { 'fields': ('org', 'user') } ), - (ugettext_lazy('Content of the petition'), + (gettext_lazy('Content of the petition'), { 'fields': ('title', 'text', 'side_text', 'footer_text', 'footer_links', 'sign_form_footer', 'target', 'paper_signatures_enabled', 'paper_signatures') } ), - (ugettext_lazy('Background color'), + (gettext_lazy('Background color'), { 'fields': ('linear_gradient_direction', 'gradient_from', 'gradient_to', 'bgcolor') } ), - (ugettext_lazy('Setup of the newsletter associated to the petition'), + (gettext_lazy('Setup of the newsletter associated to the petition'), { 'fields': ('has_newsletter', 'newsletter_text', 'newsletter_subscribe_method', 'newsletter_subscribe_http_data', 'newsletter_subscribe_http_mailfield', @@ -188,16 +188,16 @@ class PetitionAdmin(admin.ModelAdmin): 'newsletter_subscribe_mail_smtp_tls', 'newsletter_subscribe_mail_smtp_starttls') } ), - (ugettext_lazy('Confirmation email setup'), + (gettext_lazy('Confirmation email setup'), { 'fields': ('confirmation_email_reply', ) } ), - (ugettext_lazy('Petition meta-data for social networks'), + (gettext_lazy('Petition meta-data for social networks'), { 'fields': ('twitter_description', 'twitter_image', 'org_twitter_handle') }), - (ugettext_lazy('Publish the petition'), + (gettext_lazy('Publish the petition'), { 'fields': ('published', ) }) @@ -205,11 +205,11 @@ class PetitionAdmin(admin.ModelAdmin): def non_confirmed_signature_number(self, petition): return petition.get_signature_number(confirmed=False) - non_confirmed_signature_number.short_description = ugettext_lazy('Unconfirmed signatures') + non_confirmed_signature_number.short_description = gettext_lazy('Unconfirmed signatures') def confirmed_signature_number(self, petition): return petition.get_signature_number(confirmed=True) - confirmed_signature_number.short_description = ugettext_lazy('Confirmed signatures') + confirmed_signature_number.short_description = gettext_lazy('Confirmed signatures') class PetitionTemplateForm(ModelForm): @@ -222,14 +222,14 @@ class Meta: model = PetitionTemplate fields = ['linear_gradient_direction', 'side_text'] help_texts = { - 'linear_gradient_direction': ugettext_lazy('This is a gradient color. If selected, the background color will be a gradient color. If not, the background color will be a monochrome background color.'), - 'gradient_to': ugettext_lazy('Only used if gradient is selected'), - 'gradient_from': ugettext_lazy('Only used if gradient is selected'), - 'footer_links': ugettext_lazy('Put a bullet point list of links, it will appear horizontally in the page footer'), - 'twitter_description': ugettext_lazy('This is the description of the petition, it will be displayed in Twitter/Facebook cards when the link is posted to social networks. To be tested via https://cards-dev.twitter.com/validator and https://developers.facebook.com/tools/debug/'), - 'twitter_image': ugettext_lazy('Picture displayed in Twitter/Facebook cards when the link is posted to social networks. To be tested via https://cards-dev.twitter.com/validator and https://developers.facebook.com/tools/debug/'), - 'has_newsletter': ugettext_lazy('Allow to chose whether the newsletter subscription checkbox is shown or not'), - 'newsletter_subscribe_http_data': ugettext_lazy("""Only in case subscription to the newsletter via HTTP POST or GET methods. Put here data to be sent, using Python dictionary syntax. e.g.:
+ 'linear_gradient_direction': gettext_lazy('This is a gradient color. If selected, the background color will be a gradient color. If not, the background color will be a monochrome background color.'), + 'gradient_to': gettext_lazy('Only used if gradient is selected'), + 'gradient_from': gettext_lazy('Only used if gradient is selected'), + 'footer_links': gettext_lazy('Put a bullet point list of links, it will appear horizontally in the page footer'), + 'twitter_description': gettext_lazy('This is the description of the petition, it will be displayed in Twitter/Facebook cards when the link is posted to social networks. To be tested via https://cards-dev.twitter.com/validator and https://developers.facebook.com/tools/debug/'), + 'twitter_image': gettext_lazy('Picture displayed in Twitter/Facebook cards when the link is posted to social networks. To be tested via https://cards-dev.twitter.com/validator and https://developers.facebook.com/tools/debug/'), + 'has_newsletter': gettext_lazy('Allow to chose whether the newsletter subscription checkbox is shown or not'), + 'newsletter_subscribe_http_data': gettext_lazy("""Only in case subscription to the newsletter via HTTP POST or GET methods. Put here data to be sent, using Python dictionary syntax. e.g.:
{\'_wpcf7\': 21,
\'_wpcf7_version\': \'4.9\',
\'_wpcf7_locale\': \'fr_FR\',
@@ -237,58 +237,58 @@ class Meta: \'_wpcf7_container_post': \'5398\',
\'your-email\': \'\'
}"""), - 'newsletter_subscribe_http_mailfield': ugettext_lazy('Only when HTTP POST or GET subscription method is used. Name of the field to send via GET or POST, containing the email address to subscribe. Following the example of preceding form field, that would be \'your-email\''), - 'newsletter_subscribe_http_url': ugettext_lazy('Only when HTTP POST or GET subscription method is used. Adresse HTTP à requêter via GET ou POST pour enregistrer quelqu\'un sur la newsletter'), - 'newsletter_subscribe_mail_subject': ugettext_lazy('Only when EMAIL subscription method is used. Inscrire ici la syntaxe de sujet du mail qui permet d\'inscrire quelqu\'un à la newsletter. Indiquez {} à la place où le mail du signataire doit être inséré. Ex: \'ADD NOM_LISTE {} NOM_SIGNATAIRE\''), - 'newsletter_subscribe_mail_from': ugettext_lazy('Only when EMAIL subscription method is used. L\'expéditeur du mail qui permet d\'enregistrer quelqu\'un à la newsletter. Il s\'agit généralement d\'une adresse qui est administratrice de la liste SYMPA ou MAILMAN'), - 'newsletter_subscribe_mail_to': ugettext_lazy('Only when EMAIL subscription method is used. Adresse email d\'administration de la liste, ex : sympa@NOM_LISTE.listes.vox.coop'), - 'newsletter_subscribe_method': ugettext_lazy('This selects the newsletter subscription method. It is either HTTP GET or POST or via sending EMAIL to the newsletter admin address'), - 'published': ugettext_lazy('If checked, the petition is published and accessible on the website by everybody. If not checked, the petition is only accessible by logged in users, others will get a 404 error.'), - 'newsletter_text': ugettext_lazy('E.g.: I want to receive updates or informations from this organization.'), - 'sign_form_footer': ugettext_lazy('E.g.: Your data will stay strictly confidential and will not be sold, given away or exchanged with third parties. Informations about this campaign as well as other news about this organization will be sent to you if you checked the checkbox. You can unsubscribe at any moment.'), - 'org_twitter_handle': ugettext_lazy('The twitter account handle of the organization, starting with the \'@\' symbol. E.g.: @RAP_Asso. This is necessary in order to attribute the \'Twitter Card\' to the correct account. See https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary'), - 'use_custom_email_settings': ugettext_lazy('Check if you want to use your own E-Mail SMTP account.'), - 'confirmation_email_reply': ugettext_lazy('e.g.: petition@mydomain.tld'), - 'newsletter_subscribe_mail_smtp_host': ugettext_lazy('If you don\'t have a real email account, leave \'localhost\'.'), - 'newsletter_subscribe_mail_smtp_port': ugettext_lazy('25 for cleartext connection, 587 for STARTTLS, 465 for TLS. Prefer TLS if the email server supports it.'), - 'newsletter_subscribe_mail_smtp_user': ugettext_lazy('Leave empty if you don\'t use any account autentication.'), - 'newsletter_subscribe_mail_smtp_password': ugettext_lazy('Leave empty if you don\'t use any account autentication.'), - 'newsletter_subscribe_mail_smtp_tls': ugettext_lazy('SMTP connection encrypted via TLS, prefer this rather than STARTTLS if possible. Don\'t check both. The 2 settings are mutually exclusive.'), - 'newsletter_subscribe_mail_smtp_starttls': ugettext_lazy('Connexion SMTP chiffrée via STARTTLS, préférez TLS à ce réglage. Ne pas cocher les 2. Les 2 réglages sont mutuellement exclusifs.'), + 'newsletter_subscribe_http_mailfield': gettext_lazy('Only when HTTP POST or GET subscription method is used. Name of the field to send via GET or POST, containing the email address to subscribe. Following the example of preceding form field, that would be \'your-email\''), + 'newsletter_subscribe_http_url': gettext_lazy('Only when HTTP POST or GET subscription method is used. Adresse HTTP à requêter via GET ou POST pour enregistrer quelqu\'un sur la newsletter'), + 'newsletter_subscribe_mail_subject': gettext_lazy('Only when EMAIL subscription method is used. Inscrire ici la syntaxe de sujet du mail qui permet d\'inscrire quelqu\'un à la newsletter. Indiquez {} à la place où le mail du signataire doit être inséré. Ex: \'ADD NOM_LISTE {} NOM_SIGNATAIRE\''), + 'newsletter_subscribe_mail_from': gettext_lazy('Only when EMAIL subscription method is used. L\'expéditeur du mail qui permet d\'enregistrer quelqu\'un à la newsletter. Il s\'agit généralement d\'une adresse qui est administratrice de la liste SYMPA ou MAILMAN'), + 'newsletter_subscribe_mail_to': gettext_lazy('Only when EMAIL subscription method is used. Adresse email d\'administration de la liste, ex : sympa@NOM_LISTE.listes.vox.coop'), + 'newsletter_subscribe_method': gettext_lazy('This selects the newsletter subscription method. It is either HTTP GET or POST or via sending EMAIL to the newsletter admin address'), + 'published': gettext_lazy('If checked, the petition is published and accessible on the website by everybody. If not checked, the petition is only accessible by logged in users, others will get a 404 error.'), + 'newsletter_text': gettext_lazy('E.g.: I want to receive updates or informations from this organization.'), + 'sign_form_footer': gettext_lazy('E.g.: Your data will stay strictly confidential and will not be sold, given away or exchanged with third parties. Informations about this campaign as well as other news about this organization will be sent to you if you checked the checkbox. You can unsubscribe at any moment.'), + 'org_twitter_handle': gettext_lazy('The twitter account handle of the organization, starting with the \'@\' symbol. E.g.: @RAP_Asso. This is necessary in order to attribute the \'Twitter Card\' to the correct account. See https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary'), + 'use_custom_email_settings': gettext_lazy('Check if you want to use your own E-Mail SMTP account.'), + 'confirmation_email_reply': gettext_lazy('e.g.: petition@mydomain.tld'), + 'newsletter_subscribe_mail_smtp_host': gettext_lazy('If you don\'t have a real email account, leave \'localhost\'.'), + 'newsletter_subscribe_mail_smtp_port': gettext_lazy('25 for cleartext connection, 587 for STARTTLS, 465 for TLS. Prefer TLS if the email server supports it.'), + 'newsletter_subscribe_mail_smtp_user': gettext_lazy('Leave empty if you don\'t use any account autentication.'), + 'newsletter_subscribe_mail_smtp_password': gettext_lazy('Leave empty if you don\'t use any account autentication.'), + 'newsletter_subscribe_mail_smtp_tls': gettext_lazy('SMTP connection encrypted via TLS, prefer this rather than STARTTLS if possible. Don\'t check both. The 2 settings are mutually exclusive.'), + 'newsletter_subscribe_mail_smtp_starttls': gettext_lazy('Connexion SMTP chiffrée via STARTTLS, préférez TLS à ce réglage. Ne pas cocher les 2. Les 2 réglages sont mutuellement exclusifs.'), } labels = { - 'name': ugettext_lazy('Petition template name'), - 'text': ugettext_lazy('Petition text'), - 'side_text': ugettext_lazy('Side text, on top of form'), - 'target': ugettext_lazy('Signature target number'), - 'linear_gradient_direction': ugettext_lazy('Direction of linear gradient for background color'), - 'gradient_from': ugettext_lazy('Source color for linear gradient'), - 'gradient_to': ugettext_lazy('Destinatoin color for linear gradient'), - 'bgcolor': ugettext_lazy('Color for monochrome background color'), - 'footer_text': ugettext_lazy('Footer text'), - 'footer_links': ugettext_lazy('Footer links'), - 'twitter_description': ugettext_lazy('Description for Twitter/Facebook cards'), - 'twitter_image': ugettext_lazy('Picture for Twitter/Facebook cards'), - 'has_newsletter': ugettext_lazy('Is the petition associated with a newsletter?'), - 'newsletter_subscribe_http_data': ugettext_lazy('Data structure to be sent in order to subscribe someone to the newsletter in case of HTTP method'), - 'newsletter_subscribe_http_mailfield': ugettext_lazy('Name of the field which should contain the email value in the PHP data structure'), - 'newsletter_subscribe_http_url': ugettext_lazy('HTTP URL for newsletter subscription'), - 'newsletter_subscribe_mail_subject': ugettext_lazy('Email subject for newsletter subscription command'), - 'newsletter_subscribe_mail_from': ugettext_lazy('FROM field for newsletter subscription command'), - 'newsletter_subscribe_mail_to': ugettext_lazy('TO field for newsletter subscription command'), - 'newsletter_subscribe_method': ugettext_lazy('Newsletter subscription method'), - 'published': ugettext_lazy('Puslibhed'), - 'newsletter_text': ugettext_lazy('Form label text of newsletter subscription checkbox'), - 'sign_form_footer': ugettext_lazy('Sign form footer text'), - 'org_twitter_handle': ugettext_lazy('Organization Twitter handle'), - 'use_custom_email_settings': ugettext_lazy('Use custom e-mail settings?'), - 'confirmation_email_reply': ugettext_lazy('Confirmation email Reply-to address'), - 'newsletter_subscribe_mail_smtp_host': ugettext_lazy('SMTP server hostname'), - 'newsletter_subscribe_mail_smtp_port': ugettext_lazy('SMTP port'), - 'newsletter_subscribe_mail_smtp_user': ugettext_lazy('SMTP username'), - 'newsletter_subscribe_mail_smtp_password': ugettext_lazy('SMTP password'), - 'newsletter_subscribe_mail_smtp_tls': ugettext_lazy('SMTP via TLS?'), - 'newsletter_subscribe_mail_smtp_starttls': ugettext_lazy('SMTP via STARTTLS?'), + 'name': gettext_lazy('Petition template name'), + 'text': gettext_lazy('Petition text'), + 'side_text': gettext_lazy('Side text, on top of form'), + 'target': gettext_lazy('Signature target number'), + 'linear_gradient_direction': gettext_lazy('Direction of linear gradient for background color'), + 'gradient_from': gettext_lazy('Source color for linear gradient'), + 'gradient_to': gettext_lazy('Destinatoin color for linear gradient'), + 'bgcolor': gettext_lazy('Color for monochrome background color'), + 'footer_text': gettext_lazy('Footer text'), + 'footer_links': gettext_lazy('Footer links'), + 'twitter_description': gettext_lazy('Description for Twitter/Facebook cards'), + 'twitter_image': gettext_lazy('Picture for Twitter/Facebook cards'), + 'has_newsletter': gettext_lazy('Is the petition associated with a newsletter?'), + 'newsletter_subscribe_http_data': gettext_lazy('Data structure to be sent in order to subscribe someone to the newsletter in case of HTTP method'), + 'newsletter_subscribe_http_mailfield': gettext_lazy('Name of the field which should contain the email value in the PHP data structure'), + 'newsletter_subscribe_http_url': gettext_lazy('HTTP URL for newsletter subscription'), + 'newsletter_subscribe_mail_subject': gettext_lazy('Email subject for newsletter subscription command'), + 'newsletter_subscribe_mail_from': gettext_lazy('FROM field for newsletter subscription command'), + 'newsletter_subscribe_mail_to': gettext_lazy('TO field for newsletter subscription command'), + 'newsletter_subscribe_method': gettext_lazy('Newsletter subscription method'), + 'published': gettext_lazy('Puslibhed'), + 'newsletter_text': gettext_lazy('Form label text of newsletter subscription checkbox'), + 'sign_form_footer': gettext_lazy('Sign form footer text'), + 'org_twitter_handle': gettext_lazy('Organization Twitter handle'), + 'use_custom_email_settings': gettext_lazy('Use custom e-mail settings?'), + 'confirmation_email_reply': gettext_lazy('Confirmation email Reply-to address'), + 'newsletter_subscribe_mail_smtp_host': gettext_lazy('SMTP server hostname'), + 'newsletter_subscribe_mail_smtp_port': gettext_lazy('SMTP port'), + 'newsletter_subscribe_mail_smtp_user': gettext_lazy('SMTP username'), + 'newsletter_subscribe_mail_smtp_password': gettext_lazy('SMTP password'), + 'newsletter_subscribe_mail_smtp_tls': gettext_lazy('SMTP via TLS?'), + 'newsletter_subscribe_mail_smtp_starttls': gettext_lazy('SMTP via STARTTLS?'), } @@ -297,22 +297,22 @@ class PetitionTemplateAdmin(admin.ModelAdmin): #change_form_template = 'petition/petition_change_form.html' form = PetitionTemplateForm fieldsets = ( - (ugettext_lazy('To whom is this petition template?'), + (gettext_lazy('To whom is this petition template?'), { 'fields': ('org', 'user') } ), - (ugettext_lazy('Content of the petition'), + (gettext_lazy('Content of the petition'), { 'fields': ('name', 'text', 'side_text', 'footer_text', 'footer_links', 'sign_form_footer', 'target') } ), - (ugettext_lazy('Background color'), + (gettext_lazy('Background color'), { 'fields': ('linear_gradient_direction', 'gradient_from', 'gradient_to', 'bgcolor') } ), - (ugettext_lazy('Setup of the newsletter associated to the petition'), + (gettext_lazy('Setup of the newsletter associated to the petition'), { 'fields': ('has_newsletter', 'newsletter_text', 'newsletter_subscribe_method', 'newsletter_subscribe_http_data', 'newsletter_subscribe_http_mailfield', @@ -323,12 +323,12 @@ class PetitionTemplateAdmin(admin.ModelAdmin): 'newsletter_subscribe_mail_smtp_tls', 'newsletter_subscribe_mail_smtp_starttls') } ), - (ugettext_lazy('Confirmation email setup'), + (gettext_lazy('Confirmation email setup'), { 'fields': ('confirmation_email_reply', ) } ), - (ugettext_lazy('Petition meta-data for social networks'), + (gettext_lazy('Petition meta-data for social networks'), { 'fields': ('twitter_description', 'twitter_image', 'org_twitter_handle') }), diff --git a/pytition/petition/forms.py b/pytition/petition/forms.py index 56691fdf..17dd77a2 100644 --- a/pytition/petition/forms.py +++ b/pytition/petition/forms.py @@ -1,6 +1,6 @@ from django.forms import ModelForm, ValidationError from django import forms -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.contrib.auth.forms import UserCreationForm, UsernameField from django.contrib.auth import get_user_model from django.utils.text import slugify @@ -10,7 +10,6 @@ from .widgets import SwitchField from .helpers import send_welcome_mail -import uuid import html from tinymce.widgets import TinyMCE from colorfield.fields import ColorWidget @@ -47,16 +46,6 @@ def __init__(self, petition=None, *args, **kwargs): else: self.fields['subscribed_to_mailinglist'].label = self.instance.petition.newsletter_text - def save(self, commit=True): - object = super().save(commit=False) - hashstring = str(uuid.uuid4()) - object.confirmation_hash = hashstring - object.confirmed = False - if commit: - object.save() - return object - - class PetitionCreationStep1(forms.Form): ### Ask for title ### title = forms.CharField(max_length=200) @@ -105,7 +94,7 @@ class PetitionCreationStep3(forms.Form): class ContentFormGeneric(forms.Form): ### Content of a Petition ### - text = forms.CharField(widget=TinyMCE) + text = forms.CharField(widget=TinyMCE, required=False) target = forms.IntegerField(required=False) side_text = forms.CharField(widget=TinyMCE, required=False) footer_text = forms.CharField(widget=TinyMCE, required=False) @@ -184,10 +173,10 @@ def clean(self): class StyleForm(forms.Form): ### Graphical UI style info of Petition ### - bgcolor = forms.CharField(widget=ColorWidget) - linear_gradient_direction = forms.ChoiceField(choices=Petition.LINEAR_GRADIENT_CHOICES) - gradient_from = forms.CharField(widget=ColorWidget) - gradient_to = forms.CharField(widget=ColorWidget) + bgcolor = forms.CharField(widget=ColorWidget, required=False) + linear_gradient_direction = forms.ChoiceField(choices=Petition.LINEAR_GRADIENT_CHOICES, required=False) + gradient_from = forms.CharField(widget=ColorWidget, required=False) + gradient_to = forms.CharField(widget=ColorWidget, required=False) class PytitionUserCreationForm(UserCreationForm): diff --git a/pytition/petition/helpers.py b/pytition/petition/helpers.py index b1003906..29592230 100644 --- a/pytition/petition/helpers.py +++ b/pytition/petition/helpers.py @@ -7,7 +7,7 @@ from django.template.loader import render_to_string from django.utils.html import strip_tags from django.core.mail import get_connection, EmailMultiAlternatives, EmailMessage -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.contrib.auth.models import User # Remove all moderated instances of Petition @@ -93,7 +93,7 @@ def footer_content_processor(request): # Send Confirmation email def send_confirmation_email(request, signature): petition = signature.petition - url = request.build_absolute_uri("/petition/{}/confirm/{}".format(petition.id, signature.confirmation_hash)) + url = request.build_absolute_uri(reverse("confirm", args=[petition.id, signature.confirmation_hash])) html_message = render_to_string("petition/confirmation_email.html", {'firstname': signature.first_name, 'url': url}) message = strip_tags(html_message) with get_connection() as connection: diff --git a/pytition/petition/models.py b/pytition/petition/models.py index 3a63b4fb..3ca9f9d8 100644 --- a/pytition/petition/models.py +++ b/pytition/petition/models.py @@ -1,8 +1,8 @@ from django.db import models from django.utils.html import mark_safe, strip_tags from django.utils.text import slugify -from django.utils.translation import ugettext as _ -from django.utils.translation import ugettext_lazy +from django.utils.translation import gettext as _ +from django.utils.translation import gettext_lazy from django.core.exceptions import ValidationError from django.db.models.signals import post_save, post_delete, pre_save from django.dispatch import receiver @@ -19,13 +19,14 @@ from .helpers import sanitize_html import html +import uuid # ----------------------------------- PytitionUser ---------------------------- class PytitionUser(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="pytitionuser") invitations = models.ManyToManyField('Organization', related_name="invited", blank=True) - default_template = models.ForeignKey('PetitionTemplate', blank=True, null=True, related_name='+', verbose_name=ugettext_lazy("Default petition template"), to_field='id', on_delete=models.SET_NULL) + default_template = models.ForeignKey('PetitionTemplate', blank=True, null=True, related_name='+', verbose_name=gettext_lazy("Default petition template"), to_field='id', on_delete=models.SET_NULL) moderated = models.BooleanField(default=False) def drop(self): @@ -85,8 +86,8 @@ def __repr__(self): # --------------------------------- Organization ------------------------------ class Organization(models.Model): - name = models.CharField(max_length=200, verbose_name=ugettext_lazy("Name"), unique=True, null=False, blank=False) - default_template = models.ForeignKey('PetitionTemplate', blank=True, null=True, related_name='+', verbose_name=ugettext_lazy("Default petition template"), to_field='id', on_delete=models.SET_NULL) + name = models.CharField(max_length=200, verbose_name=gettext_lazy("Name"), unique=True, null=False, blank=False) + default_template = models.ForeignKey('PetitionTemplate', blank=True, null=True, related_name='+', verbose_name=gettext_lazy("Default petition template"), to_field='id', on_delete=models.SET_NULL) slugname = models.SlugField(max_length=200, unique=True) members = models.ManyToManyField(PytitionUser, through='Permission') @@ -173,7 +174,7 @@ class Petition(models.Model): ) # Description - title = models.TextField(verbose_name=ugettext_lazy("Title")) + title = models.TextField(verbose_name=gettext_lazy("Title")) text = tinymce_models.HTMLField(blank=True) side_text = tinymce_models.HTMLField(blank=True) target = models.IntegerField(default=500) @@ -438,15 +439,15 @@ def moderate(self, do_moderate=True): # --------------------------------- Signature --------------------------------- class Signature(models.Model): - first_name = models.CharField(max_length=50, verbose_name=ugettext_lazy("First name")) - last_name = models.CharField(max_length=50, verbose_name=ugettext_lazy("Last name")) - phone = PhoneNumberField(max_length=20, blank=True, verbose_name=ugettext_lazy("Phone number")) - email = models.EmailField(verbose_name=ugettext_lazy("Email address")) + first_name = models.CharField(max_length=50, verbose_name=gettext_lazy("First name")) + last_name = models.CharField(max_length=50, verbose_name=gettext_lazy("Last name")) + phone = PhoneNumberField(max_length=20, blank=True, verbose_name=gettext_lazy("Phone number")) + email = models.EmailField(verbose_name=gettext_lazy("Email address")) confirmation_hash = models.CharField(max_length=128) - confirmed = models.BooleanField(default=False, verbose_name=ugettext_lazy("Confirmed")) - petition = models.ForeignKey(Petition, on_delete=models.CASCADE, verbose_name=ugettext_lazy("Petition")) - subscribed_to_mailinglist = models.BooleanField(default=False, verbose_name=ugettext_lazy("Subscribed to mailing list")) - date = models.DateTimeField(blank=True, auto_now_add=True, verbose_name=ugettext_lazy("Date")) + confirmed = models.BooleanField(default=False, verbose_name=gettext_lazy("Confirmed")) + petition = models.ForeignKey(Petition, on_delete=models.CASCADE, verbose_name=gettext_lazy("Petition")) + subscribed_to_mailinglist = models.BooleanField(default=False, verbose_name=gettext_lazy("Subscribed to mailing list")) + date = models.DateTimeField(blank=True, auto_now_add=True, verbose_name=gettext_lazy("Date")) ipaddress = models.TextField(blank=True, null=True) def clean(self): @@ -456,6 +457,8 @@ def clean(self): def save(self, *args, **kwargs): self.clean() + if not self.confirmation_hash: + self.confirmation_hash = str(uuid.uuid4()) if self.confirmed: # invalidating other signatures from same email Signature.objects.filter(petition=self.petition).filter(email=self.email)\ @@ -501,7 +504,7 @@ class PetitionTemplate(models.Model): ) # Description - name = models.CharField(max_length=50, verbose_name=ugettext_lazy("Name")) + name = models.CharField(max_length=50, verbose_name=gettext_lazy("Name")) text = tinymce_models.HTMLField(blank=True) side_text = tinymce_models.HTMLField(blank=True) target = models.IntegerField(blank=True, null=True) @@ -580,8 +583,8 @@ def __repr__(self): # ------------------------------------ Permission ----------------------------- class Permission(models.Model): - organization = models.ForeignKey(Organization, on_delete=models.CASCADE, verbose_name=ugettext_lazy("Organization related to these permissions")) - user = models.ForeignKey(PytitionUser, on_delete=models.CASCADE, verbose_name=ugettext_lazy("User related to these permissions")) + organization = models.ForeignKey(Organization, on_delete=models.CASCADE, verbose_name=gettext_lazy("Organization related to these permissions")) + user = models.ForeignKey(PytitionUser, on_delete=models.CASCADE, verbose_name=gettext_lazy("User related to these permissions")) can_add_members = models.BooleanField(default=False) can_remove_members = models.BooleanField(default=False) can_create_petitions = models.BooleanField(default=True) @@ -655,7 +658,7 @@ def post_delete_user(sender, instance, *args, **kwargs): # ------------------------------------ ModerationReason ----------------------------- class ModerationReason(models.Model): - msg = models.TextField(verbose_name=ugettext_lazy("message")) + msg = models.TextField(verbose_name=gettext_lazy("message")) visible = models.BooleanField(default=True) class Moderation(models.Model): diff --git a/pytition/petition/templates/petition/bs4_form.html b/pytition/petition/templates/petition/bs4_form.html index 6c377cf0..1732ad05 100644 --- a/pytition/petition/templates/petition/bs4_form.html +++ b/pytition/petition/templates/petition/bs4_form.html @@ -23,7 +23,7 @@ {% render_field field|bootstrap class="is-invalid" %} {% for error in field.errors %} -
+
{{ error }}
{% endfor %} diff --git a/pytition/petition/templates/petition/edit_petition.html b/pytition/petition/templates/petition/edit_petition.html index 9991cc1f..a2311b55 100644 --- a/pytition/petition/templates/petition/edit_petition.html +++ b/pytition/petition/templates/petition/edit_petition.html @@ -51,8 +51,8 @@
{% endif %}