5 Commits

303 changed files with 5247 additions and 9039 deletions

View File

@ -6,13 +6,13 @@ runs:
- name: Install apt packages - name: Install apt packages
uses: awalsh128/cache-apt-pkgs-action@latest uses: awalsh128/cache-apt-pkgs-action@latest
with: with:
packages: gettext libgraphviz-dev packages: gettext libxapian-dev libgraphviz-dev
version: 1.0 # increment to reset cache version: 1.0 # increment to reset cache
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update sudo apt update
sudo apt install gettext libgraphviz-dev sudo apt install gettext libxapian-dev libgraphviz-dev
shell: bash shell: bash
- name: Set up python - name: Set up python
@ -45,11 +45,7 @@ runs:
${{ runner.os }}-poetry- ${{ runner.os }}-poetry-
- name: Install dependencies - name: Install dependencies
run: poetry install --with docs,tests run: poetry install -E testing -E docs
shell: bash
- name: Install xapian
run: poetry run ./manage.py install_xapian
shell: bash shell: bash
- name: Compile gettext messages - name: Compile gettext messages

View File

@ -2,35 +2,36 @@ name: Sith 3 CI
on: on:
push: push:
branches: [master, taiste] branches:
- master
- taiste
pull_request: pull_request:
branches: [master, taiste] branches:
workflow_dispatch: - master
- taiste
jobs: jobs:
ruff: black:
name: Ruff lint & format name: Black format
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - name: Check out repository
- name: ruff format uses: actions/checkout@v3
uses: chartboost/ruff-action@v1 # format - name: Setup Project
with: uses: ./.github/actions/setup_project
args: format --diff - run: poetry run black --check .
- name: ruff check
uses: chartboost/ruff-action@v1 # lint
tests: tests:
name: Run tests and generate coverage report name: Run tests and generate coverage report
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repository - name: Check out repository
uses: actions/checkout@v4 uses: actions/checkout@v3
- uses: ./.github/actions/setup_project - uses: ./.github/actions/setup_project
- uses: ./.github/actions/setup_xapian - uses: ./.github/actions/setup_xapian
- uses: ./.github/actions/compile_messages - uses: ./.github/actions/compile_messages
- name: Run tests - name: Run tests
run: poetry run coverage run -m pytest run: poetry run coverage run ./manage.py test
- name: Generate coverage report - name: Generate coverage report
run: | run: |
poetry run coverage report poetry run coverage report

View File

@ -2,8 +2,7 @@ name: Sith3 taiste
on: on:
push: push:
branches: [taiste] branches: [ taiste ]
workflow_dispatch:
jobs: jobs:
deployment: deployment:

View File

