Skip to content

Commit

Permalink
Merge pull request #308 from pytition/test_django_4.2
Browse files Browse the repository at this point in the history
Update to Django 4.2
  • Loading branch information
fallen authored Nov 4, 2023
2 parents 6fb8d0c + cab2284 commit 95df6a0
Show file tree
Hide file tree
Showing 21 changed files with 203 additions and 223 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<ENDOFFILE > my.cnf
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions dev/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
====================================

Expand Down
2 changes: 0 additions & 2 deletions doc/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 0 additions & 2 deletions doc/multi-domain-install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions pytition/locale/fr_FR/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -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 <yann@sionneau.net>\n"
"Language-Team: French (France) <https://weblate.framasoft.org/projects/"
"pytition/pytitions/fr_FR/>\n"
Expand All @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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."
Expand Down
280 changes: 140 additions & 140 deletions pytition/petition/admin.py

Large diffs are not rendered by default.

23 changes: 6 additions & 17 deletions pytition/petition/forms.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand Down
4 changes: 2 additions & 2 deletions pytition/petition/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
39 changes: 21 additions & 18 deletions pytition/petition/models.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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')

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand All @@ -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)\
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion pytition/petition/templates/petition/bs4_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
{% render_field field|bootstrap class="is-invalid" %}
</div>
{% for error in field.errors %}
<div class="invalid-feedback">
<div class="invalid-feedback d-block">
{{ error }}
</div>
{% endfor %}
Expand Down
4 changes: 2 additions & 2 deletions pytition/petition/templates/petition/edit_petition.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
</div>
{% endif %}
<div class="list-group list-group-horizontal mb-5" id="list-tab" role="tablist">
<a href="#content_form" class="list-group-item list-group-item-info list-group-item-action"
data-toggle="list" aria-controls="content_form" role="tab"><span class="oi oi-clipboard"></span> {% trans "Content" %}</a>
<a href="#content_form" class="list-group-item list-group-item-info list-group-item-action active"
data-toggle="list" aria-controls="content_form" role="tab"><span class="oi oi-clipboard" aria-current="true"></span> {% trans "Content" %}</a>
<a href="#style_form" class="list-group-item list-group-item-info list-group-item-action"
data-toggle="list" aria-controls="style_form" role="tab"><span class="oi oi-brush"></span> {% trans "Style & Look" %}</a>
<a href="#social_network_form" class="list-group-item list-group-item-info list-group-item-action"
Expand Down
6 changes: 3 additions & 3 deletions pytition/petition/tests/tests_EditPetitionView.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,9 @@ def test_edit_template_POST_style_form(self):
self.assertTemplateUsed(response, "petition/edit_petition.html")
p2.refresh_from_db()

style_form_data['bgcolor'] = '#' + style_form_data['bgcolor']
style_form_data['gradient_from'] = '#' + style_form_data['gradient_from']
style_form_data['gradient_to'] = '#' + style_form_data['gradient_to']
style_form_data['bgcolor'] = style_form_data['bgcolor']
style_form_data['gradient_from'] = style_form_data['gradient_from']
style_form_data['gradient_to'] = style_form_data['gradient_to']
for key, value in style_form_data.items():
if key == "style_form_submitted":
continue
Expand Down
2 changes: 1 addition & 1 deletion pytition/petition/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.conf.urls import include
from django.urls import include
from django.urls import path

from . import views
Expand Down
5 changes: 3 additions & 2 deletions pytition/petition/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.http import Http404, HttpResponse, HttpResponseForbidden, JsonResponse
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.contrib import messages
from django.contrib.messages import get_messages
from django.utils.html import format_html
Expand Down Expand Up @@ -1226,6 +1226,7 @@ def edit_petition(request, petition_id):
'email_form_submitted': False,
'social_network_form_submitted': False,
'newsletter_form_submitted': False,
'style_form_submitted': False,
}

if request.method == "POST":
Expand Down Expand Up @@ -1805,4 +1806,4 @@ def report_petition(request, petition_id, reason_id=None):
Moderation.objects.create(petition=petition, reason=reason)
else:
Moderation.objects.create(petition=petition)
return HttpResponse(status=200)
return HttpResponse(status=200)
4 changes: 1 addition & 3 deletions pytition/pytition/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
]

WSGI_APPLICATION = 'pytition.wsgi.application'
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

if os.environ.get('USE_POSTGRESQL'):
from .pgsql import DATABASES
Expand Down Expand Up @@ -154,11 +155,8 @@
STATIC_ROOT = os.environ.get('STATIC_ROOT')
LOGIN_URL = '/petition/login/'

TINYMCE_JS_PATH = '/vendor/tinymce/js/tinymce/tinymce.min.js'
TINYMCE_JS_URL = STATIC_URL + TINYMCE_JS_PATH
TINYMCE_DEFAULT_CONFIG = {
'plugins': 'print preview fullpage searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists textcolor wordcount imagetools contextmenu colorpicker textpattern help',
'theme': "modern",
'cleanup_on_startup': True,
'custom_undo_redo_levels': 10,
'toolbar1': 'formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat | fontselect | fontsizeselect',
Expand Down
4 changes: 0 additions & 4 deletions pytition/pytition/settings/config_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,6 @@

import os

# This needs to be redefined because STATIC_URL might be set in this config
# after TINYMCE_JS_URL was defined
TINYMCE_JS_URL = STATIC_URL + TINYMCE_JS_PATH

if DEFAULT_INDEX_THUMBNAIL == "":
print("Please set a default index thumbnail or your index page will not be very beautiful")

Expand Down
Loading

0 comments on commit 95df6a0

Please sign in to comment.