mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-12 21:09:24 +00:00
Compare commits
5 Commits
fix/licens
...
feature/im
Author | SHA1 | Date | |
---|---|---|---|
46fa14ed12 | |||
18dffb0053 | |||
6e47d1471e | |||
b5146569e1 | |||
acde993352 |
10
.github/actions/setup_project/action.yml
vendored
10
.github/actions/setup_project/action.yml
vendored
@ -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
|
||||||
|
29
.github/workflows/ci.yml
vendored
29
.github/workflows/ci.yml
vendored
@ -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
|
||||||
|
3
.github/workflows/taiste.yml
vendored
3
.github/workflows/taiste.yml
vendored
@ -2,8 +2,7 @@ name: Sith3 taiste
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [taiste]
|
branches: [ taiste ]
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deployment:
|
deployment:
|
||||||
|
@ -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._
|
|
21
LICENSE.old
21
LICENSE.old
@ -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.
|
|
@ -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"
|
|
||||||
#
|
#
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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])
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
|
@ -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])
|
||||||
|
@ -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"
|
|
||||||
#
|
#
|
||||||
|
10
api/admin.py
10
api/admin.py
@ -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.
|
||||||
|
@ -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.
|
||||||
|
10
api/tests.py
10
api/tests.py
@ -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.
|
||||||
|
12
api/urls.py
12
api/urls.py
@ -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()
|
||||||
|
@ -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 *
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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:
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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"
|
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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 }}
|
||||||
|
@ -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>
|
||||||
|
471
club/tests.py
471
club/tests.py
@ -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)
|
||||||
|
31
club/urls.py
31
club/urls.py
@ -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
|
||||||
|
@ -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
|
||||||
"""
|
"""
|
||||||
|
@ -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"
|
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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>
|
||||||
|
113
com/tests.py
113
com/tests.py
@ -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))
|
||||||
|
@ -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
|
||||||
|
76
com/views.py
76
com/views.py
@ -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
|
||||||
|
|
||||||
|
14
conftest.py
14
conftest.py
@ -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")
|
|
@ -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"
|
|
||||||
#
|
#
|
||||||
|
@ -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)
|
||||||
|
32
core/apps.py
32
core/apps.py
@ -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()
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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"
|
|
||||||
#
|
#
|
||||||
|
@ -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"
|
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
|
@ -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"
|
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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")
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
Reference in New Issue
Block a user