@ -1,31 +0,0 @@
# Contributors
Thanks to everyone who has contributed to this project! We appreciate your time and effort.
## Copyright
> All contributions to this project are subject to the copyright owned by the Association des Étudiants de l'Université de Technologie de Belfort-Montbéliard (AE UTBM), for both past and future years. By making a contribution to this project, you acknowledge and agree that AE UTBM has the exclusive right to use, distribute, and modify your contribution, as well as to license others to do the same, in any way they see fit.
## License
This project was previously released under the MIT license, but it has since been changed to the GPL v3 license. Any contributions made to this project before the switch to GPL v3 are still subject to the MIT license, while contributions made after the switch are subject to the GPL v3 license.
## List of Contributors
- [@Hyask](https://github.com/Hyask) — Florent "Skia" Jacquet <skia@hya.sk>
- [@klmp200](https://github.com/klmp200) — Antoine "Sli" Bartuccio <antoine@bartuccio.fr>
- [@nab-os](https://github.com/nab-os) (AKA Gnikwo) — Sasha "Nabos" Ballet <nabos@glargh.fr>
- [@Krophil](https://github.com/Krophil) — Pierre "Krophil'" Brunet <pierre.brunet@krophil.fr>
- [@guillaume-renaud](https://github.com/guillaume-renaud) — Guillaume "Lo-J" RENAUD <renaudg779@gmail.com>
- [@imperosol](https://github.com/imperosol) — Thomas "Maréchal" Girod <thgirod@hotmail.com>
- [@TheoDurr](https://github.com/TheoDurr) — Théo "Ailé" Durr <git@theodurr.fr>
- [@RTrioux](https://github.com/RTrioux) — Robin "Vial" Trioux
- [@TheRolfFR](https://github.com/TheRolfFR) — Yann "Réseau" Le Vaguerès
- [@Magador](https://github.com/Magador) — Lucie "Magador" Lenglet
- [@lsacienne](https://github.com/lsacienne) — Alexandre "L'Sacienne" Viala
- [@Juknum](https://github.com/Juknum) — Julien "Tinople" Constant
- [@Tartofraise](https://github.com/Tartofraise) — Ryan "Soldat" Hadj-Mebarek
- [@FrancescoWitz](https://github.com/FrancescoWitz) — Francesco "Och" WITZ
- [@maxence-leblanc](https://github.com/maxence-leblanc) — Maxence "Juste" LEBLANC
_If you've contributed to this project and your name isn't on the list, please let us know so we can add you. And if you've contributed anonymously, thank you! We appreciate your contributions just as much as those from named contributors._

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2016 Skia
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,19 +1,15 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #

View File

@ -1,27 +1,24 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.contrib import admin from django.contrib import admin
from accounting.models import * from accounting.models import *
admin.site.register(BankAccount) admin.site.register(BankAccount)
admin.site.register(ClubAccount) admin.site.register(ClubAccount)
admin.site.register(GeneralJournal) admin.site.register(GeneralJournal)

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.core.validators
import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
import django.core.validators
import accounting.models import accounting.models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import phonenumber_field.modelfields
from django.db import migrations, models from django.db import migrations, models
import phonenumber_field.modelfields
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,36 +1,32 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from decimal import Decimal
from django.conf import settings
from django.core import validators
from django.core.exceptions import ValidationError
from django.db import models
from django.template import defaultfilters
from django.urls import reverse from django.urls import reverse
from django.core.exceptions import ValidationError
from django.core import validators
from django.db import models
from django.conf import settings
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.template import defaultfilters
from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.modelfields import PhoneNumberField
from decimal import Decimal
from core.models import User, SithFile
from club.models import Club from club.models import Club
from core.models import SithFile, User
class CurrencyField(models.DecimalField): class CurrencyField(models.DecimalField):

View File

@ -1,99 +1,100 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from datetime import date, timedelta
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from django.core.management import call_command
from datetime import date, timedelta
from core.models import User
from accounting.models import ( from accounting.models import (
AccountingType,
GeneralJournal, GeneralJournal,
Label,
Operation, Operation,
Label,
AccountingType,
SimplifiedAccountingType, SimplifiedAccountingType,
) )
from core.models import User
class RefoundAccountTest(TestCase): class RefoundAccountTest(TestCase):
@classmethod def setUp(self):
def setUpTestData(cls): self.skia = User.objects.filter(username="skia").first()
cls.skia = User.objects.get(username="skia")
# reffil skia's account # reffil skia's account
cls.skia.customer.amount = 800 self.skia.customer.amount = 800
cls.skia.customer.save() self.skia.customer.save()
cls.refound_account_url = reverse("accounting:refound_account")
def test_permission_denied(self): def test_permission_denied(self):
self.client.force_login(User.objects.get(username="guy")) self.client.login(username="guy", password="plop")
response_post = self.client.post( response_post = self.client.post(
self.refound_account_url, {"user": self.skia.id} reverse("accounting:refound_account"), {"user": self.skia.id}
) )
response_get = self.client.get(self.refound_account_url) response_get = self.client.get(reverse("accounting:refound_account"))
assert response_get.status_code == 403 self.assertTrue(response_get.status_code == 403)
assert response_post.status_code == 403 self.assertTrue(response_post.status_code == 403)
def test_root_granteed(self): def test_root_granteed(self):
self.client.force_login(User.objects.get(username="root")) self.client.login(username="root", password="plop")
response = self.client.post(self.refound_account_url, {"user": self.skia.id}) response_post = self.client.post(
self.assertRedirects(response, self.refound_account_url) reverse("accounting:refound_account"), {"user": self.skia.id}
self.skia.refresh_from_db() )
response = self.client.get(self.refound_account_url) self.skia = User.objects.filter(username="skia").first()
assert response.status_code == 200 response_get = self.client.get(reverse("accounting:refound_account"))
assert '<form action="" method="post">' in str(response.content) self.assertFalse(response_get.status_code == 403)
assert self.skia.customer.amount == 0 self.assertTrue('<form action="" method="post">' in str(response_get.content))
self.assertFalse(response_post.status_code == 403)
self.assertTrue(self.skia.customer.amount == 0)
def test_comptable_granteed(self): def test_comptable_granteed(self):
self.client.force_login(User.objects.get(username="comptable")) self.client.login(username="comptable", password="plop")
response = self.client.post(self.refound_account_url, {"user": self.skia.id}) response_post = self.client.post(
self.assertRedirects(response, self.refound_account_url) reverse("accounting:refound_account"), {"user": self.skia.id}
self.skia.refresh_from_db() )
response = self.client.get(self.refound_account_url) self.skia = User.objects.filter(username="skia").first()
assert response.status_code == 200 response_get = self.client.get(reverse("accounting:refound_account"))
assert '<form action="" method="post">' in str(response.content) self.assertFalse(response_get.status_code == 403)
assert self.skia.customer.amount == 0 self.assertTrue('<form action="" method="post">' in str(response_get.content))
self.assertFalse(response_post.status_code == 403)
self.assertTrue(self.skia.customer.amount == 0)
class JournalTest(TestCase): class JournalTest(TestCase):
@classmethod def setUp(self):
def setUpTestData(cls): self.journal = GeneralJournal.objects.filter(id=1).first()
cls.journal = GeneralJournal.objects.get(id=1)
def test_permission_granted(self): def test_permission_granted(self):
self.client.force_login(User.objects.get(username="comptable")) self.client.login(username="comptable", password="plop")
response_get = self.client.get( response_get = self.client.get(
reverse("accounting:journal_details", args=[self.journal.id]) reverse("accounting:journal_details", args=[self.journal.id])
) )
assert response_get.status_code == 200 self.assertTrue(response_get.status_code == 200)
assert "<td>M\\xc3\\xa9thode de paiement</td>" in str(response_get.content) self.assertTrue(
"<td>M\\xc3\\xa9thode de paiement</td>" in str(response_get.content)
)
def test_permission_not_granted(self): def test_permission_not_granted(self):
self.client.force_login(User.objects.get(username="skia")) self.client.login(username="skia", password="plop")
response_get = self.client.get( response_get = self.client.get(
reverse("accounting:journal_details", args=[self.journal.id]) reverse("accounting:journal_details", args=[self.journal.id])
) )
assert response_get.status_code == 403 self.assertTrue(response_get.status_code == 403)
assert "<td>M\xc3\xa9thode de paiement</td>" not in str(response_get.content) self.assertFalse(
"<td>M\xc3\xa9thode de paiement</td>" in str(response_get.content)
)
class OperationTest(TestCase): class OperationTest(TestCase):
@ -107,8 +108,9 @@ class OperationTest(TestCase):
code="443", label="Ce code n'existe pas", movement_type="CREDIT" code="443", label="Ce code n'existe pas", movement_type="CREDIT"
) )
at.save() at.save()
l = Label.objects.create(club_account=self.journal.club_account, name="bob") l = Label(club_account=self.journal.club_account, name="bob")
self.client.force_login(User.objects.get(username="comptable")) l.save()
self.client.login(username="comptable", password="plop")
self.op1 = Operation( self.op1 = Operation(
journal=self.journal, journal=self.journal,
date=date.today(), date=date.today(),
@ -137,7 +139,8 @@ class OperationTest(TestCase):
self.op2.save() self.op2.save()
def test_new_operation(self): def test_new_operation(self):
at = AccountingType.objects.get(code="604") self.client.login(username="comptable", password="plop")
at = AccountingType.objects.filter(code="604").first()
response = self.client.post( response = self.client.post(
reverse("accounting:op_new", args=[self.journal.id]), reverse("accounting:op_new", args=[self.journal.id]),
{ {
@ -169,7 +172,8 @@ class OperationTest(TestCase):
self.assertTrue("<td>Le fantome de la nuit</td>" in str(response_get.content)) self.assertTrue("<td>Le fantome de la nuit</td>" in str(response_get.content))
def test_bad_new_operation(self): def test_bad_new_operation(self):
AccountingType.objects.get(code="604") self.client.login(username="comptable", password="plop")
AccountingType.objects.filter(code="604").first()
response = self.client.post( response = self.client.post(
reverse("accounting:op_new", args=[self.journal.id]), reverse("accounting:op_new", args=[self.journal.id]),
{ {
@ -195,7 +199,7 @@ class OperationTest(TestCase):
) )
def test_new_operation_not_authorized(self): def test_new_operation_not_authorized(self):
self.client.force_login(self.skia) self.client.login(username="skia", password="plop")
at = AccountingType.objects.filter(code="604").first() at = AccountingType.objects.filter(code="604").first()
response = self.client.post( response = self.client.post(
reverse("accounting:op_new", args=[self.journal.id]), reverse("accounting:op_new", args=[self.journal.id]),
@ -222,6 +226,7 @@ class OperationTest(TestCase):
) )
def test__operation_simple_accounting(self): def test__operation_simple_accounting(self):
self.client.login(username="comptable", password="plop")
sat = SimplifiedAccountingType.objects.all().first() sat = SimplifiedAccountingType.objects.all().first()
response = self.client.post( response = self.client.post(
reverse("accounting:op_new", args=[self.journal.id]), reverse("accounting:op_new", args=[self.journal.id]),
@ -258,12 +263,14 @@ class OperationTest(TestCase):
) )
def test_nature_statement(self): def test_nature_statement(self):
self.client.login(username="comptable", password="plop")
response = self.client.get( response = self.client.get(
reverse("accounting:journal_nature_statement", args=[self.journal.id]) reverse("accounting:journal_nature_statement", args=[self.journal.id])
) )
self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200) self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200)
def test_person_statement(self): def test_person_statement(self):
self.client.login(username="comptable", password="plop")
response = self.client.get( response = self.client.get(
reverse("accounting:journal_person_statement", args=[self.journal.id]) reverse("accounting:journal_person_statement", args=[self.journal.id])
) )
@ -285,6 +292,7 @@ class OperationTest(TestCase):
) )
def test_accounting_statement(self): def test_accounting_statement(self):
self.client.login(username="comptable", password="plop")
response = self.client.get( response = self.client.get(
reverse("accounting:journal_accounting_statement", args=[self.journal.id]) reverse("accounting:journal_accounting_statement", args=[self.journal.id])
) )

View File

@ -1,21 +1,17 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.urls import path from django.urls import path

View File

@ -1,58 +1,54 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView
from django.urls import reverse_lazy, reverse
from django.utils.translation import gettext_lazy as _
from django.forms.models import modelform_factory
from django.core.exceptions import PermissionDenied, ValidationError
from django.forms import HiddenInput
from django.db import transaction
from django.db.models import Sum
from django.conf import settings
from django import forms
from django.http import HttpResponse
import collections import collections
from ajax_select.fields import AutoCompleteSelectField from ajax_select.fields import AutoCompleteSelectField
from django import forms
from django.conf import settings
from django.core.exceptions import PermissionDenied, ValidationError
from django.db import transaction
from django.db.models import Sum
from django.forms import HiddenInput
from django.forms.models import modelform_factory
from django.http import HttpResponse
from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from accounting.models import (
AccountingType,
BankAccount,
ClubAccount,
Company,
GeneralJournal,
Label,
Operation,
SimplifiedAccountingType,
)
from core.views import ( from core.views import (
CanCreateMixin, CanViewMixin,
CanEditMixin, CanEditMixin,
CanEditPropMixin, CanEditPropMixin,
CanViewMixin, CanCreateMixin,
TabedViewMixin, TabedViewMixin,
) )
from core.views.forms import SelectDate, SelectFile from core.views.forms import SelectFile, SelectDate
from counter.models import Counter, Product, Selling from accounting.models import (
BankAccount,
ClubAccount,
GeneralJournal,
Operation,
AccountingType,
Company,
SimplifiedAccountingType,
Label,
)
from counter.models import Counter, Selling, Product
# Main accounting view # Main accounting view
@ -525,14 +521,14 @@ class OperationPDFView(CanViewMixin, DetailView):
pk_url_kwarg = "op_id" pk_url_kwarg = "op_id"
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors from reportlab.lib import colors
from reportlab.lib.pagesizes import letter from reportlab.lib.pagesizes import letter
from reportlab.lib.units import cm
from reportlab.lib.utils import ImageReader from reportlab.lib.utils import ImageReader
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas from reportlab.pdfbase import pdfmetrics
from reportlab.platypus import Table, TableStyle
pdfmetrics.registerFont(TTFont("DejaVu", "DejaVuSerif.ttf")) pdfmetrics.registerFont(TTFont("DejaVu", "DejaVuSerif.ttf"))
@ -603,7 +599,7 @@ class OperationPDFView(CanViewMixin, DetailView):
payment_mode = "" payment_mode = ""
for m in settings.SITH_ACCOUNTING_PAYMENT_METHOD: for m in settings.SITH_ACCOUNTING_PAYMENT_METHOD:
if m[0] == mode: if m[0] == mode:
payment_mode += "[\u00d7]" payment_mode += "[\u00D7]"
else: else:
payment_mode += "[ ]" payment_mode += "[ ]"
payment_mode += " %s\n" % (m[1]) payment_mode += " %s\n" % (m[1])

View File

@ -1,19 +1,15 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #

View File

@ -1,21 +1,19 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.contrib import admin
# Register your models here. # Register your models here.

View File

@ -1,21 +1,19 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.db import models
# Create your models here. # Create your models here.

View File

@ -1,21 +1,19 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.test import TestCase
# Create your tests here. # Create your tests here.

View File

@ -1,27 +1,23 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.urls import include, path, re_path from django.urls import re_path, path, include
from rest_framework import routers
from api.views import * from api.views import *
from rest_framework import routers
# Router config # Router config
router = routers.DefaultRouter() router = routers.DefaultRouter()

View File

@ -1,30 +1,26 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.core.exceptions import PermissionDenied
from django.db.models.query import QuerySet
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import viewsets
from django.core.exceptions import PermissionDenied
from rest_framework.decorators import action
from django.db.models.query import QuerySet
from core.views import can_edit, can_view from core.views import can_view, can_edit
def check_if(obj, user, test): def check_if(obj, user, test):
@ -68,10 +64,10 @@ class RightModelViewSet(ManageModelMixin, viewsets.ModelViewSet):
from .api import * from .api import *
from .club import *
from .counter import * from .counter import *
from .user import *
from .club import *
from .group import * from .group import *
from .launderette import * from .launderette import *
from .sas import *
from .user import *
from .uv import * from .uv import *
from .sas import *

View File

@ -1,26 +1,22 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from rest_framework.response import Response
from rest_framework.decorators import api_view, renderer_classes from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import StaticHTMLRenderer from rest_framework.renderers import StaticHTMLRenderer
from rest_framework.response import Response
from core.templatetags.renderer import markdown from core.templatetags.renderer import markdown

View File

@ -1,32 +1,30 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.conf import settings from rest_framework.response import Response
from django.core.exceptions import PermissionDenied
from rest_framework import serializers from rest_framework import serializers
from rest_framework.decorators import api_view, renderer_classes from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import StaticHTMLRenderer from rest_framework.renderers import StaticHTMLRenderer
from rest_framework.response import Response
from django.conf import settings
from django.core.exceptions import PermissionDenied
from club.models import Club, Mailing
from api.views import RightModelViewSet from api.views import RightModelViewSet
from club.models import Club, Mailing
class ClubSerializer(serializers.ModelSerializer): class ClubSerializer(serializers.ModelSerializer):

View File

@ -1,29 +1,26 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from rest_framework import serializers from rest_framework import serializers
from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import action
from counter.models import Counter
from api.views import RightModelViewSet from api.views import RightModelViewSet
from counter.models import Counter
class CounterSerializer(serializers.ModelSerializer): class CounterSerializer(serializers.ModelSerializer):

View File

@ -1,28 +1,25 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from rest_framework import serializers from rest_framework import serializers
from api.views import RightModelViewSet
from core.models import RealGroup from core.models import RealGroup
from api.views import RightModelViewSet
class GroupSerializer(serializers.ModelSerializer): class GroupSerializer(serializers.ModelSerializer):
class Meta: class Meta:

View File

@ -1,29 +1,26 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from rest_framework import serializers from rest_framework import serializers
from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import action
from launderette.models import Launderette, Machine, Token
from api.views import RightModelViewSet from api.views import RightModelViewSet
from launderette.models import Launderette, Machine, Token
class LaunderettePlaceSerializer(serializers.ModelSerializer): class LaunderettePlaceSerializer(serializers.ModelSerializer):

View File

@ -1,5 +1,4 @@
from typing import List from typing import List
from rest_framework.decorators import api_view, renderer_classes from rest_framework.decorators import api_view, renderer_classes
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import PermissionDenied
from rest_framework.generics import get_object_or_404 from rest_framework.generics import get_object_or_404
@ -7,8 +6,8 @@ from rest_framework.renderers import JSONRenderer
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from core.models import User
from core.views import can_edit from core.views import can_edit
from core.models import User
from sas.models import Picture from sas.models import Picture

View File

@ -1,31 +1,28 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import datetime import datetime
from rest_framework import serializers from rest_framework import serializers
from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import action
from core.models import User
from api.views import RightModelViewSet from api.views import RightModelViewSet
from core.models import User
class UserSerializer(serializers.ModelSerializer): class UserSerializer(serializers.ModelSerializer):

View File

@ -1,12 +1,11 @@
import json from rest_framework.response import Response
import urllib.request
from django.conf import settings
from django.core.exceptions import PermissionDenied
from rest_framework import serializers
from rest_framework.decorators import api_view, renderer_classes from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import JSONRenderer from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response from django.core.exceptions import PermissionDenied
from django.conf import settings
from rest_framework import serializers
import urllib.request
import json
from pedagogy.views import CanCreateUVFunctionMixin from pedagogy.views import CanCreateUVFunctionMixin

View File

@ -1,19 +1,15 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #

View File

@ -1,21 +1,17 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from ajax_select import make_ajax_form from ajax_select import make_ajax_form
from django.contrib import admin from django.contrib import admin

View File

@ -1,32 +1,40 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file. # - Sli <antoine@bartuccio.fr>
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from ajax_select.fields import AutoCompleteSelectMultipleField
from django import forms
from django.conf import settings from django.conf import settings
from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from club.models import Club, Mailing, MailingSubscription, Membership from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
from club.models import Mailing, MailingSubscription, Club, Membership
from core.models import User from core.models import User
from core.views.forms import SelectDate, TzAwareDateTimeField from core.views.forms import SelectDate, SelectDateTime
from counter.models import Counter from counter.models import Counter
from core.views.forms import TzAwareDateTimeField
class ClubEditForm(forms.ModelForm): class ClubEditForm(forms.ModelForm):

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models
import django.core.validators import django.core.validators
import django.db.models.deletion import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.utils.timezone
from django.db import migrations, models from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,12 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
import re import re
import django.core.validators import django.core.validators
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
from club.models import Club from club.models import Club
from core.operations import PsqlRunOnly from core.operations import PsqlRunOnly
import django.db.models.deletion
def generate_club_pages(apps, schema_editor): def generate_club_pages(apps, schema_editor):

View File

@ -1,10 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
import club.models import club.models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,37 +1,44 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file. # - Sli <antoine@bartuccio.fr>
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from typing import Optional from typing import Optional
from django.conf import settings
from django.core import validators
from django.core.cache import cache from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import models
from django.core.validators import RegexValidator, validate_email from django.core import validators
from django.db import models, transaction from django.conf import settings
from django.db.models import Q from django.db.models import Q
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.db import transaction
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.core.validators import RegexValidator, validate_email
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from core.models import Group, MetaGroup, Notification, Page, RealGroup, SithFile, User from core.models import User, MetaGroup, Group, SithFile, RealGroup, Notification, Page
# Create your models here. # Create your models here.

View File

@ -2,7 +2,7 @@
{% from 'core/macros.jinja' import user_profile_link, paginate %} {% from 'core/macros.jinja' import user_profile_link, paginate %}
{% block content %} {% block content %}
<h3>{% trans %}Sales{% endtrans %}</h3> <h3>{% trans %}Sellings{% endtrans %}</h3>
<form id="form" action="?page=1" method="post"> <form id="form" action="?page=1" method="post">
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}

View File

@ -30,7 +30,7 @@
{% endif %} {% endif %}
</ul> </ul>
{% if object.club_account.exists() %} {% if object.club_account.exists() %}
<h4>{% trans %}Accounting: {% endtrans %}</h4> <h4>{% trans %}Accouting: {% endtrans %}</h4>
<ul> <ul>
{% for ca in object.club_account.all() %} {% for ca in object.club_account.all() %}
<li><a href="{{ url('accounting:club_details', c_account_id=ca.id) }}">{{ ca.get_display_name() }}</a></li> <li><a href="{{ url('accounting:club_details', c_account_id=ca.id) }}">{{ ca.get_display_name() }}</a></li>

View File

@ -1,35 +1,32 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from datetime import timedelta from datetime import timedelta
from django.conf import settings from django.conf import settings
from django.core.cache import cache from django.core.cache import cache
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.utils import timezone, html
from django.utils import timezone from django.utils.timezone import now, localtime
from django.utils.timezone import localtime, now
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.urls import reverse
from django.core.management import call_command
from core.models import User, AnonymousUser
from club.models import Club, Membership, Mailing
from club.forms import MailingForm from club.forms import MailingForm
from club.models import Club, Mailing, Membership
from core.models import AnonymousUser, User
from sith.settings import SITH_BAR_MANAGER, SITH_MAIN_CLUB_ID from sith.settings import SITH_BAR_MANAGER, SITH_MAIN_CLUB_ID
@ -53,7 +50,6 @@ class ClubTest(TestCase):
cls.richard = User.objects.get(username="rbatsbak") cls.richard = User.objects.get(username="rbatsbak")
cls.comptable = User.objects.get(username="comptable") cls.comptable = User.objects.get(username="comptable")
cls.sli = User.objects.get(username="sli") cls.sli = User.objects.get(username="sli")
cls.root = User.objects.get(username="root")
# subscribed users - not initial members # subscribed users - not initial members
cls.krophil = User.objects.get(username="krophil") cls.krophil = User.objects.get(username="krophil")
@ -107,42 +103,45 @@ class MembershipQuerySetTest(ClubTest):
Test that the ongoing queryset method returns the memberships that Test that the ongoing queryset method returns the memberships that
are not ended. are not ended.
""" """
current_members = list(self.club.members.ongoing().order_by("id")) current_members = self.club.members.ongoing()
expected = [ expected = [
self.skia.memberships.get(club=self.club), self.skia.memberships.get(club=self.club),
self.comptable.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club),
self.richard.memberships.get(club=self.club), self.richard.memberships.get(club=self.club),
] ]
expected.sort(key=lambda i: i.id) self.assertEqual(len(current_members), len(expected))
assert current_members == expected for member in current_members:
self.assertIn(member, expected)
def test_board(self): def test_board(self):
""" """
Test that the board queryset method returns the memberships Test that the board queryset method returns the memberships
of user in the club board of user in the club board
""" """
board_members = list(self.club.members.board().order_by("id")) board_members = list(self.club.members.board())
expected = [ expected = [
self.skia.memberships.get(club=self.club), self.skia.memberships.get(club=self.club),
self.comptable.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club),
# sli is no more member, but he was in the board # sli is no more member, but he was in the board
self.sli.memberships.get(club=self.club), self.sli.memberships.get(club=self.club),
] ]
expected.sort(key=lambda i: i.id) self.assertEqual(len(board_members), len(expected))
assert board_members == expected for member in board_members:
self.assertIn(member, expected)
def test_ongoing_board(self): def test_ongoing_board(self):
""" """
Test that combining ongoing and board returns users Test that combining ongoing and board returns users
who are currently board members of the club who are currently board members of the club
""" """
members = list(self.club.members.ongoing().board().order_by("id")) members = list(self.club.members.ongoing().board())
expected = [ expected = [
self.skia.memberships.get(club=self.club), self.skia.memberships.get(club=self.club),
self.comptable.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club),
] ]
expected.sort(key=lambda i: i.id) self.assertEqual(len(members), len(expected))
assert members == expected for member in members:
self.assertIn(member, expected)
def test_update_invalidate_cache(self): def test_update_invalidate_cache(self):
""" """
@ -151,9 +150,8 @@ class MembershipQuerySetTest(ClubTest):
mem_skia = self.skia.memberships.get(club=self.club) mem_skia = self.skia.memberships.get(club=self.club)
cache.set(f"membership_{mem_skia.club_id}_{mem_skia.user_id}", mem_skia) cache.set(f"membership_{mem_skia.club_id}_{mem_skia.user_id}", mem_skia)
self.skia.memberships.update(end_date=localtime(now()).date()) self.skia.memberships.update(end_date=localtime(now()).date())
assert ( self.assertEqual(
cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}") cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}"), "not_member"
== "not_member"
) )
mem_richard = self.richard.memberships.get(club=self.club) mem_richard = self.richard.memberships.get(club=self.club)
@ -162,8 +160,8 @@ class MembershipQuerySetTest(ClubTest):
) )
self.richard.memberships.update(role=5) self.richard.memberships.update(role=5)
new_mem = self.richard.memberships.get(club=self.club) new_mem = self.richard.memberships.get(club=self.club)
assert new_mem != "not_member" self.assertNotEqual(new_mem, "not_member")
assert new_mem.role == 5 self.assertEqual(new_mem.role, 5)
def test_delete_invalidate_cache(self): def test_delete_invalidate_cache(self):
""" """
@ -180,39 +178,40 @@ class MembershipQuerySetTest(ClubTest):
# should delete the subscriptions of skia and comptable # should delete the subscriptions of skia and comptable
self.club.members.ongoing().board().delete() self.club.members.ongoing().board().delete()
assert ( self.assertEqual(
cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}") cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}"), "not_member"
== "not_member"
) )
assert ( self.assertEqual(
cache.get(f"membership_{mem_comptable.club_id}_{mem_comptable.user_id}") cache.get(f"membership_{mem_comptable.club_id}_{mem_comptable.user_id}"),
== "not_member", "not_member",
) )
class ClubModelTest(ClubTest): class ClubModelTest(ClubTest):
def assert_membership_started_today(self, user: User, role: int): def assert_membership_just_started(self, user: User, role: int):
""" """
Assert that the given membership is active and started today Assert that the given membership is active and started today
""" """
membership = user.memberships.ongoing().filter(club=self.club).first() membership = user.memberships.ongoing().filter(club=self.club).first()
assert membership is not None self.assertIsNotNone(membership)
assert localtime(now()).date() == membership.start_date self.assertEqual(localtime(now()).date(), membership.start_date)
assert membership.end_date is None self.assertIsNone(membership.end_date)
assert membership.role == role self.assertEqual(membership.role, role)
assert membership.club.get_membership_for(user) == membership self.assertEqual(membership.club.get_membership_for(user), membership)
member_group = self.club.unix_name + settings.SITH_MEMBER_SUFFIX member_group = self.club.unix_name + settings.SITH_MEMBER_SUFFIX
board_group = self.club.unix_name + settings.SITH_BOARD_SUFFIX board_group = self.club.unix_name + settings.SITH_BOARD_SUFFIX
assert user.is_in_group(name=member_group) self.assertTrue(user.is_in_group(name=member_group))
assert user.is_in_group(name=board_group) self.assertTrue(user.is_in_group(name=board_group))
def assert_membership_ended_today(self, user: User): def assert_membership_just_ended(self, user: User):
""" """
Assert that the given user have a membership which ended today Assert that the given user have a membership which ended today
""" """
today = localtime(now()).date() today = localtime(now()).date()
assert user.memberships.filter(club=self.club, end_date=today).exists() self.assertIsNotNone(
assert self.club.get_membership_for(user) is None user.memberships.filter(club=self.club, end_date=today).first()
)
self.assertIsNone(self.club.get_membership_for(user))
def test_access_unauthorized(self): def test_access_unauthorized(self):
""" """
@ -220,20 +219,20 @@ class ClubModelTest(ClubTest):
cannot see the page cannot see the page
""" """
response = self.client.post(self.members_url) response = self.client.post(self.members_url)
assert response.status_code == 403 self.assertEqual(response.status_code, 403)
self.client.force_login(self.public) self.client.login(username="public", password="plop")
response = self.client.post(self.members_url) response = self.client.post(self.members_url)
assert response.status_code == 403 self.assertEqual(response.status_code, 403)
def test_display(self): def test_display(self):
""" """
Test that a GET request return a page where the requested Test that a GET request return a page where the requested
information are displayed. information are displayed.
""" """
self.client.force_login(self.skia) self.client.login(username=self.skia.username, password="plop")
response = self.client.get(self.members_url) response = self.client.get(self.members_url)
assert response.status_code == 200 self.assertEqual(response.status_code, 200)
expected_html = ( expected_html = (
"<table><thead><tr>" "<table><thead><tr>"
"<td>Utilisateur</td><td>Rôle</td><td>Description</td>" "<td>Utilisateur</td><td>Rôle</td><td>Description</td>"
@ -266,20 +265,20 @@ class ClubModelTest(ClubTest):
""" """
Test that root users can add members to clubs, one at a time Test that root users can add members to clubs, one at a time
""" """
self.client.force_login(self.root) self.client.login(username="root", password="plop")
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users": self.subscriber.id, "role": 3}, {"users": self.subscriber.id, "role": 3},
) )
self.assertRedirects(response, self.members_url) self.assertRedirects(response, self.members_url)
self.subscriber.refresh_from_db() self.subscriber.refresh_from_db()
self.assert_membership_started_today(self.subscriber, role=3) self.assert_membership_just_started(self.subscriber, role=3)
def test_root_add_multiple_club_member(self): def test_root_add_multiple_club_member(self):
""" """
Test that root users can add multiple members at once to clubs Test that root users can add multiple members at once to clubs
""" """
self.client.force_login(self.root) self.client.login(username="root", password="plop")
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{ {
@ -289,36 +288,36 @@ class ClubModelTest(ClubTest):
) )
self.assertRedirects(response, self.members_url) self.assertRedirects(response, self.members_url)
self.subscriber.refresh_from_db() self.subscriber.refresh_from_db()
self.assert_membership_started_today(self.subscriber, role=3) self.assert_membership_just_started(self.subscriber, role=3)
self.assert_membership_started_today(self.krophil, role=3) self.assert_membership_just_started(self.krophil, role=3)
def test_add_unauthorized_members(self): def test_add_unauthorized_members(self):
""" """
Test that users who are not currently subscribed Test that users who are not currently subscribed
cannot be members of clubs. cannot be members of clubs.
""" """
self.client.force_login(self.root) self.client.login(username="root", password="plop")
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users": self.public.id, "role": 1}, {"users": self.public.id, "role": 1},
) )
assert not self.public.memberships.filter(club=self.club).exists() self.assertIsNone(self.public.memberships.filter(club=self.club).first())
assert '<ul class="errorlist"><li>' in response.content.decode() self.assertTrue('<ul class="errorlist"><li>' in str(response.content))
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users": self.old_subscriber.id, "role": 1}, {"users": self.old_subscriber.id, "role": 1},
) )
assert not self.public.memberships.filter(club=self.club).exists() self.assertIsNone(self.public.memberships.filter(club=self.club).first())
assert self.club.get_membership_for(self.public) is None self.assertIsNone(self.club.get_membership_for(self.public))
assert '<ul class="errorlist"><li>' in response.content.decode() self.assertTrue('<ul class="errorlist"><li>' in str(response.content))
def test_add_members_already_members(self): def test_add_members_already_members(self):
""" """
Test that users who are already members of a club Test that users who are already members of a club
cannot be added again to this club cannot be added again to this club
""" """
self.client.force_login(self.root) self.client.login(username="root", password="plop")
current_membership = self.skia.memberships.ongoing().get(club=self.club) current_membership = self.skia.memberships.ongoing().get(club=self.club)
nb_memberships = self.skia.memberships.count() nb_memberships = self.skia.memberships.count()
self.client.post( self.client.post(
@ -326,10 +325,10 @@ class ClubModelTest(ClubTest):
{"users": self.skia.id, "role": current_membership.role + 1}, {"users": self.skia.id, "role": current_membership.role + 1},
) )
self.skia.refresh_from_db() self.skia.refresh_from_db()
assert nb_memberships == self.skia.memberships.count() self.assertEqual(nb_memberships, self.skia.memberships.count())
new_membership = self.skia.memberships.ongoing().get(club=self.club) new_membership = self.skia.memberships.ongoing().get(club=self.club)
assert current_membership == new_membership self.assertEqual(current_membership, new_membership)
assert self.club.get_membership_for(self.skia) == new_membership self.assertEqual(self.club.get_membership_for(self.skia), new_membership)
def test_add_not_existing_users(self): def test_add_not_existing_users(self):
""" """
@ -337,16 +336,15 @@ class ClubModelTest(ClubTest):
If one user in the request is invalid, no membership creation at all If one user in the request is invalid, no membership creation at all
can take place. can take place.
""" """
self.client.force_login(self.root) self.client.login(username="root", password="plop")
nb_memberships = self.club.members.count() nb_memberships = self.club.members.count()
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users": [9999], "role": 1}, {"users": [9999], "role": 1},
) )
assert response.status_code == 200 self.assertContains(response, '<ul class="errorlist"><li>')
assert '<ul class="errorlist"><li>' in response.content.decode()
self.club.refresh_from_db() self.club.refresh_from_db()
assert self.club.members.count() == nb_memberships self.assertEqual(self.club.members.count(), nb_memberships)
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{ {
@ -355,10 +353,9 @@ class ClubModelTest(ClubTest):
"role": 3, "role": 3,
}, },
) )
assert response.status_code == 200 self.assertContains(response, '<ul class="errorlist"><li>')
assert '<ul class="errorlist"><li>' in response.content.decode()
self.club.refresh_from_db() self.club.refresh_from_db()
assert self.club.members.count() == nb_memberships self.assertEqual(self.club.members.count(), nb_memberships)
def test_president_add_members(self): def test_president_add_members(self):
""" """
@ -367,7 +364,7 @@ class ClubModelTest(ClubTest):
president = self.club.members.get(role=10).user president = self.club.members.get(role=10).user
nb_club_membership = self.club.members.count() nb_club_membership = self.club.members.count()
nb_subscriber_memberships = self.subscriber.memberships.count() nb_subscriber_memberships = self.subscriber.memberships.count()
self.client.force_login(president) self.client.login(username=president.username, password="plop")
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users": self.subscriber.id, "role": 9}, {"users": self.subscriber.id, "role": 9},
@ -375,55 +372,56 @@ class ClubModelTest(ClubTest):
self.assertRedirects(response, self.members_url) self.assertRedirects(response, self.members_url)
self.club.refresh_from_db() self.club.refresh_from_db()
self.subscriber.refresh_from_db() self.subscriber.refresh_from_db()
assert self.club.members.count() == nb_club_membership + 1 self.assertEqual(self.club.members.count(), nb_club_membership + 1)
assert self.subscriber.memberships.count() == nb_subscriber_memberships + 1 self.assertEqual(
self.assert_membership_started_today(self.subscriber, role=9) self.subscriber.memberships.count(), nb_subscriber_memberships + 1
)
self.assert_membership_just_started(self.subscriber, role=9)
def test_add_member_greater_role(self): def test_add_member_greater_role(self):
""" """
Test that a member of the club member cannot create Test that a member of the club member cannot create
a membership with a greater role than its own. a membership with a greater role than its own.
""" """
self.client.force_login(self.skia) self.client.login(username=self.skia.username, password="plop")
nb_memberships = self.club.members.count() nb_memberships = self.club.members.count()
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users": self.subscriber.id, "role": 10}, {"users": self.subscriber.id, "role": 10},
) )
assert response.status_code == 200 self.assertEqual(response.status_code, 200)
self.assertInHTML( self.assertInHTML(
"<li>Vous n'avez pas la permission de faire cela</li>", "<li>Vous n'avez pas la permission de faire cela</li>",
response.content.decode(), response.content.decode(),
) )
self.club.refresh_from_db() self.club.refresh_from_db()
assert nb_memberships == self.club.members.count() self.assertEqual(nb_memberships, self.club.members.count())
assert not self.subscriber.memberships.filter(club=self.club).exists() self.assertIsNone(self.subscriber.memberships.filter(club=self.club).first())
def test_add_member_without_role(self): def test_add_member_without_role(self):
""" """
Test that trying to add members without specifying their role fails Test that trying to add members without specifying their role fails
""" """
self.client.force_login(self.root) self.client.login(username="root", password="plop")
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users": self.subscriber.id, "start_date": "12/06/2016"}, {"users": self.subscriber.id, "start_date": "12/06/2016"},
) )
assert ( self.assertTrue(
'<ul class="errorlist"><li>Vous devez choisir un r' '<ul class="errorlist"><li>Vous devez choisir un r' in str(response.content)
in response.content.decode()
) )
def test_end_membership_self(self): def test_end_membership_self(self):
""" """
Test that a member can end its own membership Test that a member can end its own membership
""" """
self.client.force_login(self.skia) self.client.login(username="skia", password="plop")
self.client.post( self.client.post(
self.members_url, self.members_url,
{"users_old": self.skia.id}, {"users_old": self.skia.id},
) )
self.skia.refresh_from_db() self.skia.refresh_from_db()
self.assert_membership_ended_today(self.skia) self.assert_membership_just_ended(self.skia)
def test_end_membership_lower_role(self): def test_end_membership_lower_role(self):
""" """
@ -431,14 +429,14 @@ class ClubModelTest(ClubTest):
of users with lower roles of users with lower roles
""" """
# remainder : skia has role 3, comptable has role 10, richard has role 1 # remainder : skia has role 3, comptable has role 10, richard has role 1
self.client.force_login(self.skia) self.client.login(username=self.skia.username, password="plop")
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users_old": self.richard.id}, {"users_old": self.richard.id},
) )
self.assertRedirects(response, self.members_url) self.assertRedirects(response, self.members_url)
self.club.refresh_from_db() self.club.refresh_from_db()
self.assert_membership_ended_today(self.richard) self.assert_membership_just_ended(self.richard)
def test_end_membership_higher_role(self): def test_end_membership_higher_role(self):
""" """
@ -446,18 +444,18 @@ class ClubModelTest(ClubTest):
of users with higher roles of users with higher roles
""" """
membership = self.comptable.memberships.filter(club=self.club).first() membership = self.comptable.memberships.filter(club=self.club).first()
self.client.force_login(self.skia) self.client.login(username=self.skia.username, password="plop")
self.client.post( self.client.post(
self.members_url, self.members_url,
{"users_old": self.comptable.id}, {"users_old": self.comptable.id},
) )
self.club.refresh_from_db() self.club.refresh_from_db()
new_membership = self.club.get_membership_for(self.comptable) new_membership = self.club.get_membership_for(self.comptable)
assert new_membership is not None self.assertIsNotNone(new_membership)
assert new_membership == membership self.assertEqual(new_membership, membership)
membership = self.comptable.memberships.filter(club=self.club).first() membership = self.comptable.memberships.filter(club=self.club).first()
assert membership.end_date is None self.assertIsNone(membership.end_date)
def test_end_membership_as_main_club_board(self): def test_end_membership_as_main_club_board(self):
""" """
@ -469,29 +467,29 @@ class ClubModelTest(ClubTest):
Membership.objects.create(club=self.ae, user=self.subscriber, role=3) Membership.objects.create(club=self.ae, user=self.subscriber, role=3)
nb_memberships = self.club.members.count() nb_memberships = self.club.members.count()
self.client.force_login(self.subscriber) self.client.login(username=self.subscriber.username, password="plop")
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users_old": self.comptable.id}, {"users_old": self.comptable.id},
) )
self.assertRedirects(response, self.members_url) self.assertRedirects(response, self.members_url)
self.assert_membership_ended_today(self.comptable) self.assert_membership_just_ended(self.comptable)
assert self.club.members.ongoing().count() == nb_memberships - 1 self.assertEqual(self.club.members.ongoing().count(), nb_memberships - 1)
def test_end_membership_as_root(self): def test_end_membership_as_root(self):
""" """
Test that root users can end the membership of anyone Test that root users can end the membership of anyone
""" """
nb_memberships = self.club.members.count() nb_memberships = self.club.members.count()
self.client.force_login(self.root) self.client.login(username="root", password="plop")
response = self.client.post( response = self.client.post(
self.members_url, self.members_url,
{"users_old": [self.comptable.id]}, {"users_old": [self.comptable.id]},
) )
self.assertRedirects(response, self.members_url) self.assertRedirects(response, self.members_url)
self.assert_membership_ended_today(self.comptable) self.assert_membership_just_ended(self.comptable)
assert self.club.members.ongoing().count() == nb_memberships - 1 self.assertEqual(self.club.members.ongoing().count(), nb_memberships - 1)
assert self.club.members.count() == nb_memberships self.assertEqual(self.club.members.count(), nb_memberships)
def test_end_membership_as_foreigner(self): def test_end_membership_as_foreigner(self):
""" """
@ -499,15 +497,16 @@ class ClubModelTest(ClubTest):
""" """
nb_memberships = self.club.members.count() nb_memberships = self.club.members.count()
membership = self.richard.memberships.filter(club=self.club).first() membership = self.richard.memberships.filter(club=self.club).first()
self.client.force_login(self.subscriber) self.client.login(username="subscriber", password="root")
self.client.post( self.client.post(
self.members_url, self.members_url,
{"users_old": [self.richard.id]}, {"users_old": [self.richard.id]},
) )
# nothing should have changed # nothing should have changed
new_mem = self.club.get_membership_for(self.richard) new_mem = self.club.get_membership_for(self.richard)
assert self.club.members.count() == nb_memberships self.assertIsNotNone(new_mem)
assert membership == new_mem self.assertEqual(self.club.members.count(), nb_memberships)
self.assertEqual(membership, new_mem)
def test_delete_remove_from_meta_group(self): def test_delete_remove_from_meta_group(self):
""" """
@ -520,7 +519,7 @@ class ClubModelTest(ClubTest):
self.club.delete() self.club.delete()
for user in users: for user in users:
assert not user.is_in_group(name=meta_group) self.assertFalse(user.is_in_group(name=meta_group))
def test_add_to_meta_group(self): def test_add_to_meta_group(self):
""" """
@ -528,11 +527,11 @@ class ClubModelTest(ClubTest):
""" """
group_members = self.club.unix_name + settings.SITH_MEMBER_SUFFIX group_members = self.club.unix_name + settings.SITH_MEMBER_SUFFIX
board_members = self.club.unix_name + settings.SITH_BOARD_SUFFIX board_members = self.club.unix_name + settings.SITH_BOARD_SUFFIX
assert not self.subscriber.is_in_group(name=group_members) self.assertFalse(self.subscriber.is_in_group(name=group_members))
assert not self.subscriber.is_in_group(name=board_members) self.assertFalse(self.subscriber.is_in_group(name=board_members))
Membership.objects.create(club=self.club, user=self.subscriber, role=3) Membership.objects.create(club=self.club, user=self.subscriber, role=3)
assert self.subscriber.is_in_group(name=group_members) self.assertTrue(self.subscriber.is_in_group(name=group_members))
assert self.subscriber.is_in_group(name=board_members) self.assertTrue(self.subscriber.is_in_group(name=board_members))
def test_remove_from_meta_group(self): def test_remove_from_meta_group(self):
""" """
@ -540,24 +539,24 @@ class ClubModelTest(ClubTest):
""" """
group_members = self.club.unix_name + settings.SITH_MEMBER_SUFFIX group_members = self.club.unix_name + settings.SITH_MEMBER_SUFFIX
board_members = self.club.unix_name + settings.SITH_BOARD_SUFFIX board_members = self.club.unix_name + settings.SITH_BOARD_SUFFIX
assert self.comptable.is_in_group(name=group_members) self.assertTrue(self.comptable.is_in_group(name=group_members))
assert self.comptable.is_in_group(name=board_members) self.assertTrue(self.comptable.is_in_group(name=board_members))
self.comptable.memberships.update(end_date=localtime(now())) self.comptable.memberships.update(end_date=localtime(now()))
assert not self.comptable.is_in_group(name=group_members) self.assertFalse(self.comptable.is_in_group(name=group_members))
assert not self.comptable.is_in_group(name=board_members) self.assertFalse(self.comptable.is_in_group(name=board_members))
def test_club_owner(self): def test_club_owner(self):
""" """
Test that a club is owned only by board members of the main club Test that a club is owned only by board members of the main club
""" """
anonymous = AnonymousUser() anonymous = AnonymousUser()
assert not self.club.is_owned_by(anonymous) self.assertFalse(self.club.is_owned_by(anonymous))
assert not self.club.is_owned_by(self.subscriber) self.assertFalse(self.club.is_owned_by(self.subscriber))
# make sli a board member # make sli a board member
self.sli.memberships.all().delete() self.sli.memberships.all().delete()
Membership(club=self.ae, user=self.sli, role=3).save() Membership(club=self.ae, user=self.sli, role=3).save()
assert self.club.is_owned_by(self.sli) self.assertTrue(self.club.is_owned_by(self.sli))
class MailingFormTest(TestCase): class MailingFormTest(TestCase):
@ -565,13 +564,11 @@ class MailingFormTest(TestCase):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
cls.skia = User.objects.get(username="skia") cls.skia = User.objects.filter(username="skia").first()
cls.rbatsbak = User.objects.get(username="rbatsbak") cls.rbatsbak = User.objects.filter(username="rbatsbak").first()
cls.krophil = User.objects.get(username="krophil") cls.krophil = User.objects.filter(username="krophil").first()
cls.comunity = User.objects.get(username="comunity") cls.comunity = User.objects.filter(username="comunity").first()
cls.root = User.objects.get(username="root") cls.bdf = Club.objects.filter(unix_name=SITH_BAR_MANAGER["unix_name"]).first()
cls.bdf = Club.objects.get(unix_name=SITH_BAR_MANAGER["unix_name"])
cls.mail_url = reverse("club:mailing", kwargs={"club_id": cls.bdf.id})
def setUp(self): def setUp(self):
Membership( Membership(
@ -583,125 +580,134 @@ class MailingFormTest(TestCase):
def test_mailing_list_add_no_moderation(self): def test_mailing_list_add_no_moderation(self):
# Test with Communication admin # Test with Communication admin
self.client.force_login(self.comunity) self.client.login(username="comunity", password="plop")
response = self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "foyer"}, {"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "foyer"},
) )
self.assertRedirects(response, self.mail_url) response = self.client.get(
response = self.client.get(self.mail_url) reverse("club:mailing", kwargs={"club_id": self.bdf.id})
assert response.status_code == 200 )
assert "Liste de diffusion foyer@utbm.fr" in response.content.decode() self.assertContains(response, text="Liste de diffusion foyer@utbm.fr")
# Test with Root # Test with Root
self.client.force_login(self.root) self.client.login(username="root", password="plop")
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"}, {"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"},
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
assert "Liste de diffusion mde@utbm.fr" in response.content.decode() )
self.assertContains(response, text="Liste de diffusion mde@utbm.fr")
def test_mailing_list_add_moderation(self): def test_mailing_list_add_moderation(self):
self.client.force_login(self.rbatsbak) self.client.login(username="rbatsbak", password="plop")
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"}, {"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"},
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
content = response.content.decode() )
assert "Liste de diffusion mde@utbm.fr" not in content self.assertNotContains(response, text="Liste de diffusion mde@utbm.fr")
assert "<p>Listes de diffusions en attente de modération</p>" in content self.assertContains(
assert "<li>mde@utbm.fr" in content response, text="<p>Listes de diffusions en attente de modération</p>"
)
self.assertContains(response, "<li>mde@utbm.fr")
def test_mailing_list_forbidden(self): def test_mailing_list_forbidden(self):
# With anonymous user # With anonymous user
response = self.client.get(self.mail_url) response = self.client.get(
reverse("club:mailing", kwargs={"club_id": self.bdf.id})
)
self.assertContains(response, "", status_code=403) self.assertContains(response, "", status_code=403)
# With user not in club # With user not in club
self.client.force_login(self.krophil) self.client.login(username="krophil", password="plop")
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 403 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
)
self.assertContains(response, "", status_code=403)
def test_add_new_subscription_fail_not_moderated(self): def test_add_new_subscription_fail_not_moderated(self):
self.client.force_login(self.rbatsbak) self.client.login(username="rbatsbak", password="plop")
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"}, {"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"},
) )
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": self.skia.id, "subscription_users": self.skia.id,
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
assert "skia@git.an" not in response.content.decode() )
self.assertNotContains(response, "skia@git.an")
def test_add_new_subscription_success(self): def test_add_new_subscription_success(self):
# Prepare mailing list # Prepare mailing list
self.client.force_login(self.comunity) self.client.login(username="comunity", password="plop")
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"}, {"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"},
) )
# Add single user # Add single user
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": self.skia.id, "subscription_users": self.skia.id,
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
assert "skia@git.an" in response.content.decode() )
self.assertContains(response, "skia@git.an")
# Add multiple users # Add multiple users
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": "|%s|%s|" % (self.comunity.id, self.rbatsbak.id), "subscription_users": "|%s|%s|" % (self.comunity.id, self.rbatsbak.id),
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
content = response.content.decode() )
assert "richard@git.an" in content self.assertContains(response, "richard@git.an")
assert "comunity@git.an" in content self.assertContains(response, "comunity@git.an")
assert "skia@git.an" in content self.assertContains(response, "skia@git.an")
# Add arbitrary email # Add arbitrary email
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_email": "arbitrary@git.an", "subscription_email": "arbitrary@git.an",
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
content = response.content.decode() )
assert "richard@git.an" in content self.assertContains(response, "richard@git.an")
assert "comunity@git.an" in content self.assertContains(response, "comunity@git.an")
assert "skia@git.an" in content self.assertContains(response, "skia@git.an")
assert "arbitrary@git.an" in content self.assertContains(response, "arbitrary@git.an")
# Add user and arbitrary email # Add user and arbitrary email
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_email": "more.arbitrary@git.an", "subscription_email": "more.arbitrary@git.an",
@ -709,61 +715,57 @@ class MailingFormTest(TestCase):
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
content = response.content.decode() )
assert "richard@git.an" in content self.assertContains(response, "richard@git.an")
assert "comunity@git.an" in content self.assertContains(response, "comunity@git.an")
assert "skia@git.an" in content self.assertContains(response, "skia@git.an")
assert "arbitrary@git.an" in content self.assertContains(response, "arbitrary@git.an")
assert "more.arbitrary@git.an" in content self.assertContains(response, "more.arbitrary@git.an")
assert "krophil@git.an" in content self.assertContains(response, "krophil@git.an")
def test_add_new_subscription_fail_form_errors(self): def test_add_new_subscription_fail_form_errors(self):
# Prepare mailing list # Prepare mailing list
self.client.force_login(self.comunity) self.client.login(username="comunity", password="plop")
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"}, {"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"},
) )
# Neither email or email is specified # Neither email or email is specified
response = self.client.post( response = self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
assert response.status_code self.assertContains(
self.assertInHTML( response, text=_("You must specify at least an user or an email address")
_("You must specify at least an user or an email address"),
response.content.decode(),
) )
# No mailing specified # No mailing specified
response = self.client.post( response = self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": self.krophil.id, "subscription_users": self.krophil.id,
}, },
) )
assert response.status_code == 200 self.assertContains(response, text=_("This field is required"))
assert _("This field is required") in response.content.decode()
# One of the selected users doesn't exist # One of the selected users doesn't exist
response = self.client.post( response = self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": "|789|", "subscription_users": "|789|",
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
assert response.status_code == 200 self.assertContains(
self.assertInHTML( response, text=html.escape(_("One of the selected users doesn't exist"))
_("One of the selected users doesn't exist"), response.content.decode()
) )
# An user has no email adress # An user has no email adress
@ -771,17 +773,18 @@ class MailingFormTest(TestCase):
self.krophil.save() self.krophil.save()
response = self.client.post( response = self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": self.krophil.id, "subscription_users": self.krophil.id,
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
assert response.status_code == 200 self.assertContains(
self.assertInHTML( response,
_("One of the selected users doesn't have an email address"), text=html.escape(
response.content.decode(), _("One of the selected users doesn't have an email address")
),
) )
self.krophil.email = "krophil@git.an" self.krophil.email = "krophil@git.an"
@ -790,7 +793,7 @@ class MailingFormTest(TestCase):
# An user is added twice # An user is added twice
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": self.krophil.id, "subscription_users": self.krophil.id,
@ -799,29 +802,28 @@ class MailingFormTest(TestCase):
) )
response = self.client.post( response = self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": self.krophil.id, "subscription_users": self.krophil.id,
"subscription_mailing": Mailing.objects.get(email="mde").id, "subscription_mailing": Mailing.objects.get(email="mde").id,
}, },
) )
assert response.status_code == 200 self.assertContains(
self.assertInHTML( response,
_("This email is already suscribed in this mailing"), text=html.escape(_("This email is already suscribed in this mailing")),
response.content.decode(),
) )
def test_remove_subscription_success(self): def test_remove_subscription_success(self):
# Prepare mailing list # Prepare mailing list
self.client.force_login(self.comunity) self.client.login(username="comunity", password="plop")
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"}, {"action": MailingForm.ACTION_NEW_MAILING, "mailing_email": "mde"},
) )
mde = Mailing.objects.get(email="mde") mde = Mailing.objects.get(email="mde")
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_NEW_SUBSCRIPTION, "action": MailingForm.ACTION_NEW_SUBSCRIPTION,
"subscription_users": "|%s|%s|%s|" "subscription_users": "|%s|%s|%s|"
@ -830,36 +832,37 @@ class MailingFormTest(TestCase):
}, },
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
content = response.content.decode() )
assert "comunity@git.an" in content self.assertContains(response, "comunity@git.an")
assert "richard@git.an" in content self.assertContains(response, "richard@git.an")
assert "krophil@git.an" in content self.assertContains(response, "krophil@git.an")
# Delete one user # Delete one user
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_REMOVE_SUBSCRIPTION, "action": MailingForm.ACTION_REMOVE_SUBSCRIPTION,
"removal_%d" % mde.id: mde.subscriptions.get(user=self.krophil).id, "removal_%d" % mde.id: mde.subscriptions.get(user=self.krophil).id,
}, },
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
content = response.content.decode() )
assert "comunity@git.an" in content self.assertContains(response, "comunity@git.an")
assert "richard@git.an" in content self.assertContains(response, "richard@git.an")
assert "krophil@git.an" not in content self.assertNotContains(response, "krophil@git.an")
# Delete multiple users # Delete multiple users
self.client.post( self.client.post(
self.mail_url, reverse("club:mailing", kwargs={"club_id": self.bdf.id}),
{ {
"action": MailingForm.ACTION_REMOVE_SUBSCRIPTION, "action": MailingForm.ACTION_REMOVE_SUBSCRIPTION,
"removal_%d" % mde.id: [ "removal_%d"
% mde.id: [
user.id user.id
for user in mde.subscriptions.filter( for user in mde.subscriptions.filter(
user__in=[self.rbatsbak, self.comunity] user__in=[self.rbatsbak, self.comunity]
@ -867,13 +870,13 @@ class MailingFormTest(TestCase):
], ],
}, },
) )
response = self.client.get(self.mail_url) response = self.client.get(
assert response.status_code == 200 reverse("club:mailing", kwargs={"club_id": self.bdf.id})
content = response.content.decode() )
assert "comunity@git.an" not in content self.assertNotContains(response, "comunity@git.an")
assert "richard@git.an" not in content self.assertNotContains(response, "richard@git.an")
assert "krophil@git.an" not in content self.assertNotContains(response, "krophil@git.an")
class ClubSellingViewTest(TestCase): class ClubSellingViewTest(TestCase):
@ -881,17 +884,15 @@ class ClubSellingViewTest(TestCase):
Perform basics tests to ensure that the page is available Perform basics tests to ensure that the page is available
""" """
@classmethod def setUp(self):
def setUpTestData(cls): self.ae = Club.objects.filter(unix_name="ae").first()
cls.ae = Club.objects.get(unix_name="ae")
cls.skia = User.objects.get(username="skia")
def test_page_not_internal_error(self): def test_page_not_internal_error(self):
""" """
Test that the page does not return and internal error Test that the page does not return and internal error
""" """
self.client.force_login(self.skia) self.client.login(username="skia", password="plop")
response = self.client.get( response = self.client.get(
reverse("club:club_sellings", kwargs={"club_id": self.ae.id}) reverse("club:club_sellings", kwargs={"club_id": self.ae.id})
) )
assert response.status_code == 200 self.assertFalse(response.status_code == 500)

View File

@ -1,21 +1,26 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file. # - Sli <antoine@bartuccio.fr>
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.urls import path from django.urls import path

View File

@ -1,63 +1,76 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file. # - Sli <antoine@bartuccio.fr>
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import csv import csv
from django.conf import settings from django.conf import settings
from django.core.exceptions import NON_FIELD_ERRORS, PermissionDenied, ValidationError from django import forms
from django.core.paginator import InvalidPage, Paginator from django.views.generic import ListView, DetailView, TemplateView, View
from django.db.models import Sum from django.views.generic.edit import DeleteView
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import UpdateView, CreateView
from django.http import ( from django.http import (
Http404,
HttpResponseRedirect, HttpResponseRedirect,
HttpResponse,
Http404,
StreamingHttpResponse, StreamingHttpResponse,
) )
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext as _t
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView, TemplateView, View from django.utils.translation import gettext as _t
from django.views.generic.edit import CreateView, DeleteView, UpdateView from django.core.exceptions import PermissionDenied, ValidationError, NON_FIELD_ERRORS
from django.core.paginator import Paginator, InvalidPage
from django.shortcuts import get_object_or_404, redirect
from django.db.models import Sum
from club.forms import ClubEditForm, ClubMemberForm, MailingForm, SellingsForm
from club.models import Club, Mailing, MailingSubscription, Membership
from com.views import (
PosterCreateBaseView,
PosterDeleteBaseView,
PosterEditBaseView,
PosterListBaseView,
)
from core.models import PageRev
from core.views import ( from core.views import (
CanCreateMixin, CanCreateMixin,
CanViewMixin,
CanEditMixin, CanEditMixin,
CanEditPropMixin, CanEditPropMixin,
CanViewMixin,
DetailFormView,
PageEditViewBase,
TabedViewMixin,
UserIsRootMixin, UserIsRootMixin,
TabedViewMixin,
PageEditViewBase,
DetailFormView,
) )
from core.models import PageRev
from counter.models import Selling from counter.models import Selling
from com.views import (
PosterListBaseView,
PosterCreateBaseView,
PosterEditBaseView,
PosterDeleteBaseView,
)
from club.models import Club, Membership, Mailing, MailingSubscription
from club.forms import MailingForm, ClubEditForm, ClubMemberForm, SellingsForm
class ClubTabsMixin(TabedViewMixin): class ClubTabsMixin(TabedViewMixin):
def get_tabs_title(self): def get_tabs_title(self):
@ -598,7 +611,7 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
} }
return kwargs return kwargs
def add_new_mailing(self, cleaned_data) -> ValidationError | None: def add_new_mailing(self, cleaned_data) -> ValidationError:
""" """
Create a new mailing list from the form Create a new mailing list from the form
""" """
@ -615,7 +628,7 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
mailing.save() mailing.save()
return None return None
def add_new_subscription(self, cleaned_data) -> ValidationError | None: def add_new_subscription(self, cleaned_data) -> ValidationError:
""" """
Add mailing subscriptions for each user given and/or for the specified email in form Add mailing subscriptions for each user given and/or for the specified email in form
""" """

