mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 01:12:08 +01:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			21cbf2b21a
			...
			migration-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					bb9f58e497 | 
@@ -7,25 +7,10 @@ stages:
 | 
				
			|||||||
variables:
 | 
					variables:
 | 
				
			||||||
  GIT_SUBMODULE_STRATEGY: recursive
 | 
					  GIT_SUBMODULE_STRATEGY: recursive
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Debian Buster
 | 
					# Ubuntu 22.04
 | 
				
			||||||
#  py37-django22:
 | 
					py310-django50:
 | 
				
			||||||
#   stage: test
 | 
					 | 
				
			||||||
#   image: debian:buster-backports
 | 
					 | 
				
			||||||
#   before_script:
 | 
					 | 
				
			||||||
#     - >
 | 
					 | 
				
			||||||
#         apt-get update &&
 | 
					 | 
				
			||||||
#         apt-get install --no-install-recommends -t buster-backports -y
 | 
					 | 
				
			||||||
#         python3-django python3-django-crispy-forms
 | 
					 | 
				
			||||||
#         python3-django-extensions python3-django-filters python3-django-polymorphic
 | 
					 | 
				
			||||||
#         python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					 | 
				
			||||||
#         python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					 | 
				
			||||||
#         python3-bs4 python3-setuptools tox texlive-xetex
 | 
					 | 
				
			||||||
#   script: tox -e py37-django22
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Ubuntu 20.04
 | 
					 | 
				
			||||||
py38-django22:
 | 
					 | 
				
			||||||
  stage: test
 | 
					  stage: test
 | 
				
			||||||
  image: ubuntu:20.04
 | 
					  image: ubuntu:22.04
 | 
				
			||||||
  before_script:
 | 
					  before_script:
 | 
				
			||||||
    # Fix tzdata prompt
 | 
					    # Fix tzdata prompt
 | 
				
			||||||
    - ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone
 | 
					    - ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone
 | 
				
			||||||
@@ -37,12 +22,12 @@ py38-django22:
 | 
				
			|||||||
        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
				
			||||||
        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
				
			||||||
        python3-bs4 python3-setuptools tox texlive-xetex
 | 
					        python3-bs4 python3-setuptools tox texlive-xetex
 | 
				
			||||||
  script: tox -e py38-django22
 | 
					  script: tox -e py310-django50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Debian Bullseye
 | 
					# Debian Bookworm
 | 
				
			||||||
py39-django22:
 | 
					py311-django50:
 | 
				
			||||||
  stage: test
 | 
					  stage: test
 | 
				
			||||||
  image: debian:bullseye
 | 
					  image: debian:bookworm
 | 
				
			||||||
  before_script:
 | 
					  before_script:
 | 
				
			||||||
    - >
 | 
					    - >
 | 
				
			||||||
        apt-get update &&
 | 
					        apt-get update &&
 | 
				
			||||||
@@ -52,7 +37,7 @@ py39-django22:
 | 
				
			|||||||
        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
				
			||||||
        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
				
			||||||
        python3-bs4 python3-setuptools tox texlive-xetex
 | 
					        python3-bs4 python3-setuptools tox texlive-xetex
 | 
				
			||||||
  script: tox -e py39-django22
 | 
					  script: tox -e py311-django50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
linters:
 | 
					linters:
 | 
				
			||||||
  stage: quality-assurance
 | 
					  stage: quality-assurance
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
 | 
					# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
 | 
				
			||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from bootstrap_datepicker_plus.widgets import DateTimePickerInput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from datetime import timedelta
 | 
					from datetime import timedelta
 | 
				
			||||||
from random import shuffle
 | 
					from random import shuffle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -10,7 +12,7 @@ from django.utils import timezone
 | 
				
			|||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
from member.models import Club
 | 
					from member.models import Club
 | 
				
			||||||
from note.models import Note, NoteUser
 | 
					from note.models import Note, NoteUser
 | 
				
			||||||
from note_kfet.inputs import Autocomplete, DateTimePickerInput
 | 
					from note_kfet.inputs import Autocomplete
 | 
				
			||||||
