101 Commits

Author SHA1 Message Date
6169d09ac0 Update CONTRIBUTORS list 2024-06-28 18:45:39 +02:00
f876bc3599 Unified header across all files 2024-06-26 19:17:57 +02:00
147b3619f5 Restore old license & add CONTRIBUTORS file 2024-06-26 19:16:34 +02:00
d97602e60b Use pytest for tests (#681)
* use pytest for tests

Eh ouais, il y a que la config qui change. Pytest est implémentable par étapes. Et ça c'est beau.

* rework tests with pytest

* remove unittest custom TestRunner

* Edit doc and CI
2024-06-26 19:10:24 +02:00
a5cbac1f97 Merge pull request #680 from ae-utbm/ruff
Introduct Ruff as formater and linter
2024-06-26 14:11:26 +02:00
3143d3d91a reorganize imports with ruff 2024-06-26 12:35:38 +02:00
9bdf3fc4ac use ruff for formating
Co-authored-by: Bartuccio Antoine <klmp200@users.noreply.github.com>
2024-06-26 12:35:14 +02:00
e06bc7dba3 reorganize pyproject.toml 2024-06-26 12:33:35 +02:00
a8b9f38000 Merge pull request #679 from ae-utbm/xapian-from-sources
Xapian from sources and fix CVE
2024-06-26 11:48:31 +02:00
Sli
ca27b89a8b Apply shellcheck on install_xapian.sh 2024-06-26 11:31:39 +02:00
Sli
e1bf7caa9a Fix CVE-2023-31047 2024-06-24 13:27:22 +02:00
Sli
e681c17a0f Adapt CI to new xapian install process 2024-06-24 13:26:58 +02:00
Sli
5416d88c97 Upgrade dependencies and install xapian from sources 2024-06-24 13:26:58 +02:00
ee437649f0 Revert "Merge branch 'master' into taiste"
This reverts commit 4303d51c0a, reversing
changes made to d16bf12611.
2023-10-10 15:47:02 +02:00
4303d51c0a Merge branch 'master' into taiste 2023-10-10 15:32:46 +02:00
d16bf12611 Links update & translations typos fixes (#671)
* Remove BDF link (as BDF is now part of AE)

* Remove unused pages

* Fix typos

* Fix typo again
2023-10-10 15:29:02 +02:00
4231a7972d Remove eurocks tickets from eboutic (event is finished) 2023-10-04 14:27:21 +02:00
51a12814f9 Update workflow 2023-09-19 22:17:26 +02:00
00ae6e4623 Update workflow
Following this update : https://github.blog/changelog/2023-09-13-github-actions-updates-to-github_ref-and-github-ref/
2023-09-19 22:04:46 +02:00
4b587e8711 Merge branch 'taiste' of https://github.com/ae-utbm/sith3 into taiste 2023-09-19 21:31:02 +02:00
d2f377b54f Add eurocks partnership in the eboutic (#661)
Revert "Add eurocks partnership in the eboutic (#661)"

This reverts commit 193c820757.

Add eurocks partnership in the eboutic (#661)
2023-09-19 21:29:17 +02:00
193c820757 Add eurocks partnership in the eboutic (#661) 2023-09-19 20:59:22 +02:00
aaf30ab965 Add missing method on AnonymousUser (#649) 2023-09-07 23:53:42 +02:00
2db66e6154 Merge branch 'master' into taiste 2023-09-07 23:44:09 +02:00
38295e591d Fix immutable default variable in get_start_of_semester (#656)
Le serveur ne percevait pas le changement de semestre, parce
que la valeur par défaut passée à la fonction `get_start_of_semester()` était une fonction appelée une seule fois, lors du lancement du serveur. Bref, c'était ça : https://beta.ruff.rs/docs/rules/function-call-in-default-argument/

---------

Co-authored-by: imperosol <thgirod@hotmail.com>
2023-09-07 23:11:58 +02:00
544b0248b2 [UPDATE] Bump django-ordered-model from 3.6 to 3.7.4 (#625)
Bumps [django-ordered-model](https://github.com/django-ordered-model/django-ordered-model) from 3.6 to 3.7.4.
- [Release notes](https://github.com/django-ordered-model/django-ordered-model/releases)
- [Changelog](https://github.com/django-ordered-model/django-ordered-model/blob/master/CHANGES.md)
- [Commits](https://github.com/django-ordered-model/django-ordered-model/compare/3.6...3.7.4)

---
updated-dependencies:
- dependency-name: django-ordered-model
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-06 12:01:44 +02:00
2bccf633d5 Bump sqlparse from 0.4.3 to 0.4.4 (#645)
Bumps [sqlparse](https://github.com/andialbrecht/sqlparse) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/andialbrecht/sqlparse/releases)
- [Changelog](https://github.com/andialbrecht/sqlparse/blob/master/CHANGELOG)
- [Commits](https://github.com/andialbrecht/sqlparse/compare/0.4.3...0.4.4)

---
updated-dependencies:
- dependency-name: sqlparse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-06 11:37:28 +02:00
84768eb74e [FIX] Fix cached groups (#647) 2023-05-12 13:27:51 +02:00
8852ef990e [UPDATE] Bump libsass from 0.21.0 to 0.22.0 (#640)
Bumps [libsass](https://github.com/sass/libsass-python) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/sass/libsass-python/releases)
- [Changelog](https://github.com/sass/libsass-python/blob/main/docs/changes.rst)
- [Commits](https://github.com/sass/libsass-python/compare/0.21.0...0.22.0)

---
updated-dependencies:
- dependency-name: libsass
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-11 14:19:19 +02:00
87295ad9b7 Galaxy improvements (#628)
* galaxy: improve logging and performance reporting

* galaxy: add a full galaxy state test

* galaxy: optimize user self score computation

* galaxy: add 'generate_galaxy_test_data' command for development at scale

* galaxy: big refactor

Main changes:
  - Multiple Galaxy objects can now exist at the same time in DB. This allows for ruling a new galaxy while still
    displaying the old one.
  - The criteria to quickly know whether a user is a possible citizen is now a simple query on picture count. This
    avoids a very complicated query to database, that could often result in huge working memory load. With this change,
    it should be possible to run the galaxy even on a vanilla Postgres that didn't receive fine tuning for the Sith's
    galaxy.

* galaxy: template: make the galaxy graph work and be usable with a lot of stars

- Display focused star and its connections clearly
- Display star label faintly by default for other stars to avoid overloading the graph
- Hide non-focused lanes
- Avoid clicks on non-highlighted, too far stars
- Make the canva adapt its width to initial screen size, doesn't work dynamically

* galaxy: better docstrings

* galaxy: use bulk_create whenever possible

This is a big performance gain, especially for the tests.

Examples:

----

`./manage.py test galaxy.tests.GalaxyTest.test_full_galaxy_state`

Measurements averaged over 3 run on *my machine*™:
Before: 2min15s
After: 1m41s

----

`./manage.py generate_galaxy_test_data --user-pack-count 1`

Before: 48s
After: 25s

----

`./manage.py rule_galaxy` (for 600 citizen, corresponding to 1 user-pack)

Before: 14m4s
After: 12m34s

* core: populate: use a less ambiguous 'timezone.now()'

When running the tests around midnight, the day is changing, leading to some values being offset to the next day
depending on the timezone, and making some tests to fail. This ensure to use a less ambiguous `now` when populating
the database.

* write more extensive documentation

- add documentation to previously documented classes and functions and refactor some of the documented one, in accordance to the PEP257 and ReStructuredText standards ;
- add some type hints ;
- use a NamedTuple for the `Galaxy.compute_users_score` method instead of a raw tuple. Also change a little bit the logic in the function which call the latter ;
- add some additional parameter checks on a few functions ;
- change a little bit the logic of the log level setting for the galaxy related commands.

* galaxy: tests: split Model and View for more efficient data usage

---------

Co-authored-by: maréchal <thgirod@hotmail.com>
2023-05-10 12:47:02 +02:00
5ab5ef681c Remove duplicated css 2023-05-09 23:08:32 +02:00
c9e70889dd Merge branch 'master' into taiste 2023-05-09 22:37:49 +02:00
b30ee0a27a [FIX] Correction de bugs (#617)
* Fix #600

* Fix #602

* Fixes & améliorations du nouveau CSS (#616)

* Fix #604

* should fix #605

* Fix #608

* Update core/views/site.py

Co-Authored-By: thomas girod <56346771+imperosol@users.noreply.github.com>

* Added back the permission denied

* Should fix #609

* Fix failing test when 2 user are merged

* Should fix #610

* Should fix #627

* Should fix #109

Block les URLs suivantes lorsque le fichier se trouve dans le dir `profiles` ou `SAS` :
- `/file/<id>/`
- `/file/<id>/[delete|prop|edit]`

> Les urls du SAS restent accessiblent pour les roots & les admins SAS
> Les urls de profiles sont uniquement accessiblent aux roots

* Fix root dir of SAS being unnaccessible for sas admins

⚠️ need to edit the SAS directory & save it (no changes required in sas directory properties)

* Remove overwritten code

* Should fix duplicated albums in user profile (wtf)

* Fix typo

* Extended profiles picture access to board members

* Should fix #607

* Fix keyboard navigation not working properly

* Fix user tagged pictures section inside python rather than in the template

* Update utils.py

* Apply suggested changes

* Fix #604

* Fix #608

* Added back the permission denied

* Should fix duplicated albums in user profile (wtf)

* Fix user tagged pictures section inside python rather than in the template

* Apply suggested changes

---------

Co-authored-by: thomas girod <56346771+imperosol@users.noreply.github.com>
2023-05-02 13:07:36 +02:00
ef968f3673 Better usage of cache for groups and clubs related operations (#634)
* Better usage of cache for group retrieval

* Cache clearing on object deletion or update

* replace signals by save and delete override

* add is_anonymous check in is_owned_by

Add in many is_owned_by(self, user) methods that user is not anonymous. Since many of those functions do db queries, this should reduce a little bit the load of the db.

* Stricter usage of User.is_in_group

Constrain the parameters that can be passed to the function to make sure only a str or an int can be used. Also force to explicitly specify if the group id or the group name is used.

* write test and correct bugs

* remove forgotten populate commands

* Correct test
2023-05-02 12:36:59 +02:00
96dede5077 Speed up tests (#638) 2023-05-02 11:00:23 +02:00
66fcb76cb5 Merge pull request #635 from ae-utbm/dependabot/pip/taiste/sentry-sdk-1.21.0
[UPDATE] Bump sentry-sdk from 1.19.1 to 1.21.0
2023-04-26 22:17:13 +02:00
63c8e51137 [UPDATE] Bump sentry-sdk from 1.19.1 to 1.21.0
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.19.1 to 1.21.0.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/1.19.1...1.21.0)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-26 09:08:06 +00:00
12bec5c553 [UPDATE] Bump django-countries from 7.5 to 7.5.1 (#624)
Bumps [django-countries](https://github.com/SmileyChris/django-countries) from 7.5 to 7.5.1.
- [Release notes](https://github.com/SmileyChris/django-countries/releases)
- [Changelog](https://github.com/SmileyChris/django-countries/blob/main/CHANGES.rst)
- [Commits](https://github.com/SmileyChris/django-countries/compare/v7.5...v7.5.1)

---
updated-dependencies:
- dependency-name: django-countries
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-26 02:48:04 +02:00
08460a6964 update link for poetry install 2023-04-22 22:29:43 +02:00
b5a40cfda9 Mise à jour de Black vers la version 23.3 (#629) 2023-04-22 15:32:31 +02:00
c78953b036 [UPDATE] Bump cryptography from 37.0.4 to 40.0.1 (#594)
* [UPDATE] Bump cryptography from 37.0.4 to 40.0.1

Bumps [cryptography](https://github.com/pyca/cryptography) from 37.0.4 to 40.0.1.
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/37.0.4...40.0.1)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Updated pyOpenSSL to match cryptography requirements

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Julien Constant <julienconstant190@gmail.com>
2023-04-20 14:43:46 +02:00
427f7ceaff [UPDATE] Bump django-debug-toolbar from 3.8.1 to 4.0.0 (#593)
Bumps [django-debug-toolbar](https://github.com/jazzband/django-debug-toolbar) from 3.8.1 to 4.0.0.
- [Release notes](https://github.com/jazzband/django-debug-toolbar/releases)
- [Changelog](https://github.com/jazzband/django-debug-toolbar/blob/main/docs/changes.rst)
- [Commits](https://github.com/jazzband/django-debug-toolbar/compare/3.8.1...4.0.0)

---
updated-dependencies:
- dependency-name: django-debug-toolbar
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-09 21:37:48 +02:00
1055385bcc [UPDATE] Bump dict2xml from 1.7.2 to 1.7.3 (#592)
Bumps [dict2xml](https://github.com/delfick/python-dict2xml) from 1.7.2 to 1.7.3.
- [Release notes](https://github.com/delfick/python-dict2xml/releases)
- [Commits](https://github.com/delfick/python-dict2xml/compare/release-1.7.2...release-1.7.3)

---
updated-dependencies:
- dependency-name: dict2xml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...
2023-04-09 11:38:58 +02:00
c1022642a2 [FIX] Fixes supplémentaires pour la màj de mars (#622)
- Les photos de l'onglet de la page utilisateur utilise désormais leur version thumbnail au lieu de leur version HD
- Une des classes du CSS du SAS a été renommée car elle empiétait sur une class de la navbar
- Le profil utilisateur a été revu pour ajouter plus d'espacement entre le tableau des cotisations et le numéro de cotisants
- Les images de forum & blouse sont de nouveau cliquable pour les afficher en grands
- Sur mobile, lorsqu'on cliquait sur le premier élément de la navbar, ce dernier avait un overlay avec des angles arrondis
- Sur mobile, les utilisateurs avec des images de profils non carrées dépassait dans l'onglet Famille
2023-04-08 20:59:43 +02:00
06253f029c [UPDATE] Bump sentry-sdk from 1.12.1 to 1.19.1 (#620) 2023-04-08 18:50:31 +00:00
0501e6417a Merge branch 'master' into taiste 2023-04-05 20:02:12 +02:00
a198f5252d Fixes & améliorations du nouveau CSS (#616) 2023-04-05 18:03:43 +02:00
d83842af27 Fix problème de cache dans le SAS & améliore le CSS du SAS
Co-authored-by: Bartuccio Antoine <klmp200@users.noreply.github.com>
2023-04-05 14:32:32 +02:00
f605f7dcc6 Fixes pour la mise à jour de mars (#598) 2023-04-04 22:55:26 +02:00
8e7c025e47 [FIX] Broken link in readme and license fix (& update) (#591) 2023-04-04 18:39:45 +02:00
1bfe929ab3 [CSS] Follow up of #578 (#589) 2023-04-04 15:21:09 +02:00
93cc2c883e Bump django from 3.2.16 to 3.2.18 (#574) 2023-04-04 10:16:55 +02:00
44290a20a6 Create dependabot.yml (#587) 2023-04-03 17:18:16 +02:00
1f10a284f2 Added GA/Clubs Google Calendar to main page (#585)
* Added GA/Clubs google calendar to main page

* Made tables full width
2023-04-03 15:54:12 +02:00
28f397574f Amélioration des pages utilisateurs pour les petits écrans (#578, #520)
- Refonte de l'organisation des pages utilisateurs (principalement du front)
  - Page des parrains/fillots
  - Page d'édition du profil
  - Page du profil
  - Page des outils
  - Page des préférences
  - Page des stats utilisateurs

- Refonte du CSS / organisation de la navbar principale (en haut de l'écran)
- Refonte du CSS de la navbar bleu clair (le menu)
- Refonte du CSS du SAS :
  - Page de photo
  - Page d'albums
2023-03-30 14:38:40 +02:00
6c1fa6de0b remove-useless-queries-counter-stats (#519) 2023-03-24 15:32:05 +01:00
f0a08afd31 Merge branch 'repair_NaN_bug_on_click' into taiste 2023-03-10 10:50:26 +01:00
9e0b5b0b82 Merge branch 'partenariat-eurocks' into taiste 2023-03-09 17:14:34 +01:00
25c5a3297c Repair NaN bug for autocomplete on counter click 2023-03-09 14:21:12 +01:00
5ea181829e Edited unit tests
This test caused a breach in security due to the alert block displaying sensitive data.
2023-03-08 20:47:59 +01:00
0cf203669f fix wording
Co-authored-by: Théo DURR <git@theodurr.fr>
2023-03-08 20:35:24 +01:00
559bfcac60 fix typo 2023-03-08 20:13:12 +01:00
db8a1ed0ab Added eurocks links to eboutic 2023-03-08 20:10:54 +01:00
16150905a0 Fixed broken test 2023-03-08 14:11:10 +01:00
9a376887ac Update 404.jinja 2023-03-08 13:08:23 +01:00
773808fa59 Disabled Galaxy button & Removed 404 exception display 2023-03-08 12:50:52 +01:00
c1e59a0676 Disabled galaxy feature (only visually) 2023-03-07 21:32:37 +01:00
05febc60bd Merge branch 'master' into taiste 2023-03-04 16:35:41 +01:00
a73fe598ef repair user merging tool (#498) 2023-03-04 15:01:08 +01:00
585923c827 Add galaxy (#562)
* style.scss: lint

* style.scss: add 'th' padding

* core: populate: add much more data for development

* Add galaxy
2023-02-07 12:08:25 +01:00
394e17d599 resolved importError (#565) 2023-01-13 02:22:53 +01:00
59136850b8 Merge pull request #530 from ae-utbm/redirection_for_barmen
redirect the user directly on counter when barman
2023-01-11 23:24:45 +01:00
d726f4b1e8 Merge pull request #499 from ae-utbm/unify-account-creation
Unify account id creation
2023-01-11 13:26:00 +01:00
705b9b1e6a Passage de vue à Alpine pour les comptoirs (#561)
Vue, c'est cool, mais avec Django c'est un peu chiant à utiliser. Alpine a l'avantage d'être plus léger et d'avoir une syntaxe qui ne ressemble pas à celle de Jinja (ce qui évite d'avoir à mettre des {% raw %} partout).
2023-01-10 22:26:46 +01:00
31e8ad8a3e redirect directly on counter if user is barman 2023-01-10 17:37:26 +01:00
99827e005b upgrade re_path to path (#533) 2023-01-09 22:07:03 +01:00
751c8a8bc6 unify account_id creation 2023-01-09 21:40:38 +01:00
37216cd16b Updated lock file according to pyproject 2023-01-09 19:29:04 +01:00
dae68638cf Merge branch 'master' into taiste 2023-01-09 19:15:00 +01:00
7cadc0bc28 Update doc/start/install.rst 2023-01-09 19:04:43 +01:00
cce686f3a8 Update doc/about/tech.rst 2023-01-09 19:04:32 +01:00
4fe46fbcef [FIX] 3DSv2 - Echappement du XML et modif tables (#543)
* Fixed wrong HMAC signature generation
* Updated migration files

Co-authored-by: Julien Constant <julienconstant190@gmail.com>
2023-01-09 17:46:34 +01:00
fe8b8f46aa Fix 3DSv2 implementation (#542)
* Fixed wrong HMAC signature generation

* Fix xml du panier

Co-authored-by: Julien Constant <julienconstant190@gmail.com>
2023-01-06 20:02:45 +01:00
7079761ffe Merge pull request #540 from ae-utbm/3dsv2-encore-un-patch
remove csrf_token
2022-12-26 18:55:41 +01:00
f681c981c6 remove csrf_token 2022-12-26 18:51:04 +01:00
5d97146d14 Merge pull request #531 from ae-utbm/remove_useless_tests
remove useless tests
2022-12-22 13:01:56 +01:00
7b56bd697d Merge pull request #536 from ae-utbm/refactor_admin
enhance admin pages
2022-12-21 17:10:51 +01:00
14cd268d69 Merge pull request #532 from ae-utbm/update-doc
update documentation
2022-12-21 16:02:17 +01:00
754be1c9c9 Update doc/about/tech.rst
Co-authored-by: Julien Constant <49886317+Juknum@users.noreply.github.com>
2022-12-20 21:17:52 +01:00
da2c155254 update documentation 2022-12-20 17:26:28 +01:00
ceb2888f82 enhance admin pages 2022-12-19 20:55:33 +01:00
26c94c9ec6 [Eboutic] Fix double quote issue & improved user experience on small screen (#522)
* Fix #511 Regex issue with escaped double quotes

* Fix basket being when reloading the page (when cookie != "")

+ Added JSDoc
+ Cleaned some code

* Fix #509 Improved user experience on small screens

* Fix css class not being added back when reloading page

* CSS Fixes (see description)

+ Fixed overlaping item title with the cart emoji on small screen
+ Fixed minimal size of the basket on small screen (full width)

* Added darkened background circle to items with no image

* Fix issue were the basket could be None


* Edited CSS to have bette img ratio & the 🛒 icon

Adapt, Improve, Overcome

* Moved basket down on small screen size
2022-12-16 00:37:07 +01:00
639197f4c8 update some dependencies (#523) 2022-12-15 23:57:31 +01:00
faccc1367f Fix le panier de l'Eboutic pour Safari (#518)
Co-authored-by: Théo DURR <git@theodurr.fr>
Co-authored-by: thomas girod <56346771+imperosol@users.noreply.github.com>
2022-12-14 08:38:41 +01:00
22b83b0814 remove useless tests 2022-12-12 22:56:06 +01:00
1d82e2a7d9 Change country id to ISO 3166 1 numeric for 3DSV2 (#510) 2022-12-12 22:54:31 +01:00
b8a72c57e1 escape html characters on xml (#505) 2022-12-10 20:41:35 +01:00
9188565a86 Merge pull request #501 from ae-utbm/ci-cl-edit
Ci cl edit
2022-12-01 11:14:56 +01:00
4d7d22c337 edit yml to avoid git conflict when deploying on test 2022-12-01 10:07:03 +01:00
b58116b023 Merge pull request #500 from ae-utbm/eboutic-3DSv2-patch
integration of 3D secure v2 for eboutic bank payment
2022-11-30 23:10:53 +01:00
fe9e5ce861 integration of 3D secure v2 for eboutic bank payment 2022-11-30 22:52:56 +01:00
255 changed files with 4683 additions and 4604 deletions

View File

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

View File

@ -8,27 +8,29 @@ on:
workflow_dispatch:
jobs:
black:
name: Black format
ruff:
name: Ruff lint & format
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
- name: Setup Project
uses: ./.github/actions/setup_project
- run: poetry run black --check .
- uses: actions/checkout@v4
- name: ruff format
uses: chartboost/ruff-action@v1 # format
with:
args: format --diff
- name: ruff check
uses: chartboost/ruff-action@v1 # lint
tests:
name: Run tests and generate coverage report
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- uses: ./.github/actions/setup_project
- uses: ./.github/actions/setup_xapian
- uses: ./.github/actions/compile_messages
- name: Run tests
run: poetry run coverage run ./manage.py test
run: poetry run coverage run -m pytest
- name: Generate coverage report
run: |
poetry run coverage report

31
CONTRIBUTORS.md Normal file
View File

@ -0,0 +1,31 @@
# 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 Normal file
View File

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

View File

@ -1,15 +1,19 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#

View File

@ -1,24 +1,27 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 django.contrib import admin
from accounting.models import *
admin.site.register(BankAccount)
admin.site.register(ClubAccount)
admin.site.register(GeneralJournal)

View File

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

View File

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

View File

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

View File

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

View File

@ -1,32 +1,36 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 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.template import defaultfilters
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.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from decimal import Decimal
from core.models import User, SithFile
from club.models import Club
from core.models import SithFile, User
class CurrencyField(models.DecimalField):

View File

@ -1,100 +1,99 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 datetime import date, timedelta
from django.test import TestCase
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 (
GeneralJournal,
Operation,
Label,
AccountingType,
GeneralJournal,
Label,
Operation,
SimplifiedAccountingType,
)
from core.models import User
class RefoundAccountTest(TestCase):
def setUp(self):
self.skia = User.objects.filter(username="skia").first()
@classmethod
def setUpTestData(cls):
cls.skia = User.objects.get(username="skia")
# reffil skia's account
self.skia.customer.amount = 800
self.skia.customer.save()
cls.skia.customer.amount = 800
cls.skia.customer.save()
cls.refound_account_url = reverse("accounting:refound_account")
def test_permission_denied(self):
self.client.login(username="guy", password="plop")
self.client.force_login(User.objects.get(username="guy"))
response_post = self.client.post(
reverse("accounting:refound_account"), {"user": self.skia.id}
self.refound_account_url, {"user": self.skia.id}
)
response_get = self.client.get(reverse("accounting:refound_account"))
self.assertTrue(response_get.status_code == 403)
self.assertTrue(response_post.status_code == 403)
response_get = self.client.get(self.refound_account_url)
assert response_get.status_code == 403
assert response_post.status_code == 403
def test_root_granteed(self):
self.client.login(username="root", password="plop")
response_post = self.client.post(
reverse("accounting:refound_account"), {"user": self.skia.id}
)
self.skia = User.objects.filter(username="skia").first()
response_get = self.client.get(reverse("accounting:refound_account"))
self.assertFalse(response_get.status_code == 403)
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)
self.client.force_login(User.objects.get(username="root"))
response = self.client.post(self.refound_account_url, {"user": self.skia.id})
self.assertRedirects(response, self.refound_account_url)
self.skia.refresh_from_db()
response = self.client.get(self.refound_account_url)
assert response.status_code == 200
assert '<form action="" method="post">' in str(response.content)
assert self.skia.customer.amount == 0
def test_comptable_granteed(self):
self.client.login(username="comptable", password="plop")
response_post = self.client.post(
reverse("accounting:refound_account"), {"user": self.skia.id}
)
self.skia = User.objects.filter(username="skia").first()
response_get = self.client.get(reverse("accounting:refound_account"))
self.assertFalse(response_get.status_code == 403)
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)
self.client.force_login(User.objects.get(username="comptable"))
response = self.client.post(self.refound_account_url, {"user": self.skia.id})
self.assertRedirects(response, self.refound_account_url)
self.skia.refresh_from_db()
response = self.client.get(self.refound_account_url)
assert response.status_code == 200
assert '<form action="" method="post">' in str(response.content)
assert self.skia.customer.amount == 0
class JournalTest(TestCase):
def setUp(self):
self.journal = GeneralJournal.objects.filter(id=1).first()
@classmethod
def setUpTestData(cls):
cls.journal = GeneralJournal.objects.get(id=1)
def test_permission_granted(self):
self.client.login(username="comptable", password="plop")
self.client.force_login(User.objects.get(username="comptable"))
response_get = self.client.get(
reverse("accounting:journal_details", args=[self.journal.id])
)
self.assertTrue(response_get.status_code == 200)
self.assertTrue(
"<td>M\\xc3\\xa9thode de paiement</td>" in str(response_get.content)
)
assert response_get.status_code == 200
assert "<td>M\\xc3\\xa9thode de paiement</td>" in str(response_get.content)
def test_permission_not_granted(self):
self.client.login(username="skia", password="plop")
self.client.force_login(User.objects.get(username="skia"))
response_get = self.client.get(
reverse("accounting:journal_details", args=[self.journal.id])
)
self.assertTrue(response_get.status_code == 403)
self.assertFalse(
"<td>M\xc3\xa9thode de paiement</td>" in str(response_get.content)
)
assert response_get.status_code == 403
assert "<td>M\xc3\xa9thode de paiement</td>" not in str(response_get.content)
class OperationTest(TestCase):
@ -108,9 +107,8 @@ class OperationTest(TestCase):
code="443", label="Ce code n'existe pas", movement_type="CREDIT"
)
at.save()
l = Label(club_account=self.journal.club_account, name="bob")
l.save()
self.client.login(username="comptable", password="plop")
l = Label.objects.create(club_account=self.journal.club_account, name="bob")
self.client.force_login(User.objects.get(username="comptable"))
self.op1 = Operation(
journal=self.journal,
date=date.today(),
@ -139,8 +137,7 @@ class OperationTest(TestCase):
self.op2.save()
def test_new_operation(self):
self.client.login(username="comptable", password="plop")
at = AccountingType.objects.filter(code="604").first()
at = AccountingType.objects.get(code="604")
response = self.client.post(
reverse("accounting:op_new", args=[self.journal.id]),
{
@ -172,8 +169,7 @@ class OperationTest(TestCase):
self.assertTrue("<td>Le fantome de la nuit</td>" in str(response_get.content))
def test_bad_new_operation(self):
self.client.login(username="comptable", password="plop")
AccountingType.objects.filter(code="604").first()
AccountingType.objects.get(code="604")
response = self.client.post(
reverse("accounting:op_new", args=[self.journal.id]),
{
@ -199,7 +195,7 @@ class OperationTest(TestCase):
)
def test_new_operation_not_authorized(self):
self.client.login(username="skia", password="plop")
self.client.force_login(self.skia)
at = AccountingType.objects.filter(code="604").first()
response = self.client.post(
reverse("accounting:op_new", args=[self.journal.id]),
@ -226,7 +222,6 @@ class OperationTest(TestCase):
)
def test__operation_simple_accounting(self):
self.client.login(username="comptable", password="plop")
sat = SimplifiedAccountingType.objects.all().first()
response = self.client.post(
reverse("accounting:op_new", args=[self.journal.id]),
@ -263,14 +258,12 @@ class OperationTest(TestCase):
)
def test_nature_statement(self):
self.client.login(username="comptable", password="plop")
response = self.client.get(
reverse("accounting:journal_nature_statement", args=[self.journal.id])
)
self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200)
def test_person_statement(self):
self.client.login(username="comptable", password="plop")
response = self.client.get(
reverse("accounting:journal_person_statement", args=[self.journal.id])
)
@ -292,7 +285,6 @@ class OperationTest(TestCase):
)
def test_accounting_statement(self):
self.client.login(username="comptable", password="plop")
response = self.client.get(
reverse("accounting:journal_accounting_statement", args=[self.journal.id])
)

View File

@ -1,17 +1,21 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 django.urls import path

View File

@ -1,54 +1,58 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 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
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 core.views import (
CanViewMixin,
CanEditMixin,
CanEditPropMixin,
CanCreateMixin,
TabedViewMixin,
)
from core.views.forms import SelectFile, SelectDate
from accounting.models import (
AccountingType,
BankAccount,
ClubAccount,
GeneralJournal,
Operation,
AccountingType,
Company,
SimplifiedAccountingType,
GeneralJournal,
Label,
Operation,
SimplifiedAccountingType,
)
from counter.models import Counter, Selling, Product
from core.views import (
CanCreateMixin,
CanEditMixin,
CanEditPropMixin,
CanViewMixin,
TabedViewMixin,
)
from core.views.forms import SelectDate, SelectFile
from counter.models import Counter, Product, Selling
# Main accounting view
@ -521,14 +525,14 @@ class OperationPDFView(CanViewMixin, DetailView):
pk_url_kwarg = "op_id"
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.pagesizes import letter
from reportlab.lib.units import cm
from reportlab.lib.utils import ImageReader
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle
pdfmetrics.registerFont(TTFont("DejaVu", "DejaVuSerif.ttf"))
@ -599,7 +603,7 @@ class OperationPDFView(CanViewMixin, DetailView):
payment_mode = ""
for m in settings.SITH_ACCOUNTING_PAYMENT_METHOD:
if m[0] == mode:
payment_mode += "[\u00D7]"
payment_mode += "[\u00d7]"
else:
payment_mode += "[ ]"
payment_mode += " %s\n" % (m[1])

View File

@ -1,15 +1,19 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#

View File

@ -1,19 +1,21 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 django.contrib import admin
# Register your models here.

View File

@ -1,19 +1,21 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 django.db import models
# Create your models here.

View File

@ -1,19 +1,21 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 django.test import TestCase
# Create your tests here.

View File

@ -1,23 +1,27 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 django.urls import re_path, path, include
from django.urls import include, path, re_path
from rest_framework import routers
from api.views import *
from rest_framework import routers
# Router config
router = routers.DefaultRouter()

View File

@ -1,26 +1,30 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 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 rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from core.views import can_view, can_edit
from core.views import can_edit, can_view
def check_if(obj, user, test):
@ -64,10 +68,10 @@ class RightModelViewSet(ManageModelMixin, viewsets.ModelViewSet):
from .api import *
from .counter import *
from .user import *
from .club import *
from .counter import *
from .group import *
from .launderette import *
from .uv import *
from .sas import *
from .user import *
from .uv import *

View File

@ -1,22 +1,26 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 rest_framework.response import Response
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import StaticHTMLRenderer
from rest_framework.response import Response
from core.templatetags.renderer import markdown

View File

@ -1,30 +1,32 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 rest_framework.response import Response
from rest_framework import serializers
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import StaticHTMLRenderer
from django.conf import settings
from django.core.exceptions import PermissionDenied
from club.models import Club, Mailing
from rest_framework import serializers
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import StaticHTMLRenderer
from rest_framework.response import Response
from api.views import RightModelViewSet
from club.models import Club, Mailing
class ClubSerializer(serializers.ModelSerializer):

View File

@ -1,26 +1,29 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 rest_framework import serializers
from rest_framework.response import Response
from rest_framework.decorators import action
from counter.models import Counter
from rest_framework.response import Response
from api.views import RightModelViewSet
from counter.models import Counter
class CounterSerializer(serializers.ModelSerializer):

View File

@ -1,24 +1,27 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 rest_framework import serializers
from core.models import RealGroup
from api.views import RightModelViewSet
from core.models import RealGroup
class GroupSerializer(serializers.ModelSerializer):

View File

@ -1,26 +1,29 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 rest_framework import serializers
from rest_framework.response import Response
from rest_framework.decorators import action
from launderette.models import Launderette, Machine, Token
from rest_framework.response import Response
from api.views import RightModelViewSet
from launderette.models import Launderette, Machine, Token
class LaunderettePlaceSerializer(serializers.ModelSerializer):

View File

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

View File

@ -1,28 +1,31 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#
import datetime
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.decorators import action
from core.models import User
from rest_framework.response import Response
from api.views import RightModelViewSet
from core.models import User
class UserSerializer(serializers.ModelSerializer):

View File

@ -1,11 +1,12 @@
from rest_framework.response import Response
import json
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.renderers import JSONRenderer
from django.core.exceptions import PermissionDenied
from django.conf import settings
from rest_framework import serializers
import urllib.request
import json
from rest_framework.response import Response
from pedagogy.views import CanCreateUVFunctionMixin

View File

@ -1,15 +1,19 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#

View File

@ -1,17 +1,21 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 ajax_select import make_ajax_form
from django.contrib import admin

View File

@ -1,40 +1,32 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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 django.conf import settings
from ajax_select.fields import AutoCompleteSelectMultipleField
from django import forms
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
from club.models import Mailing, MailingSubscription, Club, Membership
from club.models import Club, Mailing, MailingSubscription, Membership
from core.models import User
from core.views.forms import SelectDate, SelectDateTime
from core.views.forms import SelectDate, TzAwareDateTimeField
from counter.models import Counter
from core.views.forms import TzAwareDateTimeField
class ClubEditForm(forms.ModelForm):

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,44 +1,37 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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 typing import Optional
from django.core.cache import cache
from django.db import models
from django.core import validators
from django.conf import settings
from django.core import validators
from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.core.validators import RegexValidator, validate_email
from django.db import models, transaction
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.utils import timezone
from django.core.validators import RegexValidator, validate_email
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from core.models import User, MetaGroup, Group, SithFile, RealGroup, Notification, Page
from core.models import Group, MetaGroup, Notification, Page, RealGroup, SithFile, User
# Create your models here.

View File

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

View File

@ -30,7 +30,7 @@
{% endif %}
</ul>
{% if object.club_account.exists() %}
<h4>{% trans %}Accouting: {% endtrans %}</h4>
<h4>{% trans %}Accounting: {% endtrans %}</h4>
<ul>
{% 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>

View File

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

View File

@ -1,26 +1,21 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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 django.urls import path

View File

@ -1,75 +1,62 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import csv
from django.conf import settings
from django import forms
from django.views.generic import ListView, DetailView, TemplateView, View
from django.views.generic.edit import DeleteView
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import UpdateView, CreateView
from django.core.exceptions import NON_FIELD_ERRORS, PermissionDenied, ValidationError
from django.core.paginator import InvalidPage, Paginator
from django.db.models import Sum
from django.http import (
HttpResponseRedirect,
HttpResponse,
Http404,
HttpResponseRedirect,
StreamingHttpResponse,
)
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.utils.translation import gettext as _t
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 django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView, TemplateView, View
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from core.views import (
CanCreateMixin,
CanViewMixin,
CanEditMixin,
CanEditPropMixin,
UserIsRootMixin,
TabedViewMixin,
PageEditViewBase,
DetailFormView,
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 counter.models import Selling
from com.views import (
PosterListBaseView,
PosterCreateBaseView,
PosterEditBaseView,
PosterDeleteBaseView,
from core.views import (
CanCreateMixin,
CanEditMixin,
CanEditPropMixin,
CanViewMixin,
DetailFormView,
PageEditViewBase,
TabedViewMixin,
UserIsRootMixin,
)
from club.models import Club, Membership, Mailing, MailingSubscription
from club.forms import MailingForm, ClubEditForm, ClubMemberForm, SellingsForm
from counter.models import Selling
class ClubTabsMixin(TabedViewMixin):
@ -611,7 +598,7 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
}
return kwargs
def add_new_mailing(self, cleaned_data) -> ValidationError:
def add_new_mailing(self, cleaned_data) -> ValidationError | None:
"""
Create a new mailing list from the form
"""
@ -628,7 +615,7 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
mailing.save()
return None
def add_new_subscription(self, cleaned_data) -> ValidationError:
def add_new_subscription(self, cleaned_data) -> ValidationError | None:
"""
Add mailing subscriptions for each user given and/or for the specified email in form
"""

View File

@ -1,15 +1,19 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#

View File

@ -1,17 +1,21 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 ajax_select import make_ajax_form
from django.contrib import admin

View File

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

View File

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

View File

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

View File

@ -1,44 +1,37 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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 django.shortcuts import render
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.mail import EmailMultiAlternatives
from django.db import models, transaction
from django.db.models import Q
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.shortcuts import render
from django.templatetags.static import static
from django.core.mail import EmailMultiAlternatives
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from core import utils
from core.models import User, Preferences, RealGroup, Notification, SithFile
from club.models import Club
from core import utils
from core.models import Notification, Preferences, RealGroup, User
class Sith(models.Model):

View File

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

View File

@ -1,63 +1,69 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#
import pytest
from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from django.conf import settings
from django.urls import reverse
from django.core.management import call_command
from django.utils import html
from django.utils.timezone import localtime, now
from django.utils.translation import gettext as _
from club.models import Club, Membership
from com.models import Sith, News, Weekmail, WeekmailArticle, Poster
from core.models import User, RealGroup, AnonymousUser
from com.models import News, Poster, Sith, Weekmail, WeekmailArticle
from core.models import AnonymousUser, RealGroup, User
class ComAlertTest(TestCase):
def test_page_is_working(self):
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.fixture()
def user_community():
return User.objects.get(username="comunity")
class ComInfoTest(TestCase):
def test_page_is_working(self):
self.client.login(username="comunity", password="plop")
response = self.client.get(reverse("com:info_edit"))
self.assertNotEqual(response.status_code, 500)
self.assertEqual(response.status_code, 200)
@pytest.mark.django_db
@pytest.mark.parametrize(
"url",
[
reverse("com:alert_edit"),
reverse("com:info_edit"),
],
)
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):
@classmethod
def setUpTestData(cls):
cls.skia = User.objects.filter(username="skia").first()
cls.skia = User.objects.get(username="skia")
cls.com_group = RealGroup.objects.filter(
id=settings.SITH_GROUP_COM_ADMIN_ID
).first()
cls.skia.groups.set([cls.com_group])
cls.skia.save()
def setUp(self):
self.client.login(username=self.skia.username, password="plop")
self.client.force_login(self.skia)
def test_alert_msg(self):
response = self.client.post(
self.client.post(
reverse("com:alert_edit"),
{
"alert_msg": """
@ -68,7 +74,6 @@ class ComTest(TestCase):
},
)
r = self.client.get(reverse("core:index"))
self.assertTrue(r.status_code == 200)
self.assertContains(
r,
"""<div id="alert_box">
@ -77,7 +82,7 @@ class ComTest(TestCase):
)
def test_info_msg(self):
response = self.client.post(
self.client.post(
reverse("com:info_edit"),
{
"info_msg": """
@ -86,7 +91,6 @@ class ComTest(TestCase):
},
)
r = self.client.get(reverse("core:index"))
self.assertTrue(r.status_code == 200)
self.assertContains(
r,
"""<div id="info_box">
@ -94,7 +98,7 @@ class ComTest(TestCase):
)
def test_birthday_non_subscribed_user(self):
self.client.login(username="guy", password="plop")
self.client.force_login(User.objects.get(username="guy"))
response = self.client.get(reverse("core:index"))
self.assertContains(
response,
@ -123,13 +127,13 @@ class SithTest(TestCase):
sith: Sith = Sith.objects.first()
com_admin = User.objects.get(username="comunity")
self.assertTrue(sith.is_owned_by(com_admin))
assert sith.is_owned_by(com_admin)
anonymous = AnonymousUser()
self.assertFalse(sith.is_owned_by(anonymous))
assert not sith.is_owned_by(anonymous)
sli = User.objects.get(username="sli")
self.assertFalse(sith.is_owned_by(sli))
assert not sith.is_owned_by(sli)
class NewsTest(TestCase):
@ -154,10 +158,10 @@ class NewsTest(TestCase):
or by their author but nobody else
"""
self.assertTrue(self.new.is_owned_by(self.com_admin))
self.assertTrue(self.new.is_owned_by(self.author))
self.assertFalse(self.new.is_owned_by(self.anonymous))
self.assertFalse(self.new.is_owned_by(self.sli))
assert self.new.is_owned_by(self.com_admin)
assert self.new.is_owned_by(self.author)
assert not self.new.is_owned_by(self.anonymous)
assert not self.new.is_owned_by(self.sli)
def test_news_viewer(self):
"""
@ -165,26 +169,26 @@ class NewsTest(TestCase):
and not moderated news only by com admins
"""
# by default a news isn't moderated
self.assertTrue(self.new.can_be_viewed_by(self.com_admin))
self.assertFalse(self.new.can_be_viewed_by(self.sli))
self.assertFalse(self.new.can_be_viewed_by(self.anonymous))
self.assertFalse(self.new.can_be_viewed_by(self.author))
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()
self.assertTrue(self.new.can_be_viewed_by(self.com_admin))
self.assertTrue(self.new.can_be_viewed_by(self.sli))
self.assertTrue(self.new.can_be_viewed_by(self.anonymous))
self.assertTrue(self.new.can_be_viewed_by(self.author))
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
"""
self.assertTrue(self.new.can_be_edited_by(self.com_admin))
self.assertFalse(self.new.can_be_edited_by(self.sli))
self.assertFalse(self.new.can_be_edited_by(self.anonymous))
self.assertFalse(self.new.can_be_edited_by(self.author))
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):
@ -207,10 +211,10 @@ class WeekmailArticleTest(TestCase):
"""
Test that weekmails are owned only by com admins
"""
self.assertTrue(self.article.is_owned_by(self.com_admin))
self.assertFalse(self.article.is_owned_by(self.author))
self.assertFalse(self.article.is_owned_by(self.anonymous))
self.assertFalse(self.article.is_owned_by(self.sli))
assert self.article.is_owned_by(self.com_admin)
assert not self.article.is_owned_by(self.author)
assert not self.article.is_owned_by(self.anonymous)
assert not self.article.is_owned_by(self.sli)
class PosterTest(TestCase):
@ -233,8 +237,8 @@ class PosterTest(TestCase):
"""
Test that poster are owned by com admins and board members in clubs
"""
self.assertTrue(self.poster.is_owned_by(self.com_admin))
self.assertFalse(self.poster.is_owned_by(self.anonymous))
assert 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.susbcriber))
self.assertTrue(self.poster.is_owned_by(self.sli))
assert not self.poster.is_owned_by(self.susbcriber)
assert self.poster.is_owned_by(self.sli)

View File

@ -1,17 +1,21 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 django.urls import path

View File

@ -1,60 +1,52 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
# 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"
#
# 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.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 smtplib import SMTPRecipientsRefused
from com.models import Sith, News, NewsDate, Weekmail, WeekmailArticle, Screen, Poster
from django import forms
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 (
CanViewMixin,
CanCreateMixin,
CanEditMixin,
CanEditPropMixin,
TabedViewMixin,
CanCreateMixin,
CanViewMixin,
QuickNotifMixin,
TabedViewMixin,
)
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
from core.views.forms import MarkdownInput, TzAwareDateTimeField
# Sith object

14
conftest.py Normal file
View File

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

View File

@ -1,15 +1,19 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#

View File

@ -1,25 +1,29 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 django.contrib import admin
from ajax_select import make_ajax_form
from core.models import User, Page, RealGroup, MetaGroup, SithFile
from django.contrib import admin
from django.contrib.auth.models import Group as AuthGroup
from haystack.admin import SearchModelAdmin
from core.models import MetaGroup, Page, RealGroup, SithFile, User
admin.site.unregister(AuthGroup)
admin.site.register(MetaGroup)

View File

@ -1,25 +1,21 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2017
# - Skia <skia@libskia.so>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import sys
@ -34,8 +30,8 @@ class SithConfig(AppConfig):
verbose_name = "Core app of the Sith"
def ready(self):
import core.signals # noqa F401
from forum.models import Forum
import core.signals
cache.clear()

View File

@ -1,3 +1,23 @@
# -*- 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

View File

@ -1,28 +1,31 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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 ajax_select import LookupChannel, register
from django.core.exceptions import PermissionDenied
from ajax_select import register, LookupChannel
from core.views.site import search_user
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
from club.models import Club
from core.models import Group, SithFile, User
from core.views.site import search_user
from counter.models import Counter, Customer, Product
def check_token(request):

View File

@ -1,15 +1,19 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#

View File

@ -1,15 +1,19 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#

View File

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

View File

@ -1,30 +1,27 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2019
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import os
from django.core.management.commands import compilemessages

View File

@ -1,32 +1,29 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2017
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import os
import sass
from django.core.management.base import BaseCommand
from django.conf import settings
from django.core.management.base import BaseCommand
class Command(BaseCommand):

View File

@ -1,33 +1,28 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2019
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import os
import sys
import signal
from http.server import test, CGIHTTPRequestHandler
import sys
from http.server import CGIHTTPRequestHandler, test
from django.core.management.base import BaseCommand
from django.utils import autoreload

View File

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

View File

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

View File

@ -1,28 +1,25 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2017
# - Skia <skia@libskia.so>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import os
from django.core.management.base import BaseCommand
from core.markdown import markdown

View File

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

View File

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

View File

@ -1,22 +1,27 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#
import os
from django.core.management.base import BaseCommand
from django.core.management import call_command
from django.core.management.base import BaseCommand
class Command(BaseCommand):

View File

@ -1,23 +1,28 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#
import os
import re
from mistune import Renderer, InlineGrammar, InlineLexer, Markdown, escape, escape_link
from django.urls import reverse
from mistune import InlineGrammar, InlineLexer, Markdown, Renderer, escape, escape_link
class SithRenderer(Renderer):

View File

@ -1,27 +1,32 @@
# -*- coding:utf-8 -*
# -*- 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 source code of the website at https://github.com/ae-utbm/sith3
# 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"
#
import importlib
import threading
from django.conf import settings
from django.utils.functional import SimpleLazyObject
from django.contrib.auth import get_user
from django.contrib.auth.middleware import (
AuthenticationMiddleware as DjangoAuthenticationMiddleware,
)
from django.utils.functional import SimpleLazyObject
module, klass = settings.AUTH_ANONYMOUS_MODEL.rsplit(".", 1)
AnonymousUser = getattr(importlib.import_module(module), klass)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,58 +1,56 @@
# -*- coding:utf-8 -*
## -*- coding:utf-8 -*-
#
# Copyright 2016,2017,2018
# - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import importlib
from typing import Union, Optional, List
import os
import unicodedata
from datetime import date, timedelta
from typing import List, Optional, Union
from django.core.cache import cache
from django.core.mail import send_mail
from django.conf import settings
from django.contrib.auth.models import (
AbstractBaseUser,
UserManager,
Group as AuthGroup,
GroupManager as AuthGroupManager,
)
from django.contrib.auth.models import (
AnonymousUser as AuthAnonymousUser,
)
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.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.utils.html import escape
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
import os
from core import utils
from django.utils.html import escape
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from datetime import timedelta, date
import unicodedata
from core import utils
class RealGroupManager(AuthGroupManager):
@ -698,9 +696,11 @@ class User(AbstractBaseUser):
<em>%s</em>
</a>
""" % (
self.profile_pict.get_download_url()
if self.profile_pict
else staticfiles_storage.url("core/img/unknown.jpg"),
(
self.profile_pict.get_download_url()
if self.profile_pict
else staticfiles_storage.url("core/img/unknown.jpg")
),
_("Profile"),
escape(self.get_display_name()),
)

View File

@ -1,31 +1,27 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
"""
This page is useful for custom migration tricks.
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.
This page is useful for custom migration tricks.
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.
"""
from django.db import connection, migrations

View File

@ -1,30 +1,27 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import os
from collections import OrderedDict
from django.conf import settings
from django.contrib.staticfiles.finders import FileSystemFinder
from django.core.files.storage import FileSystemStorage

View File

@ -1,35 +1,33 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2017
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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"
#
import os
import sass
from urllib.parse import urljoin
from django.utils.encoding import force_bytes, iri_to_uri
import sass
from django.conf import settings
from django.core.files.base import ContentFile
from django.templatetags.static import static
from django.conf import settings
from django.utils.encoding import force_bytes, iri_to_uri
from core.scss.storage import ScssFileStorage, find_file

View File

@ -1,26 +1,22 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2017
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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 django.conf import settings

View File

@ -1,30 +1,24 @@
# -*- coding:utf-8 -*
# -*- coding:utf-8 -*-
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# Copyright 2023 © AE UTBM
# ae@utbm.fr / ae.info@utbm.fr
# All contributors are listed in the CONTRIBUTORS file.
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
# This file is part of the website of the UTBM Student Association (AE UTBM),
# https://ae.utbm.fr.
#
# 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.
# You can find the whole source code at https://github.com/ae-utbm/sith3
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# 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.
# 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 django.db import models
from haystack import indexes, signals
from core.models import User

View File

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

View File

@ -203,11 +203,7 @@
<ul class="content">
<li><a href="{{ url('core:page', page_name='ae') }}">{% trans %}AE{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='clubs') }}">{% trans %}AE's clubs{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='bdf') }}">{% trans %}BdF{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='bds') }}">{% trans %}BDS{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='cetu') }}">{% trans %}CETU{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='clubs/doceo') }}">{% trans %}Doceo{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='positions') }}">{% trans %}Positions{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='utbm-associations') }}">{% trans %}Others UTBM's Associations{% endtrans %}</a></li>
</ul>
</div>
<div class="menu">

View File

@ -17,7 +17,7 @@
{% if user_registered %}
{% trans user_name=user_registered.get_display_name() %}Welcome {{ user_name }}!{% endtrans %}<br>
{% trans %}You successfully registred and you will soon receive a confirmation mail.{% endtrans %}<br>
{% trans %}You successfully registered and you will soon receive a confirmation mail.{% endtrans %}<br>
{% trans username=user_registered.username %}Your username is {{ username }}.{% endtrans %}<br>
{% else %}

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