View File

@ -1,19 +1,15 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #

View File

@ -1,21 +1,17 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from ajax_select import make_ajax_form from ajax_select import make_ajax_form
from django.contrib import admin from django.contrib import admin

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,10 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion from django.db import migrations, models
import django.utils.timezone import django.utils.timezone
from django.conf import settings from django.conf import settings
from django.db import migrations, models import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,37 +1,44 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file. # - Sli <antoine@bartuccio.fr>
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.conf import settings from django.shortcuts import render
from django.core.exceptions import ValidationError
from django.core.mail import EmailMultiAlternatives
from django.db import models, transaction from django.db import models, transaction
from django.db.models import Q from django.db.models import Q
from django.shortcuts import render
from django.templatetags.static import static
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.urls import reverse
from django.conf import settings
from django.templatetags.static import static
from django.core.mail import EmailMultiAlternatives
from django.core.exceptions import ValidationError
from django.utils import timezone
from club.models import Club
from core import utils from core import utils
from core.models import Notification, Preferences, RealGroup, User from core.models import User, Preferences, RealGroup, Notification, SithFile
from club.models import Club
class Sith(models.Model): class Sith(models.Model):

View File

@ -39,7 +39,7 @@
<p> <a href="{{ url('com:news_moderate', news_id=news.id) }}">{% trans %}Moderate{% endtrans %}</a></p> <p> <a href="{{ url('com:news_moderate', news_id=news.id) }}">{% trans %}Moderate{% endtrans %}</a></p>
{% endif %} {% endif %}
{% if user.can_edit(news) %} {% if user.can_edit(news) %}
<p> <a href="{{ url('com:news_edit', news_id=news.id) }}">{% trans %}Edit (will be moderated again){% endtrans %}</a></p> <p> <a href="{{ url('com:news_edit', news_id=news.id) }}">{% trans %}Edit (will be remoderated){% endtrans %}</a></p>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -1,69 +1,63 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import pytest
from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase from django.test import TestCase
from django.conf import settings
from django.urls import reverse from django.urls import reverse
from django.core.management import call_command
from django.utils import html from django.utils import html
from django.utils.timezone import localtime, now from django.utils.timezone import localtime, now
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from club.models import Club, Membership from club.models import Club, Membership
from com.models import News, Poster, Sith, Weekmail, WeekmailArticle from com.models import Sith, News, Weekmail, WeekmailArticle, Poster
from core.models import AnonymousUser, RealGroup, User from core.models import User, RealGroup, AnonymousUser
@pytest.fixture() class ComAlertTest(TestCase):
def user_community(): def test_page_is_working(self):
return User.objects.get(username="comunity") self.client.login(username="comunity", password="plop")
response = self.client.get(reverse("com:alert_edit"))
self.assertNotEqual(response.status_code, 500)
self.assertEqual(response.status_code, 200)
@pytest.mark.django_db class ComInfoTest(TestCase):
@pytest.mark.parametrize( def test_page_is_working(self):
"url", self.client.login(username="comunity", password="plop")
[ response = self.client.get(reverse("com:info_edit"))
reverse("com:alert_edit"), self.assertNotEqual(response.status_code, 500)
reverse("com:info_edit"), self.assertEqual(response.status_code, 200)
],
)
def test_com_page_is_working(client, url, user_community):
client.force_login(user_community)
response = client.get(url)
assert response.status_code == 200
class ComTest(TestCase): class ComTest(TestCase):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
cls.skia = User.objects.get(username="skia") cls.skia = User.objects.filter(username="skia").first()
cls.com_group = RealGroup.objects.filter( cls.com_group = RealGroup.objects.filter(
id=settings.SITH_GROUP_COM_ADMIN_ID id=settings.SITH_GROUP_COM_ADMIN_ID
).first() ).first()
cls.skia.groups.set([cls.com_group]) cls.skia.groups.set([cls.com_group])
cls.skia.save()
def setUp(self): def setUp(self):
self.client.force_login(self.skia) self.client.login(username=self.skia.username, password="plop")
def test_alert_msg(self): def test_alert_msg(self):
self.client.post( response = self.client.post(
reverse("com:alert_edit"), reverse("com:alert_edit"),
{ {
"alert_msg": """ "alert_msg": """
@ -74,6 +68,7 @@ class ComTest(TestCase):
}, },
) )
r = self.client.get(reverse("core:index")) r = self.client.get(reverse("core:index"))
self.assertTrue(r.status_code == 200)
self.assertContains( self.assertContains(
r, r,
"""<div id="alert_box"> """<div id="alert_box">
@ -82,7 +77,7 @@ class ComTest(TestCase):
) )
def test_info_msg(self): def test_info_msg(self):
self.client.post( response = self.client.post(
reverse("com:info_edit"), reverse("com:info_edit"),
{ {
"info_msg": """ "info_msg": """
@ -91,6 +86,7 @@ class ComTest(TestCase):
}, },
) )
r = self.client.get(reverse("core:index")) r = self.client.get(reverse("core:index"))
self.assertTrue(r.status_code == 200)
self.assertContains( self.assertContains(
r, r,
"""<div id="info_box"> """<div id="info_box">
@ -98,7 +94,7 @@ class ComTest(TestCase):
) )
def test_birthday_non_subscribed_user(self): def test_birthday_non_subscribed_user(self):
self.client.force_login(User.objects.get(username="guy")) self.client.login(username="guy", password="plop")
response = self.client.get(reverse("core:index")) response = self.client.get(reverse("core:index"))
self.assertContains( self.assertContains(
response, response,
@ -127,13 +123,13 @@ class SithTest(TestCase):
sith: Sith = Sith.objects.first() sith: Sith = Sith.objects.first()
com_admin = User.objects.get(username="comunity") com_admin = User.objects.get(username="comunity")
assert sith.is_owned_by(com_admin) self.assertTrue(sith.is_owned_by(com_admin))
anonymous = AnonymousUser() anonymous = AnonymousUser()
assert not sith.is_owned_by(anonymous) self.assertFalse(sith.is_owned_by(anonymous))
sli = User.objects.get(username="sli") sli = User.objects.get(username="sli")
assert not sith.is_owned_by(sli) self.assertFalse(sith.is_owned_by(sli))
class NewsTest(TestCase): class NewsTest(TestCase):
@ -158,37 +154,10 @@ class NewsTest(TestCase):
or by their author but nobody else or by their author but nobody else
""" """
assert self.new.is_owned_by(self.com_admin) self.assertTrue(self.new.is_owned_by(self.com_admin))
assert self.new.is_owned_by(self.author) self.assertTrue(self.new.is_owned_by(self.author))
assert not self.new.is_owned_by(self.anonymous) self.assertFalse(self.new.is_owned_by(self.anonymous))
assert not self.new.is_owned_by(self.sli) self.assertFalse(self.new.is_owned_by(self.sli))
def test_news_viewer(self):
"""
Test that moderated news can be viewed by anyone
and not moderated news only by com admins
"""
# by default a news isn't moderated
assert self.new.can_be_viewed_by(self.com_admin)
assert not self.new.can_be_viewed_by(self.sli)
assert not self.new.can_be_viewed_by(self.anonymous)
assert not self.new.can_be_viewed_by(self.author)
self.new.is_moderated = True
self.new.save()
assert self.new.can_be_viewed_by(self.com_admin)
assert self.new.can_be_viewed_by(self.sli)
assert self.new.can_be_viewed_by(self.anonymous)
assert self.new.can_be_viewed_by(self.author)
def test_news_editor(self):
"""
Test that only com admins can edit news
"""
assert self.new.can_be_edited_by(self.com_admin)
assert not self.new.can_be_edited_by(self.sli)
assert not self.new.can_be_edited_by(self.anonymous)
assert not self.new.can_be_edited_by(self.author)
class WeekmailArticleTest(TestCase): class WeekmailArticleTest(TestCase):
@ -211,10 +180,10 @@ class WeekmailArticleTest(TestCase):
""" """
Test that weekmails are owned only by com admins Test that weekmails are owned only by com admins
""" """
assert self.article.is_owned_by(self.com_admin) self.assertTrue(self.article.is_owned_by(self.com_admin))
assert not self.article.is_owned_by(self.author) self.assertFalse(self.article.is_owned_by(self.author))
assert not self.article.is_owned_by(self.anonymous) self.assertFalse(self.article.is_owned_by(self.anonymous))
assert not self.article.is_owned_by(self.sli) self.assertFalse(self.article.is_owned_by(self.sli))
class PosterTest(TestCase): class PosterTest(TestCase):
@ -237,8 +206,8 @@ class PosterTest(TestCase):
""" """
Test that poster are owned by com admins and board members in clubs Test that poster are owned by com admins and board members in clubs
""" """
assert self.poster.is_owned_by(self.com_admin) self.assertTrue(self.poster.is_owned_by(self.com_admin))
assert not self.poster.is_owned_by(self.anonymous) self.assertFalse(self.poster.is_owned_by(self.anonymous))
assert not self.poster.is_owned_by(self.susbcriber) self.assertFalse(self.poster.is_owned_by(self.susbcriber))
assert self.poster.is_owned_by(self.sli) self.assertTrue(self.poster.is_owned_by(self.sli))

View File

@ -1,21 +1,17 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.urls import path from django.urls import path

View File

@ -1,52 +1,60 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file. # - Sli <antoine@bartuccio.fr>
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE, # You should have received a copy of the GNU General Public License along with
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old # this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# OR WITHIN THE LOCAL FILE "LICENSE.old" # Place - Suite 330, Boston, MA 02111-1307, USA.
# #
#
from django.shortcuts import redirect, get_object_or_404
from django.http import HttpResponseRedirect
from django.views.generic import ListView, DetailView, View
from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.views.generic.detail import SingleObjectMixin
from django.utils.translation import gettext_lazy as _
from django.urls import reverse, reverse_lazy
from django.core.exceptions import ValidationError
from django.utils import timezone
from django.conf import settings
from django.db.models import Max
from django.forms.models import modelform_factory
from django.core.exceptions import PermissionDenied
from django import forms
from datetime import timedelta from datetime import timedelta
from smtplib import SMTPRecipientsRefused from smtplib import SMTPRecipientsRefused
from django import forms from com.models import Sith, News, NewsDate, Weekmail, WeekmailArticle, Screen, Poster
from django.conf import settings
from django.core.exceptions import PermissionDenied, ValidationError
from django.db.models import Max
from django.forms.models import modelform_factory
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView, View
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from club.models import Club, Mailing
from com.models import News, NewsDate, Poster, Screen, Sith, Weekmail, WeekmailArticle
from core.models import Notification, RealGroup, User
from core.views import ( from core.views import (
CanCreateMixin, CanViewMixin,
CanEditMixin, CanEditMixin,
CanEditPropMixin, CanEditPropMixin,
CanViewMixin,
QuickNotifMixin,
TabedViewMixin, TabedViewMixin,
CanCreateMixin,
QuickNotifMixin,
) )
from core.views.forms import MarkdownInput, TzAwareDateTimeField from core.views.forms import SelectDateTime, MarkdownInput
from core.models import Notification, RealGroup, User
from club.models import Club, Mailing
from core.views.forms import TzAwareDateTimeField
# Sith object # Sith object

View File

@ -1,14 +0,0 @@
import pytest
from django.core.management import call_command
from django.utils.translation import activate
@pytest.fixture(scope="session")
def django_db_setup(django_db_setup, django_db_blocker):
with django_db_blocker.unblock():
call_command("setup")
@pytest.fixture(scope="session", autouse=True)
def set_default_language():
activate("fr")

View File

@ -1,19 +1,15 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #

View File

@ -1,29 +1,25 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from ajax_select import make_ajax_form
from django.contrib import admin from django.contrib import admin
from ajax_select import make_ajax_form
from core.models import User, Page, RealGroup, MetaGroup, SithFile
from django.contrib.auth.models import Group as AuthGroup from django.contrib.auth.models import Group as AuthGroup
from haystack.admin import SearchModelAdmin from haystack.admin import SearchModelAdmin
from core.models import MetaGroup, Page, RealGroup, SithFile, User
admin.site.unregister(AuthGroup) admin.site.unregister(AuthGroup)
admin.site.register(MetaGroup) admin.site.register(MetaGroup)

View File

@ -1,21 +1,25 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import sys import sys
@ -30,8 +34,8 @@ class SithConfig(AppConfig):
verbose_name = "Core app of the Sith" verbose_name = "Core app of the Sith"
def ready(self): def ready(self):
import core.signals # noqa F401
from forum.models import Forum from forum.models import Forum
import core.signals
cache.clear() cache.clear()

View File

@ -1,23 +1,3 @@
# -*- coding:utf-8 -*-
#
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE"
#
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
#
from core.models import Page from core.models import Page

View File

@ -1,31 +1,28 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from ajax_select import LookupChannel, register
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from ajax_select import register, LookupChannel
from accounting.models import ClubAccount, Company
from club.models import Club
from core.models import Group, SithFile, User
from core.views.site import search_user from core.views.site import search_user
from counter.models import Counter, Customer, Product from core.models import User, Group, SithFile
from club.models import Club
from counter.models import Product, Counter, Customer
from accounting.models import ClubAccount, Company
from eboutic.models import BasketItem
def check_token(request): def check_token(request):

View File

@ -1,19 +1,15 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #

View File

@ -1,19 +1,15 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #

View File

@ -23,8 +23,8 @@
# #
import os import os
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.core.management import call_command
from core.models import SithFile from core.models import SithFile

View File

@ -1,27 +1,30 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2019
# ae@utbm.fr / ae.info@utbm.fr # - Sli <antoine@bartuccio.fr>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import os import os
from django.core.management.commands import compilemessages from django.core.management.commands import compilemessages

View File

@ -1,29 +1,32 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2017
# ae@utbm.fr / ae.info@utbm.fr # - Sli <antoine@bartuccio.fr>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import os import os
import sass import sass
from django.conf import settings
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.conf import settings
class Command(BaseCommand): class Command(BaseCommand):

View File

@ -1,28 +1,33 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2019
# ae@utbm.fr / ae.info@utbm.fr # - Sli <antoine@bartuccio.fr>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import os import os
import signal
import sys import sys
from http.server import CGIHTTPRequestHandler, test import signal
from http.server import test, CGIHTTPRequestHandler
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.utils import autoreload from django.utils import autoreload

View File

@ -1,68 +0,0 @@
# -*- coding:utf-8 -*
#
# Copyright 2024 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
#
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# You can find the source code of the website at https://github.com/ae-utbm/sith3
#
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE"
#
#
import os
import subprocess
from pathlib import Path
import tomli
from django.core.management.base import BaseCommand, CommandParser
class Command(BaseCommand):
help = "Install xapian"
def add_arguments(self, parser: CommandParser):
parser.add_argument(
"-f",
"--force",
action="store_true",
help="Force installation even if already installed",
)
def _current_version(self) -> str | None:
try:
import xapian
except ImportError:
return None
return xapian.version_string()
def _desired_version(self) -> str:
with open(
Path(__file__).parent.parent.parent.parent / "pyproject.toml", "rb"
) as f:
pyproject = tomli.load(f)
return pyproject["tool"]["xapian"]["version"]
def handle(self, force: bool, *args, **options):
if not os.environ.get("VIRTUAL_ENV", None):
print("No virtual environment detected, this command can't be used")
return
desired = self._desired_version()
if desired == self._current_version():
if not force:
print(
f"Version {desired} is already installed, use --force to re-install"
)
return
print(f"Version {desired} is already installed, re-installing")
print(f"Installing xapian version {desired} at {os.environ['VIRTUAL_ENV']}")
subprocess.run(
[str(Path(__file__).parent / "install_xapian.sh"), desired],
env=dict(os.environ),
).check_returncode()
print("Installation success")

View File

@ -1,47 +0,0 @@
#!/usr/bin/env bash
# Originates from https://gist.github.com/jorgecarleitao/ab6246c86c936b9c55fd
# first argument of the script is Xapian version (e.g. 1.2.19)
VERSION=$1
# Cleanup env vars for auto discovery mechanism
export CPATH=
export LIBRARY_PATH=
export CFLAGS=
export LDFLAGS=
export CCFLAGS=
export CXXFLAGS=
export CPPFLAGS=
# prepare
rm -rf "$VIRTUAL_ENV/packages"
mkdir -p "$VIRTUAL_ENV/packages" && cd "$VIRTUAL_ENV/packages" || exit 1
CORE=xapian-core-$VERSION
BINDINGS=xapian-bindings-$VERSION
# download
echo "Downloading source..."
curl -O "https://oligarchy.co.uk/xapian/$VERSION/${CORE}.tar.xz"
curl -O "https://oligarchy.co.uk/xapian/$VERSION/${BINDINGS}.tar.xz"
# extract
echo "Extracting source..."
tar xf "${CORE}.tar.xz"
tar xf "${BINDINGS}.tar.xz"
# install
echo "Installing Xapian-core..."
cd "$VIRTUAL_ENV/packages/${CORE}" || exit 1
./configure --prefix="$VIRTUAL_ENV" && make && make install
PYTHON_FLAG=--with-python3
echo "Installing Xapian-bindings..."
cd "$VIRTUAL_ENV/packages/${BINDINGS}" || exit 1
./configure --prefix="$VIRTUAL_ENV" $PYTHON_FLAG XAPIAN_CONFIG="$VIRTUAL_ENV/bin/xapian-config" && make && make install
# clean
rm -rf "$VIRTUAL_ENV/packages"
# test
python -c "import xapian"

View File

@ -1,25 +1,28 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import os import os
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from core.markdown import markdown from core.markdown import markdown

View File

@ -24,37 +24,38 @@
import os import os
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from io import BytesIO, StringIO from io import StringIO, BytesIO
from pathlib import Path from pathlib import Path
from django.conf import settings
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.contrib.sites.models import Site
from django.core.management import call_command
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.core.management import call_command
from django.conf import settings
from django.db import connection from django.db import connection
from django.contrib.sites.models import Site
from django.utils import timezone from django.utils import timezone
from PIL import Image from PIL import Image
from core.models import Group, User, Page, PageRev, SithFile
from accounting.models import ( from accounting.models import (
AccountingType, GeneralJournal,
BankAccount, BankAccount,
ClubAccount, ClubAccount,
Company,
GeneralJournal,
Operation, Operation,
AccountingType,
SimplifiedAccountingType, SimplifiedAccountingType,
Company,
) )
from club.models import Club, Membership
from com.models import News, NewsDate, Sith, Weekmail
from core.models import Group, Page, PageRev, SithFile, User
from core.utils import resize_image from core.utils import resize_image
from counter.models import Counter, Customer, Product, ProductType, Selling, StudentCard from club.models import Club, Membership
from election.models import Candidature, Election, ElectionList, Role from subscription.models import Subscription
from counter.models import Customer, ProductType, Product, Counter, Selling, StudentCard
from com.models import Sith, Weekmail, News, NewsDate
from election.models import Election, Role, Candidature, ElectionList
from forum.models import Forum, ForumTopic from forum.models import Forum, ForumTopic
from pedagogy.models import UV from pedagogy.models import UV
from sas.models import Album, PeoplePictureRelation, Picture from sas.models import Album, Picture, PeoplePictureRelation
from subscription.models import Subscription
class Command(BaseCommand): class Command(BaseCommand):

View File

@ -23,8 +23,8 @@
# #
import os import os
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.core.management import call_command
from core.models import SithFile from core.models import SithFile

View File

@ -1,27 +1,22 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import os import os
from django.core.management import call_command
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.core.management import call_command
class Command(BaseCommand): class Command(BaseCommand):

View File

@ -1,28 +1,23 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import os import os
import re import re
from mistune import Renderer, InlineGrammar, InlineLexer, Markdown, escape, escape_link
from django.urls import reverse from django.urls import reverse
from mistune import InlineGrammar, InlineLexer, Markdown, Renderer, escape, escape_link
class SithRenderer(Renderer): class SithRenderer(Renderer):

View File

@ -1,32 +1,27 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr # ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr. # https://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # You can find the source code of the website at https://github.com/ae-utbm/sith3
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import importlib import importlib
import threading import threading
from django.conf import settings from django.conf import settings
from django.utils.functional import SimpleLazyObject
from django.contrib.auth import get_user from django.contrib.auth import get_user
from django.contrib.auth.middleware import ( from django.contrib.auth.middleware import (
AuthenticationMiddleware as DjangoAuthenticationMiddleware, AuthenticationMiddleware as DjangoAuthenticationMiddleware,
) )
from django.utils.functional import SimpleLazyObject
module, klass = settings.AUTH_ANONYMOUS_MODEL.rsplit(".", 1) module, klass = settings.AUTH_ANONYMOUS_MODEL.rsplit(".", 1)
AnonymousUser = getattr(importlib.import_module(module), klass) AnonymousUser = getattr(importlib.import_module(module), klass)

View File

@ -1,14 +1,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models
import django.contrib.auth.models import django.contrib.auth.models
import django.core.validators
import django.db.models.deletion import django.db.models.deletion
import django.core.validators
import core.models
import phonenumber_field.modelfields import phonenumber_field.modelfields
from django.conf import settings from django.conf import settings
from django.db import migrations, models import django.db.models.deletion
import core.models
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.core.validators
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,9 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
import core.models import core.models

View File

@ -1,9 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.utils.timezone
from django.db import migrations, models from django.db import migrations, models
import django.utils.timezone
import core.models import core.models

View File

@ -1,10 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.utils.timezone
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.core.validators
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.core.validators
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,10 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings
import django.utils.timezone
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,10 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
import core.models import core.models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,8 +1,8 @@
# Generated by Django 2.2.6 on 2019-11-14 15:10 # Generated by Django 2.2.6 on 2019-11-14 15:10
import django.db.models.deletion
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -1,56 +1,58 @@
## -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017,2018
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file. # - Sli <antoine@bartuccio.fr>
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import importlib import importlib
import os from typing import Union, Optional, List
import unicodedata
from datetime import date, timedelta
from typing import List, Optional, Union
from django.conf import settings from django.core.cache import cache
from django.core.mail import send_mail
from django.contrib.auth.models import ( from django.contrib.auth.models import (
AbstractBaseUser, AbstractBaseUser,
UserManager, UserManager,
) Group as AuthGroup,
from django.contrib.auth.models import ( GroupManager as AuthGroupManager,
AnonymousUser as AuthAnonymousUser, AnonymousUser as AuthAnonymousUser,
) )
from django.contrib.auth.models import (
Group as AuthGroup,
)
from django.contrib.auth.models import (
GroupManager as AuthGroupManager,
)
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core import validators
from django.core.cache import cache
from django.core.exceptions import PermissionDenied, ValidationError
from django.core.mail import send_mail
from django.db import models, transaction
from django.urls import reverse
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.html import escape
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.core import validators
from django.core.exceptions import ValidationError, PermissionDenied
from django.urls import reverse
from django.conf import settings
from django.db import models, transaction
from django.contrib.staticfiles.storage import staticfiles_storage
from django.utils.html import escape
from django.utils.functional import cached_property
import os
from core import utils
from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.modelfields import PhoneNumberField
from core import utils from datetime import timedelta, date
import unicodedata
class RealGroupManager(AuthGroupManager): class RealGroupManager(AuthGroupManager):
@ -178,15 +180,14 @@ def get_group(*, pk: int = None, name: str = None) -> Optional[Group]:
:param pk: The primary key of the group :param pk: The primary key of the group
:param name: The name of the group :param name: The name of the group
:return: The group if it exists, else None :return: The group if it exists, else None
:raise ValueError: If no group matches the criteria :raises ValueError: If no group matches the criteria
""" """
if pk is None and name is None: if pk is None and name is None:
raise ValueError("Either pk or name must be set") raise ValueError("Either pk or name must be set")
if name is not None:
# replace space characters to hide warnings with memcached backend name = name.replace(" ", "_") # avoid errors with memcached backend
pk_or_name: Union[str, int] = pk if pk is not None else name.replace(" ", "_") pk_or_name: Union[str, int] = pk if pk is not None else name
group = cache.get(f"sith_group_{pk_or_name}") group = cache.get(f"sith_group_{pk_or_name}")
if group == "not_found": if group == "not_found":
# Using None as a cache value is a little bit tricky, # Using None as a cache value is a little bit tricky,
# so we use a special string to represent None # so we use a special string to represent None
@ -696,11 +697,9 @@ class User(AbstractBaseUser):
<em>%s</em> <em>%s</em>
</a> </a>
""" % ( """ % (
( self.profile_pict.get_download_url()
self.profile_pict.get_download_url() if self.profile_pict
if self.profile_pict else staticfiles_storage.url("core/img/unknown.jpg"),
else staticfiles_storage.url("core/img/unknown.jpg")
),
_("Profile"), _("Profile"),
escape(self.get_display_name()), escape(self.get_display_name()),
) )
@ -810,10 +809,6 @@ class AnonymousUser(AuthAnonymousUser):
def can_edit(self, obj): def can_edit(self, obj):
return False return False
@property
def is_com_admin(self):
return False
def can_view(self, obj): def can_view(self, obj):
if ( if (
hasattr(obj, "view_groups") hasattr(obj, "view_groups")

View File

@ -1,27 +1,31 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Sli <antoine@bartuccio.fr>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
""" """
This page is useful for custom migration tricks. This page is useful for custom migration tricks.
Sometimes, when you need to have a migration hack and you think it can be Sometimes, when you need to have a migration hack and you think it can be
useful again, put it there, we never know if we might need the hack again. useful again, put it there, we never know if we might need the hack again.
""" """
from django.db import connection, migrations from django.db import connection, migrations

View File

@ -1,27 +1,30 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Sli <antoine@bartuccio.fr>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import os import os
from collections import OrderedDict from collections import OrderedDict
from django.conf import settings from django.conf import settings
from django.contrib.staticfiles.finders import FileSystemFinder from django.contrib.staticfiles.finders import FileSystemFinder
from django.core.files.storage import FileSystemStorage from django.core.files.storage import FileSystemStorage

View File

@ -1,33 +1,35 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2017
# ae@utbm.fr / ae.info@utbm.fr # - Sli <antoine@bartuccio.fr>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
import os import os
from urllib.parse import urljoin
import sass import sass
from django.conf import settings from urllib.parse import urljoin
from django.utils.encoding import force_bytes, iri_to_uri
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.templatetags.static import static from django.templatetags.static import static
from django.utils.encoding import force_bytes, iri_to_uri from django.conf import settings
from core.scss.storage import ScssFileStorage, find_file from core.scss.storage import ScssFileStorage, find_file

View File

@ -1,22 +1,26 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2017
# ae@utbm.fr / ae.info@utbm.fr # - Sli <antoine@bartuccio.fr>
# All contributors are listed in the CONTRIBUTORS file.
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.conf import settings from django.conf import settings

View File

@ -1,24 +1,30 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*
# #
# Copyright 2023 © AE UTBM # Copyright 2016,2017
# ae@utbm.fr / ae.info@utbm.fr # - Skia <skia@libskia.so>
# All contributors are listed in the CONTRIBUTORS file. # - Sli <antoine@bartuccio.fr>
# #
# This file is part of the website of the UTBM Student Association (AE UTBM), # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# https://ae.utbm.fr. # http://ae.utbm.fr.
# #
# You can find the whole source code at https://github.com/ae-utbm/sith3 # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# #
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # This program is distributed in the hope that it will be useful, but WITHOUT
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# OR WITHIN THE LOCAL FILE "LICENSE" # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
# OR WITHIN THE LOCAL FILE "LICENSE.old"
# #
from django.db import models from django.db import models
from haystack import indexes, signals from haystack import indexes, signals
from core.models import User from core.models import User

View File

@ -8,10 +8,10 @@ from core.models import User
@receiver(m2m_changed, sender=User.groups.through, dispatch_uid="user_groups_changed") @receiver(m2m_changed, sender=User.groups.through, dispatch_uid="user_groups_changed")
def user_groups_changed(sender, instance: User, **kwargs): def user_groups_changed(sender, instance: User, **kwargs):
""" """
Clear the cached groups of the user Clear the cached clubs of the user
""" """
# As a m2m relationship doesn't live within the model # As a m2m relationship doesn't live within the model
# but rather on an intermediary table, there is no # but rather on an intermediary table, there is no
# model method to override, meaning we must use # model method to override, meaning we must use
# a signal to invalidate the cache when a user is removed from a group # a signal to invalidate the cache when a user is removed from a club
cache.delete(f"user_{instance.pk}_groups") cache.delete(f"user_{instance.id}_groups")

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More