from note_kfet.middlewares import get_current_request
 | 
					from note_kfet.middlewares import get_current_request
 | 
				
			||||||
from permission.backends import PermissionBackend
 | 
					from permission.backends import PermissionBackend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.conf.urls import url, include
 | 
					from django.urls import include, re_path
 | 
				
			||||||
from rest_framework import routers
 | 
					from rest_framework import routers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .views import UserInformationView
 | 
					from .views import UserInformationView
 | 
				
			||||||
@@ -47,7 +47,7 @@ app_name = 'api'
 | 
				
			|||||||
# Wire up our API using automatic URL routing.
 | 
					# Wire up our API using automatic URL routing.
 | 
				
			||||||
# Additionally, we include login URLs for the browsable API.
 | 
					# Additionally, we include login URLs for the browsable API.
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    url('^', include(router.urls)),
 | 
					    re_path('^', include(router.urls)),
 | 
				
			||||||
    url('^me/', UserInformationView.as_view()),
 | 
					    re_path('^me/', UserInformationView.as_view()),
 | 
				
			||||||
    url('^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
 | 
					    re_path('^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import io
 | 
					import io
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from bootstrap_datepicker_plus.widgets import DatePickerInput
 | 
				
			||||||
from PIL import Image, ImageSequence
 | 
					from PIL import Image, ImageSequence
 | 
				
			||||||
from django import forms
 | 
					from django import forms
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
@@ -13,7 +14,7 @@ from django.forms import CheckboxSelectMultiple
 | 
				
			|||||||
from django.utils import timezone
 | 
					from django.utils import timezone
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
from note.models import NoteSpecial, Alias
 | 
					from note.models import NoteSpecial, Alias
 | 
				
			||||||
from note_kfet.inputs import Autocomplete, AmountInput, DatePickerInput
 | 
					from note_kfet.inputs import Autocomplete, AmountInput
 | 
				
			||||||
from permission.models import PermissionMask, Role
 | 
					from permission.models import PermissionMask, Role
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import Profile, Club, Membership
 | 
					from .models import Profile, Club, Membership
 | 
				
			||||||
@@ -32,7 +33,7 @@ class UserForm(forms.ModelForm):
 | 
				
			|||||||
        # Django usernames can only contain letters, numbers, @, ., +, - and _.
 | 
					        # Django usernames can only contain letters, numbers, @, ., +, - and _.
 | 
				
			||||||
        # We want to allow users to have uncommon and unpractical usernames:
 | 
					        # We want to allow users to have uncommon and unpractical usernames:
 | 
				
			||||||
        # That is their problem, and we have normalized aliases for us.
 | 
					        # That is their problem, and we have normalized aliases for us.
 | 
				
			||||||
        return super()._get_validation_exclusions() + ["username"]
 | 
					        return super()._get_validation_exclusions() | {"username"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = User
 | 
					        model = User
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,7 @@ class TemplateLoggedInTests(TestCase):
 | 
				
			|||||||
        self.assertRedirects(response, settings.LOGIN_REDIRECT_URL, 302, 302)
 | 
					        self.assertRedirects(response, settings.LOGIN_REDIRECT_URL, 302, 302)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_logout(self):
 | 
					    def test_logout(self):
 | 
				
			||||||
        response = self.client.get(reverse("logout"))
 | 
					        response = self.client.post(reverse("logout"))
 | 
				
			||||||
        self.assertEqual(response.status_code, 200)
 | 
					        self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_admin_index(self):
 | 
					    def test_admin_index(self):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ def register_note_urls(router, path):
 | 
				
			|||||||
    router.register(path + '/note', NotePolymorphicViewSet)
 | 
					    router.register(path + '/note', NotePolymorphicViewSet)
 | 
				
			||||||
    router.register(path + '/alias', AliasViewSet)
 | 
					    router.register(path + '/alias', AliasViewSet)
 | 
				
			||||||
    router.register(path + '/trust', TrustViewSet)
 | 
					    router.register(path + '/trust', TrustViewSet)
 | 
				
			||||||
    router.register(path + '/consumer', ConsumerViewSet)
 | 
					    router.register(path + '/consumer', ConsumerViewSet, basename="consumer")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    router.register(path + '/transaction/category', TemplateCategoryViewSet)
 | 
					    router.register(path + '/transaction/category', TemplateCategoryViewSet)
 | 
				
			||||||
    router.register(path + '/transaction/transaction', TransactionViewSet)
 | 
					    router.register(path + '/transaction/transaction', TransactionViewSet)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -179,19 +179,10 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
 | 
				
			|||||||
            # We match first an alias if it is matched without normalization,
 | 
					            # We match first an alias if it is matched without normalization,
 | 
				
			||||||
            # then if the normalized pattern matches a normalized alias.
 | 
					            # then if the normalized pattern matches a normalized alias.
 | 
				
			||||||
            queryset = queryset.filter(
 | 
					            queryset = queryset.filter(
 | 
				
			||||||
                **{f'name{suffix}': alias_prefix + alias}
 | 
					                Q(**{f'name{suffix}': alias_prefix + alias})
 | 
				
			||||||
            ).union(
 | 
					                | Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)})
 | 
				
			||||||
                queryset.filter(
 | 
					                | Q(**{f'normalized_name{suffix}': alias_prefix + alias.lower()})
 | 
				
			||||||
                    Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)})
 | 
					            )
 | 
				
			||||||
                    & ~Q(**{f'name{suffix}': alias_prefix + alias})
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                all=True).union(
 | 
					 | 
				
			||||||
                queryset.filter(
 | 
					 | 
				
			||||||
                    Q(**{f'normalized_name{suffix}': alias_prefix + alias.lower()})
 | 
					 | 
				
			||||||
                    & ~Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)})
 | 
					 | 
				
			||||||
                    & ~Q(**{f'name{suffix}': alias_prefix + alias})
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                all=True)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        queryset = queryset if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' \
 | 
					        queryset = queryset if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' \
 | 
				
			||||||
            else queryset.order_by("name")
 | 
					            else queryset.order_by("name")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,15 @@
 | 
				
			|||||||
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
 | 
					# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
 | 
				
			||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from datetime import datetime
 | 
					from datetime import datetime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from bootstrap_datepicker_plus.widgets import DateTimePickerInput
 | 
				
			||||||
from django import forms
 | 
					from django import forms
 | 
				
			||||||
from django.contrib.contenttypes.models import ContentType
 | 
					from django.contrib.contenttypes.models import ContentType
 | 
				
			||||||
from django.forms import CheckboxSelectMultiple
 | 
					from django.forms import CheckboxSelectMultiple
 | 
				
			||||||
from django.utils.timezone import make_aware
 | 
					from django.utils.timezone import make_aware
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
from note_kfet.inputs import Autocomplete, AmountInput, DateTimePickerInput
 | 
					from note_kfet.inputs import Autocomplete, AmountInput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import TransactionTemplate, NoteClub, Alias
 | 
					from .models import TransactionTemplate, NoteClub, Alias
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ def create_special_notes(apps, schema_editor):
 | 
				
			|||||||
class Migration(migrations.Migration):
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
    dependencies = [
 | 
					    dependencies = [
 | 
				
			||||||
        ('note', '0001_initial'),
 | 
					        ('note', '0001_initial'),
 | 
				
			||||||
 | 
					        ('logs', '0001_initial'),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    operations = [
 | 
					    operations = [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					# Generated by Django 5.0.7 on 2024-07-11 09:24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import django.db.models.deletion
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('contenttypes', '0002_remove_content_type_name'),
 | 
				
			||||||
 | 
					        ('note', '0006_trust'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='note',
 | 
				
			||||||
 | 
					            name='polymorphic_ctype',
 | 
				
			||||||
 | 
					            field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='transaction',
 | 
				
			||||||
 | 
					            name='polymorphic_ctype',
 | 
				
			||||||
 | 
					            field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -9,7 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			|||||||
           name="{{ widget.name }}"
 | 
					           name="{{ widget.name }}"
 | 
				
			||||||
           {# Other attributes are loaded  #}
 | 
					           {# Other attributes are loaded  #}
 | 
				
			||||||
           {% for name, value in widget.attrs.items %}
 | 
					           {% for name, value in widget.attrs.items %}
 | 
				
			||||||
                {% ifnotequal value False %}{{ name }}{% ifnotequal value True %}="{{ value|stringformat:'s' }}"{% endifnotequal %}{% endifnotequal %}
 | 
					                {% if value != False %}{{ name }}{% if value != True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}
 | 
				
			||||||
            {% endfor %}>
 | 
					            {% endfor %}>
 | 
				
			||||||
    <div class="input-group-append">
 | 
					    <div class="input-group-append">
 | 
				
			||||||
        <span class="input-group-text">€</span>
 | 
					        <span class="input-group-text">€</span>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					# Generated by Django 5.0.7 on 2024-07-11 09:24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('note', '0007_alter_note_polymorphic_ctype_and_more'),
 | 
				
			||||||
 | 
					        ('treasury', '0008_auto_20240322_0045'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='sogecredit',
 | 
				
			||||||
 | 
					            name='transactions',
 | 
				
			||||||
 | 
					            field=models.ManyToManyField(blank=True, related_name='+', to='note.membershiptransaction', verbose_name='membership transactions'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -1,13 +1,14 @@
 | 
				
			|||||||
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
 | 
					# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
 | 
				
			||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from bootstrap_datepicker_plus.widgets import DatePickerInput
 | 
				
			||||||
from django import forms
 | 
					from django import forms
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
from django.db.models import Q
 | 
					from django.db.models import Q
 | 
				
			||||||
from django.forms import CheckboxSelectMultiple
 | 
					from django.forms import CheckboxSelectMultiple
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
from note.models import NoteSpecial, NoteUser
 | 
					from note.models import NoteSpecial, NoteUser
 | 
				
			||||||
from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete, ColorWidget
 | 
					from note_kfet.inputs import AmountInput, Autocomplete, ColorWidget
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..models import WEIClub, WEIRegistration, Bus, BusTeam, WEIMembership, WEIRole
 | 
					from ..models import WEIClub, WEIRegistration, Bus, BusTeam, WEIMembership, WEIRole
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -439,7 +439,7 @@ class TestWEIRegistration(TestCase):
 | 
				
			|||||||
            emergency_contact_phone='+33123456789',
 | 
					            emergency_contact_phone='+33123456789',
 | 
				
			||||||
        ))
 | 
					        ))
 | 
				
			||||||
        self.assertEqual(response.status_code, 200)
 | 
					        self.assertEqual(response.status_code, 200)
 | 
				
			||||||
        self.assertTrue("This user can't be in her/his first year since he/she has already participated to a WEI."
 | 
					        self.assertTrue("This user can't be in her/his first year since he/she has already participated to a WEI."
 | 
				
			||||||
                        in str(response.context["form"].errors))
 | 
					                        in str(response.context["form"].errors))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Check that if the WEI is started, we can't register anyone
 | 
					        # Check that if the WEI is started, we can't register anyone
 | 
				
			||||||
@@ -635,7 +635,7 @@ class TestWEIRegistration(TestCase):
 | 
				
			|||||||
        ))
 | 
					        ))
 | 
				
			||||||
        self.assertEqual(response.status_code, 200)
 | 
					        self.assertEqual(response.status_code, 200)
 | 
				
			||||||
        self.assertFalse(response.context["form"].is_valid())
 | 
					        self.assertFalse(response.context["form"].is_valid())
 | 
				
			||||||
        self.assertTrue("This team doesn't belong to the given bus." in str(response.context["form"].errors))
 | 
					        self.assertTrue("This team doesn't belong to the given bus." in str(response.context["form"].errors))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        response = self.client.post(reverse("wei:validate_registration", kwargs=dict(pk=self.registration.pk)), dict(
 | 
					        response = self.client.post(reverse("wei:validate_registration", kwargs=dict(pk=self.registration.pk)), dict(
 | 
				
			||||||
            roles=[WEIRole.objects.get(name="GC WEI").id],
 | 
					            roles=[WEIRole.objects.get(name="GC WEI").id],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,19 +25,13 @@ admin_site.register(Site, SiteAdmin)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Add external apps model
 | 
					# Add external apps model
 | 
				
			||||||
if "oauth2_provider" in settings.INSTALLED_APPS:
 | 
					if "oauth2_provider" in settings.INSTALLED_APPS:
 | 
				
			||||||
    from oauth2_provider.admin import Application, ApplicationAdmin, Grant, \
 | 
					    from oauth2_provider.admin import ApplicationAdmin, GrantAdmin, AccessTokenAdmin, RefreshTokenAdmin
 | 
				
			||||||
        GrantAdmin, AccessToken, AccessTokenAdmin, RefreshToken, RefreshTokenAdmin
 | 
					    from oauth2_provider.models import Application, Grant, AccessToken, RefreshToken
 | 
				
			||||||
    admin_site.register(Application, ApplicationAdmin)
 | 
					    admin_site.register(Application, ApplicationAdmin)
 | 
				
			||||||
    admin_site.register(Grant, GrantAdmin)
 | 
					    admin_site.register(Grant, GrantAdmin)
 | 
				
			||||||
    admin_site.register(AccessToken, AccessTokenAdmin)
 | 
					    admin_site.register(AccessToken, AccessTokenAdmin)
 | 
				
			||||||
    admin_site.register(RefreshToken, RefreshTokenAdmin)
 | 
					    admin_site.register(RefreshToken, RefreshTokenAdmin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if "django_htcpcp_tea" in settings.INSTALLED_APPS:
 | 
					 | 
				
			||||||
    from django_htcpcp_tea.admin import *
 | 
					 | 
				
			||||||
    from django_htcpcp_tea.models import *
 | 
					 | 
				
			||||||
    admin_site.register(Pot, PotAdmin)
 | 
					 | 
				
			||||||
    admin_site.register(TeaType, TeaTypeAdmin)
 | 
					 | 
				
			||||||
    admin_site.register(Addition, AdditionAdmin)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if "mailer" in settings.INSTALLED_APPS:
 | 
					if "mailer" in settings.INSTALLED_APPS:
 | 
				
			||||||
    from mailer.admin import *
 | 
					    from mailer.admin import *
 | 
				
			||||||
@@ -50,9 +44,3 @@ if "rest_framework" in settings.INSTALLED_APPS:
 | 
				
			|||||||
    from rest_framework.authtoken.admin import *
 | 
					    from rest_framework.authtoken.admin import *
 | 
				
			||||||
    from rest_framework.authtoken.models import *
 | 
					    from rest_framework.authtoken.models import *
 | 
				
			||||||
    admin_site.register(Token, TokenAdmin)
 | 
					    admin_site.register(Token, TokenAdmin)
 | 
				
			||||||
 | 
					 | 
				
			||||||
if "cas_server" in settings.INSTALLED_APPS:
 | 
					 | 
				
			||||||
    from cas_server.admin import *
 | 
					 | 
				
			||||||
    from cas_server.models import *
 | 
					 | 
				
			||||||
    admin_site.register(ServicePattern, ServicePatternAdmin)
 | 
					 | 
				
			||||||
    admin_site.register(FederatedIendityProvider, FederatedIendityProviderAdmin)
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ INSTALLED_APPS = [
 | 
				
			|||||||
    'bootstrap_datepicker_plus',
 | 
					    'bootstrap_datepicker_plus',
 | 
				
			||||||
    'colorfield',
 | 
					    'colorfield',
 | 
				
			||||||
    'crispy_forms',
 | 
					    'crispy_forms',
 | 
				
			||||||
    'django_htcpcp_tea',
 | 
					    'crispy_bootstrap4',
 | 
				
			||||||
    'django_tables2',
 | 
					    'django_tables2',
 | 
				
			||||||
    'mailer',
 | 
					    'mailer',
 | 
				
			||||||
    'phonenumber_field',
 | 
					    'phonenumber_field',
 | 
				
			||||||
@@ -90,7 +90,6 @@ MIDDLEWARE = [
 | 
				
			|||||||
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
 | 
					    'django.middleware.clickjacking.XFrameOptionsMiddleware',
 | 
				
			||||||
    'django.middleware.locale.LocaleMiddleware',
 | 
					    'django.middleware.locale.LocaleMiddleware',
 | 
				
			||||||
    'django.contrib.sites.middleware.CurrentSiteMiddleware',
 | 
					    'django.contrib.sites.middleware.CurrentSiteMiddleware',
 | 
				
			||||||
    'django_htcpcp_tea.middleware.HTCPCPTeaMiddleware',
 | 
					 | 
				
			||||||
    'note_kfet.middlewares.SessionMiddleware',
 | 
					    'note_kfet.middlewares.SessionMiddleware',
 | 
				
			||||||
    'note_kfet.middlewares.LoginByIPMiddleware',
 | 
					    'note_kfet.middlewares.LoginByIPMiddleware',
 | 
				
			||||||
    'note_kfet.middlewares.TurbolinksMiddleware',
 | 
					    'note_kfet.middlewares.TurbolinksMiddleware',
 | 
				
			||||||
@@ -295,3 +294,6 @@ PHONENUMBER_DEFAULT_REGION = 'FR'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# We add custom information to CAS, in order to give a normalized name to other services
 | 
					# We add custom information to CAS, in order to give a normalized name to other services
 | 
				
			||||||
CAS_AUTH_CLASS = 'member.auth.CustomAuthUser'
 | 
					CAS_AUTH_CLASS = 'member.auth.CustomAuthUser'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Default field for primary key
 | 
				
			||||||
 | 
					DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			|||||||
   {% if widget.value != None and widget.value != "" %}value="{{ widget.value }}"{% endif %}
 | 
					   {% if widget.value != None and widget.value != "" %}value="{{ widget.value }}"{% endif %}
 | 
				
			||||||
   name="{{ widget.name }}_name" autocomplete="off"
 | 
					   name="{{ widget.name }}_name" autocomplete="off"
 | 
				
			||||||
    {% for name, value in widget.attrs.items %}
 | 
					    {% for name, value in widget.attrs.items %}
 | 
				
			||||||
        {% ifnotequal value False %}{{ name }}{% ifnotequal value True %}="{{ value|stringformat:'s' }}"{% endifnotequal %}{% endifnotequal %}
 | 
					        {% if value != False %}{{ name }}{% if value != True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}
 | 
				
			||||||
    {% endfor %}
 | 
					    {% endfor %}
 | 
				
			||||||
    aria-describedby="{{widget.attrs.id}}_tooltip">
 | 
					    aria-describedby="{{widget.attrs.id}}_tooltip">
 | 
				
			||||||
    {% if widget.resetable %}
 | 
					    {% if widget.resetable %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -126,9 +126,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			|||||||
                                <a class="dropdown-item" href="{% url 'member:user_detail' pk=request.user.pk %}">
 | 
					                                <a class="dropdown-item" href="{% url 'member:user_detail' pk=request.user.pk %}">
 | 
				
			||||||
                                    <i class="fa fa-user"></i> {% trans "My account" %}
 | 
					                                    <i class="fa fa-user"></i> {% trans "My account" %}
 | 
				
			||||||
                                </a>
 | 
					                                </a>
 | 
				
			||||||
                                <a class="dropdown-item" href="{% url 'logout' %}">
 | 
					                                <form method="post" action="{% url 'logout' %}">
 | 
				
			||||||
 | 
					                                  {% csrf_token %}
 | 
				
			||||||
 | 
					                                  <button class="dropdown-item" type="submit">
 | 
				
			||||||
                                    <i class="fa fa-sign-out"></i> {% trans "Log out" %}
 | 
					                                    <i class="fa fa-sign-out"></i> {% trans "Log out" %}
 | 
				
			||||||
                                </a>
 | 
					                                  </button>
 | 
				
			||||||
 | 
					                                </form>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                        </li>
 | 
					                        </li>
 | 
				
			||||||
                    {% else %}
 | 
					                    {% else %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,9 +30,6 @@ urlpatterns = [
 | 
				
			|||||||
    path('accounts/', include('django.contrib.auth.urls')),
 | 
					    path('accounts/', include('django.contrib.auth.urls')),
 | 
				
			||||||
    path('api/', include('api.urls')),
 | 
					    path('api/', include('api.urls')),
 | 
				
			||||||
    path('permission/', include('permission.urls')),
 | 
					    path('permission/', include('permission.urls')),
 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Make coffee
 | 
					 | 
				
			||||||
    path('coffee/', include('django_htcpcp_tea.urls')),
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# During development, serve static and media files
 | 
					# During development, serve static and media files
 | 
				
			||||||
@@ -46,11 +43,6 @@ if "oauth2_provider" in settings.INSTALLED_APPS:
 | 
				
			|||||||
        path('o/', include('oauth2_provider.urls', namespace='oauth2_provider'))
 | 
					        path('o/', include('oauth2_provider.urls', namespace='oauth2_provider'))
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if "cas_server" in settings.INSTALLED_APPS:
 | 
					 | 
				
			||||||
    urlpatterns.append(
 | 
					 | 
				
			||||||
        path('cas/', include('cas_server.urls', namespace='cas_server'))
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if "debug_toolbar" in settings.INSTALLED_APPS:
 | 
					if "debug_toolbar" in settings.INSTALLED_APPS:
 | 
				
			||||||
    import debug_toolbar
 | 
					    import debug_toolbar
 | 
				
			||||||
    urlpatterns = [
 | 
					    urlpatterns = [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,19 +1,17 @@
 | 
				
			|||||||
beautifulsoup4~=4.7.1
 | 
					beautifulsoup4~=4.12.3
 | 
				
			||||||
Django~=2.2.15
 | 
					crispy-bootstrap4~=2024.1
 | 
				
			||||||
django-bootstrap-datepicker-plus~=3.0.5
 | 
					Django~=5.0.7
 | 
				
			||||||
django-cas-server~=1.2.0
 | 
					django-bootstrap-datepicker-plus~=5.0.5
 | 
				
			||||||
django-colorfield~=0.3.2
 | 
					django-colorfield~=0.11.0
 | 
				
			||||||
django-crispy-forms~=1.7.2
 | 
					django-crispy-forms~=2.2
 | 
				
			||||||
django-extensions>=2.1.4
 | 
					django-extensions~=3.2.3
 | 
				
			||||||
django-filter~=2.1
 | 
					django-filter~=24.2
 | 
				
			||||||
django-htcpcp-tea~=0.3.1
 | 
					django-mailer~=2.3.2
 | 
				
			||||||
django-mailer~=2.0.1
 | 
					django-oauth-toolkit~=2.4.0
 | 
				
			||||||
django-oauth-toolkit~=1.3.3
 | 
					django-phonenumber-field~=8.0.0
 | 
				
			||||||
django-phonenumber-field~=5.0.0
 | 
					django-polymorphic~=3.1.0
 | 
				
			||||||
django-polymorphic>=2.0.3,<3.0.0
 | 
					django-rest-polymorphic~=0.1.10
 | 
				
			||||||
djangorestframework>=3.9.0,<3.13.0
 | 
					django-tables2~=2.7.0
 | 
				
			||||||
django-rest-polymorphic~=0.1.9
 | 
					djangorestframework~=3.15.2
 | 
				
			||||||
django-tables2~=2.3.1
 | 
					phonenumbers~=8.13.40
 | 
				
			||||||
python-memcached~=1.59
 | 
					 | 
				
			||||||
phonenumbers~=8.9.10
 | 
					 | 
				
			||||||
Pillow>=5.4.1
 | 
					Pillow>=5.4.1
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								tox.ini
									
									
									
									
									
								
							@@ -1,13 +1,10 @@
 | 
				
			|||||||
[tox]
 | 
					[tox]
 | 
				
			||||||
envlist =
 | 
					envlist =
 | 
				
			||||||
    # Debian Buster Python
 | 
					 | 
				
			||||||
    py37-django22
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Ubuntu 20.04 Python
 | 
					    # Ubuntu 20.04 Python
 | 
				
			||||||
    py38-django22
 | 
					    py310-django50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Debian Bullseye Python
 | 
					    # Debian Bullseye Python
 | 
				
			||||||
    py39-django22
 | 
					    py311-django50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    linters
 | 
					    linters
 | 
				
			||||||
skipsdist = True
 | 
					skipsdist = True
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user