Mise à jour de mars (#586)

---------

Co-authored-by: Thomas Girod <thgirod@hotmail.com>
Co-authored-by: Théo DURR <git@theodurr.fr>
This commit is contained in:
Julien Constant 2023-04-04 19:17:44 +02:00 committed by GitHub
parent 982fc09908
commit 4830c3ea2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
125 changed files with 4978 additions and 3243 deletions

18
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,18 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "pip" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
# Raise pull requests for version updates
# to pip against the `develop` branch
target-branch: "taiste"
reviewers:
- "ae-utbm/developpers-v3"
commit-message:
prefix: "[UPDATE] "

View File

@ -18,7 +18,7 @@ formats: all
# Optionally set the version of Python and requirements required to build your docs # Optionally set the version of Python and requirements required to build your docs
python: python:
version: 3.8 version: "3.8"
install: install:
- method: pip - method: pip
path: . path: .

View File

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

View File

@ -9,7 +9,7 @@
<img src="https://img.shields.io/readthedocs/sith-ae?logo=readthedocs&style=for-the-badge"> <img src="https://img.shields.io/readthedocs/sith-ae?logo=readthedocs&style=for-the-badge">
</a> </a>
<a href="https://discord.gg/XK9WfPsUFm"> <a href="https://discord.gg/XK9WfPsUFm">
<img src="https://img.shields.io/discord/889796155523874847?label=Discord&logo=discord&style=for-the-badge"> <img src="https://img.shields.io/discord/971448179075731476?label=Discord&logo=discord&style=for-the-badge">
</a> </a>
</p> </p>
@ -37,5 +37,4 @@
</li> </li>
</ul> </ul>
> This project is licenced under GNU GPL, see the LICENSE file at the top of the repository for more details. > This project is licensed under GNU GPL, see the LICENSE file at the top of the repository for more details.

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
from ajax_select import make_ajax_form from ajax_select import make_ajax_form

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
from ajax_select import make_ajax_form from ajax_select import make_ajax_form

View File

@ -36,6 +36,7 @@ from django.core.exceptions import ValidationError
from django.utils import timezone from django.utils import timezone
from core import utils
from core.models import User, Preferences, RealGroup, Notification, SithFile from core.models import User, Preferences, RealGroup, Notification, SithFile
from club.models import Club from club.models import Club
@ -46,6 +47,7 @@ class Sith(models.Model):
alert_msg = models.TextField(_("alert message"), default="", blank=True) alert_msg = models.TextField(_("alert message"), default="", blank=True)
info_msg = models.TextField(_("info message"), default="", blank=True) info_msg = models.TextField(_("info message"), default="", blank=True)
weekmail_destinations = models.TextField(_("weekmail destinations"), default="") weekmail_destinations = models.TextField(_("weekmail destinations"), default="")
version = utils.get_git_revision_short_hash()
def is_owned_by(self, user): def is_owned_by(self, user):
return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)

View File

@ -8,13 +8,13 @@
{% block content %} {% block content %}
{% if user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %} {% if user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %}
<div id="news_admin"> <div id="news_admin">
<a href="{{ url('com:news_admin_list') }}">{% trans %}Administrate news{% endtrans %}</a> <a class="button" href="{{ url('com:news_admin_list') }}">{% trans %}Administrate news{% endtrans %}</a>
</div> </div>
<br>
{% endif %} {% endif %}
<div id="news"> <div id="news">
<div id="left_column" class="news_column"> <div id="left_column" class="news_column">
{% for news in object_list.filter(type="NOTICE") %} {% for news in object_list.filter(type="NOTICE") %}
<section class="news_notice"> <section class="news_notice">
<h4><a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4> <h4><a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4>
@ -97,6 +97,15 @@
</section> </section>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
<h3>{% trans %}All coming events{% endtrans %}</h3>
<iframe
src="https://embed.styledcalendar.com/#2mF2is8CEXhr4ADcX6qN"
title="Styled Calendar"
class="styled-calendar-container"
style="width: 100%; border: none; height: 1060px"
data-cy="calendar-embed-iframe">
</iframe>
</div> </div>
<div id="right_column" class="news_column"> <div id="right_column" class="news_column">

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
@ -82,7 +74,7 @@ class ComTest(TestCase):
self.assertContains( self.assertContains(
r, r,
"""<div id="alert_box"> """<div id="alert_box">
<div class="markdown"><h3>ALERTE!</h3> <div class="markdown"><h3>ALERTE!</h3>
<p><strong>Caaaataaaapuuuulte!!!!</strong></p>""", <p><strong>Caaaataaaapuuuulte!!!!</strong></p>""",
) )
@ -100,7 +92,7 @@ class ComTest(TestCase):
self.assertContains( self.assertContains(
r, r,
"""<div id="info_box"> """<div id="info_box">
<div class="markdown"><h3>INFO: <strong>Caaaataaaapuuuulte!!!!</strong></h3>""", <div class="markdown"><h3>INFO: <strong>Caaaataaaapuuuulte!!!!</strong></h3>""",
) )
def test_birthday_non_subscribed_user(self): def test_birthday_non_subscribed_user(self):

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -13,7 +13,7 @@ class Migration(migrations.Migration):
model_name="preferences", model_name="preferences",
name="receive_weekmail", name="receive_weekmail",
field=models.BooleanField( field=models.BooleanField(
default=False, verbose_name="do you want to receive the weekmail" default=False, verbose_name="receive the weekmail"
), ),
) )
] ]

View File

@ -783,9 +783,7 @@ class Preferences(models.Model):
user = models.OneToOneField( user = models.OneToOneField(
User, related_name="_preferences", on_delete=models.CASCADE User, related_name="_preferences", on_delete=models.CASCADE
) )
receive_weekmail = models.BooleanField( receive_weekmail = models.BooleanField(_("receive the Weekmail"), default=False)
_("do you want to receive the weekmail"), default=False
)
show_my_stats = models.BooleanField(_("show your stats to others"), default=False) show_my_stats = models.BooleanField(_("show your stats to others"), default=False)
notify_on_click = models.BooleanField( notify_on_click = models.BooleanField(
_("get a notification for every click"), default=False _("get a notification for every click"), default=False

View File

@ -0,0 +1,433 @@
.header {
box-sizing: border-box;
background-color: #354a5f;
box-shadow: 3px 3px 3px 0 #dfdfdf;
border-radius: 0;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 10px;
gap: 10px;
@media (max-width: 700px) {
height: auto;
}
@media (max-width: 580px) {
justify-content: space-between;
}
&-logo {
display: flex;
flex-direction: row;
gap: 10px;
>a {
color: #fff;
}
&:hover>a {
color: #1a78b3;
}
@media (max-width: 607px) {
width: 100%;
justify-content: center;
}
&-picture {
height: 100%;
width: 65px;
display: flex;
background-position: center center;
background-size: contain;
background-repeat: no-repeat;
@media (max-width: 580px) {
height: auto;
}
}
&-text {
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
>span:first-child {
font-size: 1.43em;
}
>span:last-child {
font-size: .7em;
}
}
}
&-lang {
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 3px;
@media (max-width: 580px) {
flex-direction: row;
}
>form {
margin: 0;
box-sizing: border-box;
position: relative;
>input[type=submit] {
border-radius: 0;
margin: 0;
box-sizing: border-box;
background-color: #354a5f;
width: 45px;
height: 25px;
padding: 0;
color: white;
font-weight: normal;
line-height: 1.3em;
&:hover {
background-color: #283747;
}
}
}
}
&-disconnected {
box-sizing: border-box;
flex: 1;
display: flex;
justify-content: flex-end;
align-items: center;
@media (max-width: 607px) {
justify-content: center;
}
>.button {
box-sizing: border-box;
height: 35px;
background-color: transparent;
font-weight: normal;
padding: 5px 20px;
display: flex;
justify-content: center;
align-items: center;
text-transform: uppercase;
text-decoration: none;
color: white;
margin: 0;
font-size: .9em;
width: 120px;
&:hover {
background-color: #283747;
}
}
}
&-disconnected~&-lang {
@media (max-width: 662px) {
flex-direction: row;
width: 100%;
}
}
&-connected {
box-sizing: border-box;
flex: 1;
display: flex;
flex-direction: row;
@media (min-width: 400px) and (max-width: 1200px) {
flex-direction: column;
min-width: 100%;
justify-content: center;
align-items: center;
gap: 10px;
}
@media (max-width: 400px) {
flex-direction: column;
width: 100%;
gap: 10px;
padding: 0 10px;
}
>.right,
>.left {
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
@media (min-width: 400px) and (max-width: 1200px) {
width: 100%;
justify-content: space-between;
padding: 0 20px;
}
}
>.right {
flex: 1;
justify-content: flex-end;
>.user {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 15px;
@media (max-width: 1200px) {
width: 100%;
flex-direction: row-reverse;
justify-content: flex-end;
}
>a>img {
width: 40px;
height: 40px;
border-radius: 50%;
}
>.options {
display: flex;
flex-direction: column;
gap: 2px;
>.username {
display: flex;
justify-content: flex-end;
gap: 5px;
>a {
color: white;
&:hover {
color: #1a78b3;
}
}
}
>.links {
width: 100%;
display: flex;
justify-content: flex-end;
gap: 5px;
@media (max-width: 1200px) {
justify-content: flex-start;
}
>a {
text-align: right;
color: white;
&:hover {
color: #1a78b3;
}
&:last-child {
color: #eb2f06;
&:hover {
color: #cc2804;
}
}
}
}
}
}
>.notification {
height: 100%;
width: 55px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
>a {
color: white;
position: relative;
font-size: 25px;
&:hover {
color: #1a78b3;
}
>span {
color: white;
font-size: 14px;
display: flex;
justify-content: center;
align-items: center;
width: 10px;
height: 10px;
padding: 5px;
background-color: #eb2f06;
border-radius: 50%;
position: absolute;
top: -50%;
right: -50%;
}
}
>#header_notif {
box-sizing: border-box;
display: none;
position: absolute;
margin: 0;
background-color: whitesmoke;
top: calc(100% + 10px);
right: calc(50% - 30px);
width: 400px;
max-width: calc(100vw - 30px);
padding: 10px;
z-index: 100;
border-radius: 10px;
box-shadow: 3px 3px 3px 0 #767676;
>ul {
list-style-type: none;
margin: 0;
display: flex;
flex-direction: column;
gap: 10px;
min-height: 20px;
max-height: 120px;
overflow-y: auto;
>li {
>a {
.datetime {
display: flex;
justify-content: flex-start;
gap: 10px;
font-style: italic;
font-size: .8em;
}
}
&.empty-notification {
text-align: center;
font-style: italic;
}
}
}
.options {
width: 100%;
display: flex;
justify-content: space-between;
margin-top: 10px;
gap: 5px;
>a {
color: black;
padding: 5px;
width: 50%;
display: flex;
justify-content: center;
text-align: center;
align-items: center;
border-radius: 5px;
background-color: #ddd;
&:hover {
background-color: rgba(0, 0, 0, .2);
}
}
}
}
}
}
>.left {
gap: 10px;
display: flex;
@media (max-width: 1200px) {
flex-direction: row-reverse;
}
@media (max-width: 550px) {
flex-direction: column-reverse;
}
>form {
margin: 0;
width: 200px;
@media (max-width: 550px) {
width: 100%;
}
>input[type=text] {
box-sizing: border-box;
max-width: 100%;
width: 100%;
height: 35px;
border-radius: 5px;
font-size: .9em;
margin: 0;
background-color: #283747;
padding: 0 10px;
color: white;
}
}
}
}
&-connected~&-lang {
@media (max-width: 1200px) {
flex-direction: row;
width: 100%;
}
}
}
.bars {
list-style-type: none;
min-width: 120px;
margin: 0;
padding: 0;
@media(max-width: 1200px) {
display: flex;
flex-direction: row;
gap: 20px;
}
>li>a {
display: flex;
color: white;
&:hover {
color: #1a78b3;
}
>span {
margin-left: 10px;
}
>i {
width: 16px;
display: flex;
justify-content: center;
align-items: center;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -1,5 +1,3 @@
console.log('Guy');
$( function() { $( function() {
buttons = $(".choose_file_button"); buttons = $(".choose_file_button");
popups = $(".choose_file_widget"); popups = $(".choose_file_widget");

View File

@ -0,0 +1,110 @@
nav.navbar {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
background-color: hsl(203, 75%, 40%);
margin: 1em;
color: white;
border-radius: 0.6em;
@media (max-width: 500px) {
position: relative;
flex-direction: column;
align-items: flex-start;
gap: 0;
margin: .2em;
}
> .menu,
> .link {
box-sizing: border-box;
width: 130px;
height: 52px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
@media (max-width: 500px) {
width: 100%;
height: auto;
justify-content: flex-start;
&:first-child {
border-radius: .6em .6em 0 0;
}
&:last-child {
border-radius: 0 0 .6em .6em;
> .content {
box-shadow: 3px 3px 3px 0 #dfdfdf;
}
}
}
}
> .menu > .head,
> .link {
color: white;
padding: 10px 20px;
box-sizing: border-box;
@media (max-width: 500px) {
padding: 10px;
}
}
.link:hover,
.menu:hover {
background-color: rgba(0, 0, 0, .2);
}
> .menu:hover > .content,
> .menu > .head:hover + .content,
> .menu > .content:hover {
display: flex;
}
> .menu {
display: flex;
position: relative;
> .content {
z-index: 10;
display: none;
position: absolute;
top: 100%;
background-color: white;
margin: 0;
list-style-type: none;
width: 130px;
box-shadow: 3px 3px 3px 0 #dfdfdf;
flex-direction: column;
@media (max-width: 500px) {
position: absolute;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
box-shadow: inset 3px 3px 3px 0 #dfdfdf;
}
> li > a {
display: flex;
padding: 15px 20px;
@media (max-width: 500px) {
padding: 10px;
}
&:hover {
color: hsl(203, 75%, 40%);
background-color: rgba(0, 0, 0, .05);
}
}
}
}
}

View File

@ -48,6 +48,7 @@ body {
font-family: sans-serif; font-family: sans-serif;
} }
a.button,
button, button,
input[type="button"], input[type="button"],
input[type="submit"], input[type="submit"],
@ -60,11 +61,13 @@ input[type="file"] {
margin: 0.1em; margin: 0.1em;
font-size: 1.2em; font-size: 1.2em;
border-radius: 5px; border-radius: 5px;
color: black;
&:hover { &:hover {
background: hsl(0, 0%, 83%); background: hsl(0, 0%, 83%);
} }
} }
a.button,
input[type="button"], input[type="button"],
input[type="submit"], input[type="submit"],
input[type="reset"], input[type="reset"],
@ -72,10 +75,12 @@ input[type="file"] {
font-weight: bold; font-weight: bold;
} }
a.button:not(:disabled),
button:not(:disabled), button:not(:disabled),
input[type="button"]:not(:disabled), input[type="button"]:not(:disabled),
input[type="submit"]:not(:disabled), input[type="submit"]:not(:disabled),
input[type="reset"]:not(:disabled), input[type="reset"]:not(:disabled),
input[type="checkbox"]:not(:disabled),
input[type="file"]:not(:disabled) { input[type="file"]:not(:disabled) {
cursor: pointer; cursor: pointer;
} }
@ -99,6 +104,7 @@ textarea {
padding: 7px; padding: 7px;
font-size: 1.2em; font-size: 1.2em;
border-radius: 5px; border-radius: 5px;
font-family: sans-serif;
} }
select { select {
border: none; border: none;
@ -109,7 +115,8 @@ select {
border-radius: 5px; border-radius: 5px;
cursor: pointer; cursor: pointer;
} }
a {
a:not(.button) {
text-decoration: none; text-decoration: none;
color: $primary-dark-color; color: $primary-dark-color;
&:hover { &:hover {
@ -181,166 +188,6 @@ a {
/*--------------------------------HEADER-------------------------------*/ /*--------------------------------HEADER-------------------------------*/
#header_language_chooser {
position: absolute;
top: 2em;
left: 0.5em;
width: 3%;
min-width: 2.2em;
text-align: center;
input {
display: block;
width: 100%;
padding: 4px;
margin: 0px;
}
form {
display: block;
margin: 0.2em 0em;
width: 100%;
}
}
header {
width: 90%;
margin: 0 auto;
display: flex;
box-shadow: $shadow-color 0 0 15px;
border-top: none;
background-color: $primary-neutral-dark-color;
border-radius: 0px 0px 10px 10px;
#header_logo {
background-color: $white-color;
padding: 0.2em;
border-radius: 0 0 0 9px;
a {
display: flex;
align-items: center;
margin: 0px;
width: 100%;
height: 100%;
img {
max-width: 70%;
max-height: 100%;
margin: auto;
display: block;
}
}
}
#header_connect_links {
margin: 0.6em 0.6em 0 auto;
padding: 0.2em;
color: $white-color;
form {
display: inline;
width: 100%;
label {
display: inline;
}
}
}
#header_bar {
display: flex;
flex: auto;
flex-wrap: wrap;
align-items: center;
width: 80%;
a {
text-decoration: none;
margin: 0 1em;
font-weight: bold;
color: $white-color;
&:hover {
color: $secondary-color;
text-decoration: underline;
}
}
#header_bars_infos {
flex: initial;
list-style-type: none;
margin: 0.2em 0.2em;
}
#header_search {
display: inline-block;
flex: auto;
margin: 0.8em 0;
input {
width: 14ch;
}
}
#header_user_links {
display: flex;
flex: initial;
flex-wrap: wrap;
text-align: right;
margin: 0;
div {
display: inline;
padding: 1.2em 0;
&:first-child {
flex: auto;
}
}
.white {
background: $white-color;
a {
color: $black-color;
}
}
#header_notif {
display: none;
position: absolute;
max-height: 20em;
width: 22em;
overflow: auto;
list-style-type: none;
box-shadow: grey 1px 1px 5px;
background: white;
text-align: left;
font-size: 80%;
margin: 1.5em 0 0em -14em;
.header_notif_date {
font-weight: bold;
}
.header_notif_time {
color: grey;
}
a {
margin: 0;
color: $black-color;
&:hover {
color: $primary-dark-color;
}
}
li {
padding: 0.2em;
&:hover {
background: hsl(180, 14%, 77%);
}
}
li:last-child {
text-align: center;
a {
color: $primary-dark-color;
&:hover {
color: $primary-light-color;
}
}
}
}
}
}
}
#popupheader { #popupheader {
width: 88%; width: 88%;
margin: 0 auto; margin: 0 auto;
@ -350,8 +197,13 @@ header {
#info_boxes { #info_boxes {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
width: 90%; margin: 1em;
margin: 1em auto;
@media (max-width: 500px) {
margin: 0;
width: 100%;
}
#alert_box, #alert_box,
#info_box { #info_box {
flex: 49%; flex: 49%;
@ -388,75 +240,6 @@ header {
width: 90%; width: 90%;
margin: 20px auto 0; margin: 20px auto 0;
/*---------------------------------NAV---------------------------------*/ /*---------------------------------NAV---------------------------------*/
nav {
display: flex;
flex-wrap: wrap;
background-color: $primary-dark-color;
color: $white-color;
border-radius: 6px 6px 0 0;
box-shadow: $shadow-color 0 0 15px;
align-items: center;
a {
flex: auto;
text-align: center;
padding: 1.5em;
color: $white-color;
font-style: normal;
font-weight: bolder;
text-decoration: none;
&:hover {
background: $secondary-neutral-color;
color: $white-color;
&:first-of-type {
border-radius: 6px 0 0 0;
}
&:last-of-type {
border-radius: 0 6px 0 0;
}
}
}
.dropdown {
flex: auto;
text-align: center;
position: relative;
}
.dropbtn {
all: unset;
padding: 20px;
font-weight: bolder;
}
.dropdown-content {
display: none;
position: absolute;
overflow: auto;
width: 100%;
background-color: #f9f9f9;
box-shadow: 3px 3px 3px 0 $shadow-color;
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
display: block;
text-align: center;
&:hover {
border-radius: unset;
color: white;
background: $secondary-neutral-color;
}
}
.dropdown:hover .dropdown-content {
display: block;
}
}
.btn { .btn {
font-size: 15px; font-size: 15px;
@ -570,7 +353,11 @@ header {
/*---------------------------------NEWS--------------------------------*/ /*---------------------------------NEWS--------------------------------*/
#news { #news {
display: flex; display: flex;
flex-wrap: wrap;
@media (max-width: 800px) {
flex-direction: column;
}
.news_column { .news_column {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
@ -1120,32 +907,26 @@ h6 {
h1 { h1 {
font-size: 160%; font-size: 160%;
margin-left: 0;
} }
h2 { h2 {
font-size: 150%; font-size: 150%;
margin-left: 10px;
} }
h3 { h3 {
font-size: 140%; font-size: 140%;
margin-left: 20px;
} }
h4 { h4 {
font-size: 130%; font-size: 130%;
margin-left: 30px;
} }
h5 { h5 {
font-size: 120%; font-size: 120%;
margin-left: 40px;
} }
h6 { h6 {
font-size: 110%; font-size: 110%;
margin-left: 50px;
} }
p, p,
@ -1199,17 +980,37 @@ blockquote h5:first-child {
table { table {
width: 100%; width: 100%;
font-size: 0.9em; margin: 15px auto;
border-collapse: collapse;
border-spacing: 0;
border-radius: 5px;
-moz-border-radius: 5px;
overflow: hidden;
box-shadow: rgba(60, 64, 67, .3) 0 1px 3px 0, rgba(60, 64, 67, .15) 0 4px 8px 3px;
}
@media screen and (max-width: 500px){
table {
width: 100%;
}
} }
th { th {
padding: 4px; padding: 4px;
} }
td, th {
vertical-align: middle;
text-align: center;
padding: 5px 10px;
> ul {
margin-top: 0;
}
}
td { td {
padding: 4px; padding: 4px;
margin: 5px; margin: 5px;
border: solid 1px $primary-neutral-color;
border-collapse: collapse; border-collapse: collapse;
vertical-align: top; vertical-align: top;
overflow: hidden; overflow: hidden;
@ -1219,18 +1020,29 @@ td {
} }
} }
th, thead td {
text-align: center;
border-top: none;
}
thead { thead {
font-weight: bold; background-color: #354a5f;
color: white;
} }
tbody > tr { tbody > tr {
&:nth-child(even) { &:nth-child(even) {
background: $primary-neutral-light-color; background: $primary-neutral-light-color;
} }
&:hover { &.clickable:hover {
cursor: pointer;
background: $secondary-neutral-light-color; background: $secondary-neutral-light-color;
width: 100%; width: 100%;
} }
&.highlight {
color: $primary-dark-color;
font-style: italic;
}
} }
sup { sup {
@ -1297,88 +1109,6 @@ u,
/*-----------------------------USER PROFILE----------------------------*/ /*-----------------------------USER PROFILE----------------------------*/
#user_profile_page {
#user_profile {
display: flex;
justify-content: center;
margin-top: 2em;
margin-bottom: 4em;
#user_profile_infos {
flex-basis: 30%;
border-right: solid 1px grey;
div {
margin: 0.5em;
}
#user_profile_infos_items {
margin-top: 3em;
}
.user_profile_infos_item,
.user_profile_infos_item_value {
vertical-align: top;
display: inline-block;
width: 49%;
}
.user_profile_infos_item {
color: grey;
}
#user_profile_infos_promo {
display: flex;
align-items: center;
img {
width: 5em;
margin: 0.5em;
}
}
#user_profile_infos_quote {
text-align: right;
color: grey;
font-style: italic;
&:after,
&:before {
content: "\201C";
vertical-align: middle;
}
}
}
#user_profile_pictures {
height: 20em;
flex-basis: 30%;
display: flex;
justify-content: flex-end;
#user_profile_pictures_bigone {
flex-grow: 9;
flex-basis: 20em;
display: flex;
justify-content: center;
align-items: center;
img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
}
#user_profile_pictures_thumbnails {
flex-grow: 1;
flex-basis: 50px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
img {
margin: 0.1em;
width: 50px;
}
}
}
@media screen and (max-width: $small-devices) {
#user_profile_infos,
#user_profile_pictures {
flex-basis: 50%;
}
}
}
}
.user_mini_profile { .user_mini_profile {
height: 100%; height: 100%;
width: 100%; width: 100%;
@ -1660,47 +1390,6 @@ textarea {
} }
} }
/*------------------------------SAS------------------------------------*/
.album {
display: inline-block;
border: solid 1px $black-color;
text-align: center;
padding: 5px;
width: 200px;
height: 140px;
background: hsl(0, 0%, 93%);
box-shadow: black 2px 2px 10px;
margin: 10px;
vertical-align: top;
img {
max-height: 100px;
}
}
.picture {
display: inline-block;
border: solid 1px $black-color;
width: 150px;
height: 100px;
margin: 5px;
background: #eeeeee;
box-shadow: grey 2px 2px 5px;
padding: 2px;
vertical-align: middle;
img {
max-width: 100%;
max-height: 100px;
display: block;
margin: auto;
}
}
.not_moderated {
border: solid 1px red;
box-shadow: red 2px 2px 10px;
}
/*--------------------------------FOOTER-------------------------------*/ /*--------------------------------FOOTER-------------------------------*/
footer { footer {
@ -1716,18 +1405,24 @@ footer {
border-radius: 5px; border-radius: 5px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center;
background-color: $primary-neutral-dark-color; background-color: $primary-neutral-dark-color;
box-shadow: $shadow-color 0 0 15px; box-shadow: $shadow-color 0 0 15px;
a { a {
padding: 0.8em; padding: 0.8em;
flex: 1; flex: 1;
font-weight: bold; font-weight: bold;
color: $white-color; color: $white-color !important;
&:hover { &:hover {
color: $primary-dark-color; color: $primary-dark-color;
} }
} }
} }
> .version {
margin-top: 3px;
color: rgba(0, 0, 0, .3)
}
} }
/*---------------------------------FORMS-------------------------------*/ /*---------------------------------FORMS-------------------------------*/
@ -2350,4 +2045,4 @@ $pedagogy-white-text: #f0f0f0;
} }
} }
} }
} }

View File

@ -0,0 +1,24 @@
.activity-description {
display: flex;
flex-direction: column;
gap: 5px;
width: 100%;
margin-top: 10px;
> div {
display: flex;
flex-direction: row;
gap: 10px;
> span {
text-align: left;
}
> i {
width: 16px;
display: flex;
justify-content: center;
align-items: center;
}
}
}

249
core/static/sas/album.scss Normal file
View File

@ -0,0 +1,249 @@
main {
box-sizing: border-box;
padding: 10px;
}
.navbar {
margin-top: 10px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 10px;
justify-content: space-between;
}
.toolbar {
display: flex;
align-items: flex-end;
flex-wrap: wrap;
gap: 5px;
> a,
> input {
padding: 0.4em;
margin: 0.1em;
font-size: 1.2em;
line-height: 1.2em;
color: black;
background-color: #f2f2f2;
border-radius: 5px;
font-weight: bold;
&:hover {
background-color: #d4d4d4;
}
&:disabled {
background-color: #f2f2f2;
color: #d4d4d4;
}
}
}
.add-files {
display: flex;
flex-direction: column;
> .inputs {
align-items: flex-end;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 10px;
> p {
box-sizing: border-box;
max-width: 300px;
width: 100%;
@media (max-width: 500px) {
max-width: 100%;
}
> input {
box-sizing: border-box;
max-width: 100%;
width: 100%;
height: 40px;
line-height: normal;
font-size: 16px;
}
}
> div > input,
> input {
box-sizing: border-box;
height: 40px;
width: 100%;
max-width: 300px;
@media (max-width: 500px) {
max-width: 100%;
}
}
> div {
width: 100%;
max-width: 300px;
}
> input[type=submit]:hover {
background-color: #287fb8;
color: white;
}
}
}
.clipboard {
margin-top: 10px;
padding: 10px;
background-color: rgba(0,0,0,.1);
border-radius: 10px;
}
.paginator {
display: flex;
justify-content: center;
gap: 10px;
width: -moz-fit-content;
width: fit-content;
background-color: rgba(0,0,0,.1);
border-radius: 10px;
padding: 10px;
margin: 10px 0 10px auto;
}
.photos,
.albums {
box-sizing: border-box;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 5px;
> div {
background: rgba(0, 0, 0, .5);
cursor: not-allowed;
}
> div,
> a {
box-sizing: border-box;
position: relative;
height: 128px;
@media (max-width: 500px) {
width: calc(50% - 5px);
height: 108px;
}
@media (max-width: 300px) {
width: 100%;
}
&:hover {
background: rgba(0, 0, 0, .5);
}
> input[type=checkbox] {
position: absolute;
top: 0;
right: 0;
height: 15px;
width: 15px;
margin: 5px;
cursor: pointer;
}
> .photo,
> .album {
box-sizing: border-box;
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
width: calc(16 / 9 * 128px);
height: 128px;
margin: 0;
padding: 0;
box-shadow: none;
border: 1px solid rgba(0, 0, 0, .3);
@media (max-width: 500px) {
width: 100%;
height: 100%;
}
&:hover > .text {
background-color: rgba(0, 0, 0, .5);
}
&:hover > .overlay {
-webkit-backdrop-filter: blur(2px);
backdrop-filter: blur(2px);
~ .text {
background-color: transparent;
}
}
> .text {
position: absolute;
box-sizing: border-box;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: flex-start;
padding: 10px;
color: white;
}
> .overlay {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
&::before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: '⚠️';
color: white;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, .5);
-webkit-backdrop-filter: blur(5px);
backdrop-filter: blur(5px);
}
}
}
> .album > div {
background: rgba(0, 0, 0, .5);
background: linear-gradient(0deg, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, 0) 100%);
text-align: left;
word-break: break-word;
}
> .photo > .text {
align-items: center;
padding-bottom: 30px;
}
}
}

View File

@ -0,0 +1,309 @@
#content {
padding: 10px !important;
}
.title {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.container {
display: flex;
flex-direction: row;
gap: 10px;
@media (max-width: 1000px) {
flex-direction: column;
}
}
.main {
display: flex;
flex-direction: column;
width: calc(75% - 5px);
gap: 10px;
@media (max-width: 1000px) {
width: 100%;
}
> .photo {
box-sizing: border-box;
height: 500px;
display: flex;
justify-content: center;
background-color: #333333;
padding: 5px;
@media (max-width: 1000px) {
width: 100%;
height: auto;
}
> img {
height: 100%;
max-width: 100%;
object-fit: contain;
}
}
}
.subsection {
width: calc(25% - 5px);
@media (max-width: 1000px) {
width: 100%;
}
> .navigation {
display: flex;
flex-direction: row;
gap: 10px;
@media (max-width: 1000px) {
width: 100%;
}
> #prev,
> #next {
width: calc(50% - 5px);
aspect-ratio: 16/9;
background: #aaa;
> a {
display: flex;
position: relative;
width: 100%;
height: 100%;
> div {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
color: white;
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
&::before {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, .3);
}
}
}
}
> #prev > a > div::before {
content: '';
}
> #next > a > div::before {
content: '';
}
}
> .tags {
@media (min-width: 1001px) {
margin-right: 5px;
}
> ul {
list-style-type: none;
margin: 0;
display: flex;
flex-direction: column;
gap: 5px;
@media (max-width: 1000px) {
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
margin-right: 5px;
}
> li {
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
justify-content: space-between;
@media (max-width: 1000px) {
max-width: calc(50% - 5px);
}
> a {
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
&.user {
width: 100%;
background-color: #eee;
padding: 5px 10px 5px 5px;
border-radius: 5px;
color: black;
max-width: calc(100% - 40px);
min-height: 30px;
&:hover {
background-color: #aaa;
}
> span {
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
&.delete {
margin-left: 10px;
}
> img {
width: 25px;
max-height: 25px;
object-fit: contain;
border-radius: 50%;
}
}
}
}
> form {
> p {
box-sizing: border-box;
> input {
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
}
> .results_on_deck > div {
position: relative;
display: flex;
align-items: center;
word-break: break-word;
> span {
position: absolute;
top: 0;
right: 0;
}
}
> input {
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
}
}
}
.general {
display: flex;
flex-direction: row;
gap: 20px;
@media (max-width: 1000px) {
flex-direction: column;
}
> .infos {
display: flex;
flex-direction: column;
> div > div {
display: flex;
flex-direction: row;
justify-content: space-between;
> *:first-child {
min-width: 150px;
@media (max-width: 1000px) {
min-width: auto;
}
}
}
}
> .tools {
display: flex;
flex-direction: column;
width: 100%;
> div {
display: flex;
flex-direction: row;
justify-content: space-between;
> div {
> a.button {
box-sizing: border-box;
background-color: #f2f2f2;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
color: black;
border-radius: 5px;
width: 40px;
height: 40px;
&:hover {
background-color: #aaa;
}
}
> a.text.danger {
color: red;
&:hover {
color: darkred;
}
}
&.buttons {
display: flex;
gap: 5px;
}
}
}
}
}
.moderation {
box-sizing: border-box;
width: 100%;
border: 2px solid coral;
border-radius: 2px;
padding: 10px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
> div:last-child {
display: flex;
gap: 20px;
}
}

108
core/static/user/login.scss Normal file
View File

@ -0,0 +1,108 @@
html,
body {
box-sizing: border-box;
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
#page {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
#content {
display: flex;
flex-direction: column;
padding: 10px;
box-shadow: none;
background-color: white;
margin: 0;
> .title {
text-align: center;
margin: 0;
}
> div,
> form {
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
width: 100%;
max-width: 500px;
margin-top: 20px;
> p,
> div {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
margin: 0;
> label {
width: 100%;
@media (min-width: 500px) {
width: 300px;
}
}
}
> input,
> p > input,
> div > input {
box-sizing: border-box;
width: 100%;
max-width: 500px;
@media (min-width: 500px) {
max-width: 300px;
}
}
> .errorlist {
color: red;
text-align: center;
margin: 10px 0 0 0;
list-style-type: none;
}
> .required > .helptext {
text-align: center;
font-style: italic;
}
> .required:last-of-type {
box-sizing: border-box;
max-width: 300px;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
> label {
width: 100%;
}
> img {
width: 70px;
object-fit: contain;
}
> input {
width: 200px;
}
}
}
}
}

View File

@ -0,0 +1,200 @@
main {
box-sizing: border-box;
display: flex;
margin-bottom: 4em;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px;
width: 100%;
> .user_profile > .user_profile_infos {
@media (max-width: 960px) {
border-right-color: transparent;
}
}
}
.user-name {
display: flex;
flex-direction: column;
align-items: flex-start;
width: 100%;
max-width: 1080px;
margin: 0 auto;
}
.infos-and-picture {
display: flex;
flex-direction: row;
justify-content: center;
width: 100%;
max-width: 1080px;
margin: 0 auto;
@media (max-width: 960px) {
flex-direction: column-reverse;
gap: 20px;
}
> .user_profile_infos {
width: 50%;
border-right: solid 1px grey;
@media (max-width: 960px) {
width: 100%;
}
@media (min-width: 960px) {
padding-right: 20px;
}
> .user_profile_infos_promo {
display: flex;
flex-direction: row;
gap: 10px;
align-items: center;
justify-content: center;
width: 100%;
> img {
width: 5em;
margin: 0.5em;
}
}
> .user_profile_infos_items {
margin-top: 30px;
display: flex;
flex-direction: column;
gap: 5px;
> div {
box-sizing: border-box;
display: flex;
> .user_profile_infos_item,
> .user_profile_infos_item_value {
vertical-align: top;
display: block;
width: 50%;
}
> .user_profile_infos_item {
color: gray;
}
}
}
> #user_profile_infos_quote {
text-align: right;
color: grey;
font-style: italic;
@media (max-width: 960px) {
text-align: center;
}
&:after,
&:before {
vertical-align: middle;
}
&:before {
content: "\201C";
}
&:after {
content: "\201D";
}
}
}
> .user_profile_pictures {
height: 20em;
width: 50%;
display: flex;
flex-direction: row;
justify-content: flex-end;
@media (max-width: 960px) {
width: 100%;
height: 100%;
flex-direction: column;
}
@media (min-width: 960px) {
padding-left: 20px;
}
> .user_profile_pictures_bigone {
flex-grow: 9;
flex-basis: 20em;
display: flex;
justify-content: center;
align-items: center;
> img {
max-height: 100%;
max-width: 100%;
object-fit: contain;
@media (max-width: 960px) {
max-width: 300px;
width: 100%;
object-fit: contain;
}
}
}
> .user_profile_pictures_thumbnails {
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 20px;
flex-grow: 1;
@media (max-width: 960px) {
flex-direction: row;
height: 50%;
}
> img {
max-height: calc(100% / 3);
width: 100%;
object-fit: contain;
@media (max-width: 960px) {
max-height: 100%;
max-width: calc(100% / 3) !important;
height: auto;
}
}
}
}
}
.form-gifts {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: 10px;
@media (max-width: 960px) {
flex-direction: column;
}
>select,
>input {
min-width: 300px;
max-width: 100%;
height: 40px;
@media (max-width: 960px) {
width: 100%;
}
}
}

View File

@ -0,0 +1,193 @@
@media (max-width: 750px) {
.title {
text-align: center;
}
}
.field-error {
height: auto !important;
> ul {
list-style-type: none;
margin: 0;
color: indianred;
> li {
text-align: left !important;
line-height: normal;
margin-top: 5px;
}
}
}
.profile {
&-visible {
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
padding-top: 10px;
}
&-pictures {
box-sizing: border-box;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
gap: 40px;
align-items: stretch;
@media (max-width: 750px) {
flex-direction: column;
gap: 10px
}
}
&-picture {
box-sizing: border-box;
display: flex;
justify-content: space-between;
flex-direction: column;
align-items: center;
flex-wrap: wrap;
gap: 20px;
width: 100%;
height: 100%;
max-width: 300px;
@media (max-width: 750px) {
max-width: 100%;
padding: 10px 10px 0;
}
&-display {
display: flex;
flex-direction: column;
justify-content: center;
height: 300px;
gap: 10px;
@media (max-width: 750px) {
height: auto;
}
>img {
width: 100% !important;
object-fit: contain;
height: auto;
}
>p {
text-align: left !important;
width: 100% !important;
}
}
&-edit {
display: flex;
flex-direction: column-reverse;
align-items: center;
justify-content: center;
width: 100%;
> a {
margin-bottom: 15px;
}
> input {
font-size: .8em;
font-weight: normal;
cursor: pointer;
}
> p {
margin-bottom: 0;
text-align: left !important;
min-height: 50px;
}
}
}
&-fields {
padding: 10px 10px 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}
&-field {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
width: 100%;
max-width: 330px;
min-width: 300px;
@media (max-width: 750px) {
gap: 4px;
max-width: 100%;
}
>* {
width: 100%;
max-width: 300px;
@media (max-width: 750px) {
max-width: 100%;
}
}
&-label {
text-align: left !important;
}
&-content {
>* {
box-sizing: border-box;
text-align: left !important;
line-height: 40px;
max-width: 100%;
width: 100%;
height: 40px;
margin: 0;
>* {
text-align: left !important;
}
}
>textarea {
height: 120px;
min-height: 40px;
min-width: 300px;
max-width: 300px;
line-height: initial;
@media (max-width: 750px) {
max-width: 100%;
}
}
>input[type="file"] {
font-size: small;
line-height: 30px;
}
>input[type="checkbox"] {
width: 20px;
height: 20px;
margin: 0;
float: left;
}
}
}
}

View File

@ -0,0 +1,113 @@
.container {
display: flex;
flex-direction: column;
gap: 10px;
padding: 10px;
box-sizing: border-box;
> form {
margin: 0;
}
}
.users {
display: flex;
flex-direction: row;
flex-wrap: wrap;
list-style-type: none;
margin: 0;
gap: 10px
}
.users-card {
display: flex;
flex-direction: column;
gap: 10px;
width: 150px;
padding: 10px;
background-color: rgba(0, 0, 0, .05);
border-radius: 10px;
@media (max-width: 375px) {
width: 100%;
}
// Django moment
> div.mini_profile_link {
position: relative;
> a {
&.mini_profile_link {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 10px;
@media (max-width: 375px) {
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
max-height: 65px;
}
> span {
height: 150px;
width: 100%;
@media (max-width: 375px) {
height: 80px;
width: 80px;
}
> img {
width: 100%;
max-width: 100%;
max-height: 100%;
height: auto;
object-fit: contain;
@media (max-width: 375px) {
max-width: 100%;
max-height: 80px;
}
}
}
> em {
box-sizing: border-box;
padding: 0 5px;
text-align: center;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
@media (max-width: 375px) {
margin-top: 10px;
text-align: left;
max-width: none;
width: 100%;
}
}
}
&:last-of-type {
margin-top: 10px;
display: block;
text-align: center;
color: orangered;
@media (max-width: 375px) {
position: absolute;
bottom: 0%;
right: 0;
}
}
}
}
// Django moment
> a.mini_profile_link {
display: none;
}
}

View File

@ -0,0 +1,12 @@
#id_groups {
margin: 0;
>li {
list-style-type: none;
padding-left: 20px;
>label {
cursor: pointer;
}
}
}

View File

@ -0,0 +1,58 @@
.form {
display: flex;
flex-direction: column;
margin: 10px 0;
gap: 5px;
&-general {
> p {
display: flex;
flex-direction: row-reverse;
justify-content: left;
align-items: center;
gap: 5px;
margin: 0;
> label {
cursor: pointer;
margin: 0;
}
}
}
&-cards,
&-trombi {
>p {
display: flex;
flex-direction: column;
align-items: flex-start;
text-align: justify;
gap: 5px;
margin: 0;
>input,
>select {
min-width: 300px;
}
}
}
&-submit-btn {
margin-top: 10px !important;
max-width: 100px;
}
}
.justify {
text-align: justify;
}
.main {
padding: 10px;
}
.no-cards,
.student-cards {
margin-top: 10px;
display: block;
}

View File

@ -0,0 +1,48 @@
.container {
padding: 10px;
display: flex;
flex-direction: column;
gap: 10px;
}
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
margin-bottom: 10px;
gap: 30px;
@media (max-width: 535px) {
gap: 20px;
>div,
>div>.flexed {
width: 100%;
align-items: stretch;
}
}
}
.flexed {
display: flex;
flex-direction: column;
gap: 2px;
align-items: self-start;
>div {
display: flex;
justify-content: space-between;
>b,
>span {
width: 120px;
&:last-child {
text-align: right;
}
}
}
}

View File

@ -0,0 +1,91 @@
main {
box-sizing: border-box;
padding: 10px;
}
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
margin-top: 20px;
gap: 10px;
> div {
border-radius: 10px;
background-color: rgba(0, 0, 0, .05);
width: 210px;
> h4 {
text-align: center;
}
> ul {
list-style-type: none;
margin: 20px 10px;
display: flex;
flex-direction: column;
gap: 10px;
> .rows {
display: flex;
flex-direction: column;
gap: 5px;
> span {
margin-top: 5px;
}
> span > span,
> span {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 5px;
width: 100%;
>.button {
font-size: smaller;
width: 100%;
margin: 0;
}
> span {
display: flex;
flex-direction: row;
width: 100%;
> .button {
width: 100%;
}
}
}
> span > span {
flex-wrap: nowrap;
}
}
> .counter {
background-color: rgba(0, 0, 0, .05);
border-radius: 5px;
padding: 10px;
@media (max-width: 550px) {
background-color: rgba(0, 0, 0, .1);
}
}
}
}
@media (max-width: 550px) {
>div {
width: 100%;
background-color: transparent;
>h4 {
text-align: left;
}
}
}
}

View File

@ -2,27 +2,32 @@
<html lang="fr"> <html lang="fr">
<head> <head>
{% block head %} {% block head %}
<title>{% block title %}{% trans %}Welcome!{% endtrans %}{% endblock %} - Association des Étudiants UTBM</title> <title>{% block title %}{% trans %}Welcome!{% endtrans %}{% endblock %} - Association des Étudiants UTBM</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="{{ static('core/img/favicon.ico') }}"> <link rel="shortcut icon" href="{{ static('core/img/favicon.ico') }}">
<link rel="stylesheet" href="{{ static('core/base.css') }}"> <link rel="stylesheet" href="{{ static('core/base.css') }}">
<link rel="stylesheet" href="{{ static('core/jquery.datetimepicker.min.css') }}"> <link rel="stylesheet" href="{{ static('core/jquery.datetimepicker.min.css') }}">
<link rel="stylesheet" href="{{ static('ajax_select/css/ajax_select.css') }}"> <link rel="stylesheet" href="{{ static('ajax_select/css/ajax_select.css') }}">
<link rel="stylesheet" href="{{ scss('core/style.scss') }}"> <link rel="stylesheet" href="{{ scss('core/style.scss') }}">
{% block jquery_css %} <link rel="stylesheet" href="{{ scss('core/header.scss') }}">
{# Thile file is quite heavy (around 250kb), so declaring it in a block allows easy removal #} <link rel="stylesheet" href="{{ scss('core/navbar.scss') }}">
<link rel="stylesheet" href="{{ static('core/js/ui/jquery-ui.min.css') }}">
{% endblock %}
<link rel="preload" as="style" href="{{ static('core/font-awesome/css/font-awesome.min.css') }}" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="{{ static('core/font-awesome/css/font-awesome.min.css') }}"></noscript>
<script defer href="{{ static('core/font-awesome/js/fontawesone.min.js') }}"></script>
<!-- Jquery declared here to be accessible in every django widgets --> {% block jquery_css %}
<script src="{{ static('core/js/jquery-3.6.2.min.js') }}"></script> {# Thile file is quite heavy (around 250kb), so declaring it in a block allows easy removal #}
<!-- Put here to always have acces to those functions on django widgets --> <link rel="stylesheet" href="{{ static('core/js/ui/jquery-ui.min.css') }}">
<script src="{{ static('core/js/script.js') }}"></script> {% endblock %}
{% block additional_css %}{% endblock %}
{% block additional_js %}{% endblock %} <link rel="preload" as="style" href="{{ static('core/font-awesome/css/font-awesome.min.css') }}" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="{{ static('core/font-awesome/css/font-awesome.min.css') }}"></noscript>
<script defer href="{{ static('core/font-awesome/js/fontawesone.min.js') }}"></script>
<!-- Jquery declared here to be accessible in every django widgets -->
<script src="{{ static('core/js/jquery-3.6.2.min.js') }}"></script>
<!-- Put here to always have acces to those functions on django widgets -->
<script src="{{ static('core/js/script.js') }}"></script>
{% block additional_css %}{% endblock %}
{% block additional_js %}{% endblock %}
{% endblock %} {% endblock %}
</head> </head>
@ -33,197 +38,215 @@
{% csrf_token %} {% csrf_token %}
<!-- BEGIN HEADER --> <!-- BEGIN HEADER -->
{% block header %} {% block header %}
{% if not popup %} {% if not popup %}
<header> <header class="header">
<div id="header_language_chooser"> <div class="header-logo">
{% for language in LANGUAGES %} <a class="header-logo-picture" href="{{ url('core:index') }}" style="background-image: url('{{ static('core/img/logo_no_text.png') }}')">
<form action="{{ url('set_language') }}" method="post">{% csrf_token %} &nbsp;
<input name="next" value="{{ request.path }}" type="hidden" /> </a>
<input name="language" value="{{ language[0] }}" type="hidden" /> <a class="header-logo-text" href="{{ url('core:index') }}">
<input type="submit" value="{{ language[0]|upper }}" /> <span>Association des Étudiants</span>
</form> <span>de l'Université de Technologie de Belfort-Montbéliard</span>
{% endfor %} </a>
</div> </div>
<div id="header_logo"> {% if not user.is_authenticated %}
<a href="{{ url('core:index') }}"> <div class="header-disconnected">
<img src="{{ static('core/img/logo.png') }}" alt="AE logo"> <a class="button" href="{{ url('core:login') }}">{% trans %}Login{% endtrans %}</a>
</a> <a class="button" href="{{ url('core:register') }}">{% trans %}Register{% endtrans %}</a>
</div> </div>
{% if not user.is_authenticated %} {% else %}
<div id="header_connect_links"> <div class="header-connected">
<form method="post" action="{{ url('core:login') }}"> <div class="left">
{% csrf_token %} <form class="search" action="{{ url('core:search') }}" method="GET" id="header_search">
<label for="id_username">{% trans %}Username{% endtrans %}</label> <input class="header-input" type="text" placeholder="{% trans %}Search{% endtrans %}" name="query" id="search" />
<input id="id_username" maxlength="254" name="username" type="text"> <input type="submit" value="{% trans %}Search{% endtrans %}" style="display: none;" />
<label for="id_password">{% trans %}Password{% endtrans %}</label> </form>
<input type="password" name="password" id="id_password"> <ul class="bars">
<input type="submit" value="{% trans %}Login{% endtrans %}"> {% cache 100 "counters_activity" %}
</form> {% for bar in Counter.objects.annotate_has_barman(user).filter(type="BAR") %}
<a href="{{ url('core:register') }}"><button type="button">{% trans %}Register{% endtrans %}</button></a> <li>
</div> {# If the user is a barman, we redirect him directly to the barman page
else we redirect him to the activity page #}
{% if bar.has_annotated_barman %}
<a href="{{ url('counter:details', counter_id=bar.id) }}">
{% else %}
<a href="{{ url('counter:activity', counter_id=bar.id) }}">
{% endif %}
{% if bar.is_inactive() %}
<i class="fa fa-question" style="color: #f39c12"></i>
{% elif bar.is_open(): %}
<i class="fa fa-check" style="color: #2ecc71"></i>
{% else %}
<i class="fa fa-times" style="color: #eb2f06"></i>
{% endif %}
<span>{{ bar }}</span>
</a>
</li>
{% endfor %}
{% endcache %}
</ul>
</div>
<div class="right">
<div class="user">
<div class="options">
<div class="username">
<a href="{{ url('core:user_profile', user_id=user.id) }}">{{ user.get_display_name() }}</a>
</div>
<div class="links">
<a href="{{ url('core:user_tools') }}">{% trans %}Tools{% endtrans %}</a>
<a href="{{ url('core:logout') }}">{% trans %}Logout{% endtrans %}</a>
</div>
</div>
<a href="{{ url('core:user_profile', user_id=user.id) }}">
{% if user.profile_pict %}
<img src="{{ user.profile_pict.get_download_url() }}" alt="{% trans %}Profile{% endtrans %}" title="{% trans %}Profile{% endtrans %}" />
{% else %}
<img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Profile{% endtrans %}" title="{% trans %}Profile{% endtrans %}" />
{% endif %}
</a>
</div>
<div class="notification">
<a href="#" onclick="display_notif()">
<i class="fa fa-bell-o"></i>
{% set notification_count = user.notifications.filter(viewed=False).count() %}
{% if notification_count > 0 %}
<span>
{% if notification_count < 100 %}
{{ notification_count }}
{% else %}
&nbsp;
{% endif %}
</span>
{% endif %}
</a>
<div id="header_notif">
<ul>
{% if user.notifications.filter(viewed=False).count() > 0 %}
{% for n in user.notifications.filter(viewed=False).order_by('-date') %}
<li>
<a href="{{ url("core:notification", notif_id=n.id) }}">
<div class="datetime">
<span class="header_notif_date">
{{ n.date|localtime|date(DATE_FORMAT) }}
</span>
<span class="header_notif_time">
{{ n.date|localtime|time(DATETIME_FORMAT) }}
</span>
</div>
<div class="reason">
{{ n }}
</div>
</a>
</li>
{% endfor %}
{% else %}
<li class="empty-notification">{% trans %}You do not have any unread notification{% endtrans %}</li>
{% endif %}
</ul>
<div class="options">
<a href="{{ url('core:notification_list') }}">
{% trans %}View more{% endtrans %}
</a>
<a href="{{ url('core:notification_list') }}?see_all">
{% trans %}Mark all as read{% endtrans %}
</a>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<div class="header-lang">
{% for language in LANGUAGES %}
<form action="{{ url('set_language') }}" method="post">
{% csrf_token %}
<input name="next" value="{{ request.path }}" type="hidden" />
<input name="language" value="{{ language[0] }}" type="hidden" />
<input type="submit" value="{% if language[0] == 'en' %}🇬🇧{% else %}🇫🇷{% endif %}" />
</form>
{% endfor %}
</div>
</header>
{% block info_boxes %}
<div id="info_boxes">
{% set sith = get_sith() %}
{% if sith.alert_msg %}
<div id="alert_box">
{{ sith.alert_msg|markdown }}
</div>
{% endif %}
{% if sith.info_msg %}
<div id="info_box">
{{ sith.info_msg|markdown }}
</div>
{% endif %}
</div>
{% endblock %}
{% else %} {% else %}
<div id="header_bar"> <div id="popupheader">{{ user.get_display_name() }}</div>
<ul id="header_bars_infos">
{% cache 100 "counters_activity" %}
{% for bar in Counter.objects.annotate_has_barman(user).filter(type="BAR") %}
<li>
{# If the user is a barman, we redirect him directly to the barman page
else we redirect him to the activity page #}
{% if bar.has_annotated_barman %}
<a href="{{ url('counter:details', counter_id=bar.id) }}" style="padding: 0">
{% else %}
<a href="{{ url('counter:activity', counter_id=bar.id) }}" style="padding: 0">
{% endif %}
{% if bar.is_inactive(): %}
<i class="fa fa-question" style="color: #f39c12"></i>
{% elif bar.is_open(): %}
<i class="fa fa-check" style="color: #2ecc71"></i>
{% else %}
<i class="fa fa-times" style="color: #eb2f06"></i>
{% endif %}
{{ bar }}
</a>
</li>
{% endfor %}
</ul>
{% endcache %}
<form action="{{ url('core:search') }}" method="GET" id="header_search">
<input type="text" placeholder="{% trans %}Search{% endtrans %}" name="query" id="search" />
<input type="submit" value="{% trans %}Search{% endtrans %}" style="display: none;" />
</form>
<div id="header_user_links">
<div>
<a href="{{ url('core:user_profile', user_id=user.id) }}">{{ user.get_display_name() }}</a>
</div>
<div>
<a href="#" onclick="display_notif()" style="white-space: nowrap;"><i class="fa fa-bell-o"></i> ({{ user.notifications.filter(viewed=False).count() }})</a>
<ul id="header_notif">
{% for n in user.notifications.filter(viewed=False).order_by('-date') %}
<li>
<a href="{{ url("core:notification", notif_id=n.id) }}">
<span class="header_notif_date">
{{ n.date|localtime|date(DATE_FORMAT) }}
</span>
<span class="header_notif_time">
{{ n.date|localtime|time(DATETIME_FORMAT) }}
</span>
<br>
{{ n }}
</a>
</li>
{% endfor %}
<li>
<strong>
<a href="{{ url('core:notification_list') }}">
{% trans %}View more{% endtrans %}
</a>
<br />
<a href="{{ url('core:notification_list') }}?see_all">
{% trans %}Mark all as read{% endtrans %}
</a>
</strong>
</li>
</ul>
</div>
<div>
<a href="{{ url('core:user_tools') }}">{% trans %}Tools{% endtrans %}</a>
</div>
<div>
<a href="{{ url('core:logout') }}">{% trans %}Logout{% endtrans %}</a>
</div>
</div>
</div>
{% endif %} {% endif %}
</header>
<div id="info_boxes">
{% block info_boxes %}
{% set sith = get_sith() %}
{% if sith.alert_msg %}
<div id="alert_box">
{{ sith.alert_msg|markdown }}
</div>
{% endif %}
{% if sith.info_msg %}
<div id="info_box">
{{ sith.info_msg|markdown }}
</div>
{% endif %}
{% endblock %}
</div>
{% else %}{# if not popup #}
<div id="popupheader">{{ user.get_display_name() }}</div>
{% endif %}
{% endblock %} {% endblock %}
<!-- END HEADER --> <!-- END HEADER -->
{% block nav %}
{% if not popup %}
<nav class="navbar">
<a class="link" href="{{ url('core:index') }}">{% trans %}Main{% endtrans %}</a>
<div class="menu">
<span class="head">{% trans %}Associations & Clubs{% endtrans %}</span>
<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>
</ul>
</div>
<div class="menu">
<span class="head">{% trans %}Events{% endtrans %}</span>
<ul class="content">
<li><a href="{{ url('election:list') }}">{% trans %}Elections{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='ga') }}">{% trans %}Big event{% endtrans %}</a></li>
</ul>
</div>
<a class="link" href="{{ url('forum:main') }}">{% trans %}Forum{% endtrans %}</a>
<a class="link" href="{{ url('sas:main') }}">{% trans %}Gallery{% endtrans %}</a>
<a class="link" href="{{ url('eboutic:main') }}">{% trans %}Eboutic{% endtrans %}</a>
<div class="menu">
<span class="head">{% trans %}Services{% endtrans %}</span>
<ul class="content">
<li><a href="{{ url('matmat:search_clear') }}">{% trans %}Matmatronch{% endtrans %}</a></li>
<li><a href="/launderette">{% trans %}Launderette{% endtrans %}</a></li>
<li><a href="{{ url('core:file_list') }}">{% trans %}Files{% endtrans %}</a></li>
<li><a href="{{ url('pedagogy:guide') }}">{% trans %}Pedagogy{% endtrans %}</a></li>
</ul>
</div>
<div class="menu">
<span class="head">{% trans %}My Benefits{% endtrans %}</span>
<ul class="content">
<li><a href="{{ url('core:page', page_name='partenaires')}}">{% trans %}Sponsors{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='avantages') }}">{% trans %}Subscriber benefits{% endtrans %}</a></li>
</ul>
</div>
<div class="menu">
<span class="head">{% trans %}Help{% endtrans %}</span>
<ul class="content">
<li><a href="{{ url('core:page', page_name='FAQ') }}">{% trans %}FAQ{% endtrans %}</a></li>
<li><a href="{{ url('core:page', 'contacts') }}">{% trans %}Contacts{% endtrans %}</a></li>
<li><a href="{{ url('core:page', page_name='Index') }}">{% trans %}Wiki{% endtrans %}</a></li>
</ul>
</div>
</nav>
{% endif %}
{% endblock %}
<div id="page"> <div id="page">
{% block nav %}
{% if not popup %}
<nav>
<a href="{{ url('core:index') }}">{% trans %}Main{% endtrans %}</a>
<div class="dropdown">
<button class="dropbtn">{% trans %}Associations & Clubs{% endtrans %}
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
<a href="{{ url('core:page', page_name='ae') }}">{% trans %}AE{% endtrans %}</a>
<a href="{{ url('core:page', page_name='clubs') }}">{% trans %}AE's clubs{% endtrans %}</a>
<a href="{{ url('core:page', page_name='bdf') }}">{% trans %}BdF{% endtrans %}</a>
<a href="{{ url('core:page', page_name='bds') }}">{% trans %}BDS{% endtrans %}</a>
<a href="{{ url('core:page', page_name='cetu') }}">{% trans %}CETU{% endtrans %}</a>
<a href="{{ url('core:page', page_name='clubs/doceo') }}">{% trans %}Doceo{% endtrans %}</a>
<a href="{{ url('core:page', page_name='positions') }}">{% trans %}Positions{% endtrans %}</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn">{% trans %}Events{% endtrans %}
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
<a href="{{ url('election:list') }}">{% trans %}Elections{% endtrans %}</a>
<a href="{{ url('core:page', page_name='ga') }}">{% trans %}Big event{% endtrans %}</a>
</div>
</div>
<a href="{{ url('forum:main') }}">{% trans %}Forum{% endtrans %}</a>
<a href="{{ url('sas:main') }}">{% trans %}Gallery{% endtrans %}</a>
<a href="{{ url('eboutic:main') }}">{% trans %}Eboutic{% endtrans %}</a>
<div class="dropdown">
<button class="dropbtn">{% trans %}Services{% endtrans %}
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
<a href="{{ url('matmat:search_clear') }}">{% trans %}Matmatronch{% endtrans %}</a>
<a href="/launderette">{% trans %}Launderette{% endtrans %}</a>
<a href="{{ url('core:file_list') }}">{% trans %}Files{% endtrans %}</a>
<a href="{{ url('pedagogy:guide') }}">{% trans %}Pedagogy{% endtrans %}</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn">{% trans %}My Benefits{% endtrans %}
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
<a href="{{ url('core:page', page_name='partenaires')}}">{% trans %}Sponsors{% endtrans %}</a>
<a href="{{ url('core:page', page_name='avantages') }}">{% trans %}Subscriber benefits{% endtrans %}</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn">{% trans %}Help{% endtrans %}
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
<a href="{{ url('core:page', page_name='FAQ') }}">{% trans %}FAQ{% endtrans %}</a>
<a href="{{ url('core:page', 'contacts') }}">{% trans %}Contacts{% endtrans %}</a>
<a href="{{ url('core:page', page_name="Index") }}">{% trans %}Wiki{% endtrans %}</a>
</div>
</div>
</nav>
{% endif %}
{% endblock %}
<ul id="quick_notif"> <ul id="quick_notif">
{% for n in quick_notifs %} {% for n in quick_notifs %}
@ -232,20 +255,15 @@
</ul> </ul>
<div id="content"> <div id="content">
{% if list_of_tabs %} {% if list_of_tabs %}
<div class="tool_bar"> <div class="tool_bar">
<div>{{ tabs_title }}</div> <div class="tools">
<div class="tools"> {% for t in list_of_tabs -%}
{% for t in list_of_tabs -%} <a href="{{ t.url }}" {%- if current_tab==t.slug %} class="selected_tab" {%- endif -%}>{{ t.name }}</a>
<a href="{{ t.url }}" {%- endfor %}
{%- if current_tab == t.slug %} </div>
class="selected_tab" </div>
{%- endif -%} {% endif %}
>{{ t.name }}</a>
{%- endfor %}
</div>
</div>
{% endif %}
{% if error %} {% if error %}
{{ error }} {{ error }}
@ -256,18 +274,26 @@
</div> </div>
{% if not popup %} {% if not popup %}
<footer> <footer>
{% block footer %} {% block footer %}
<div> <div>
<a href="{{ url('core:page', 'contacts') }}">{% trans %}Contacts{% endtrans %}</a> <a href="{{ url('core:page', 'contacts') }}">{% trans %}Contacts{% endtrans %}</a>
<a href="{{ url('core:page', 'legals') }}">{% trans %}Legal notices{% endtrans %}</a> <a href="{{ url('core:page', 'legals') }}">{% trans %}Legal notices{% endtrans %}</a>
<a href="{{ url('core:page', 'copyright_agent') }}">{% trans %}Intellectual property{% endtrans %}</a> <a href="{{ url('core:page', 'copyright_agent') }}">{% trans %}Intellectual property{% endtrans %}</a>
<a href="{{ url('core:page', 'docs') }}">{% trans %}Help & Documentation{% endtrans %}</a> <a href="{{ url('core:page', 'docs') }}">{% trans %}Help & Documentation{% endtrans %}</a>
<a href="{{ url('core:page', 'rd') }}">{% trans %}R&D{% endtrans %}</a> <a href="{{ url('core:page', 'rd') }}">{% trans %}R&D{% endtrans %}</a>
</div> </div>
{% trans %}Site made by good people{% endtrans %} <a href="https://discord.gg/XK9WfPsUFm" target="_link">
{% endblock %} {% trans %}Site created by the IT Department of the AE{% endtrans %}
</footer> </a>
{% endblock %}
<br>
<code class="version">
{% cache 1000 "sith_version" %}
{% trans %}Sith version:{% endtrans %}&nbsp;{{ get_sith().version }}
{% endcache %}
</code>
</footer>
{% endif %} {% endif %}
<!-- <!--
{% block tests %} {% block tests %}

View File

@ -1,35 +1,61 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('user/login.scss') }}">
{%- endblock -%}
{% block title %} {% block title %}
{% trans %}Login{% endtrans %} {% trans %}Login{% endtrans %}
{% endblock %}
{% block info_boxes %}
{% endblock %}
{% block nav %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h1 class="title">{% trans %}Login{% endtrans %}</h1>
{% if form.errors %} {% if next %}
<p>{% trans %}Your username and password didn't match. Please try again.{% endtrans %}</p> {% if user.is_authenticated %}
{% endif %} <p>{% trans %}Your account doesn't have access to this page. To proceed,
please login with an account that has access.{% endtrans %}</p>
{% if next %} {% else %}
{% if user.is_authenticated %} <p>{% trans %}Please login or create an account to see this page.{% endtrans %}</p>
<p>{% trans %}Your account doesn't have access to this page. To proceed, {% endif %}
please login with an account that has access.{% endtrans %}</p>
{% else %}
<p>{% trans %}Please login or create an account to see this page.{% endtrans %}</p>
{% endif %} {% endif %}
{% endif %}
<form method="post" action="{{ url('core:login') }}"> <form method="post" action="{{ url('core:login') }}">
{% csrf_token %} {% if form.errors %}
<p>{{ form.username.errors }}<label for="{{ form.username.name }}">{{ form.username.label }} <p class="alert alert-red">{% trans %}Your username and password didn't match. Please try again.{% endtrans %}</p>
</label><input id="id_username" maxlength="254" name="username" type="text" autofocus="autofocus" /></p> <br>
<p>{{ form.password.errors }}<label for="{{ form.password.name }}">{{ form.password.label }}</label>{{ form.password }}</p> {% endif %}
<input type="hidden" name="next" value="{{ next }}">
<p><input type="submit" value="{% trans %}login{% endtrans %}"></p>
</form>
{# Assumes you setup the password_reset view in your URLconf #} {% csrf_token %}
<p><a href="{{ url('core:password_reset') }}">{% trans %}Lost password?{% endtrans %}</a></p>
<p><a href="{{ url('core:register') }}">{% trans %}Create account{% endtrans %}</a></p>
<div>
<label for="{{ form.username.name }}">{{ form.username.label }}</label>
<input id="id_username" maxlength="254" name="username" type="text" autofocus="autofocus" />
{{ form.username.errors }}
</div>
<div>
<label for="{{ form.password.name }}">{{ form.password.label }}</label>
{{ form.password }}
{{ form.password.errors }}
</div>
<input type="hidden" name="next" value="{{ next }}">
<input type="submit" value="{% trans %}Login{% endtrans %}">
{# Assumes you setup the password_reset view in your URLconf #}
<p>
<a href="{{ url('core:password_reset') }}">{% trans %}Lost password?{% endtrans %}</a>
&nbsp;&nbsp;
<a href="{{ url('core:register') }}">{% trans %}Create account{% endtrans %}</a>
</p>
</form>
{% endblock %} {% endblock %}

View File

@ -1,20 +1,31 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% block title %}{% trans %}Register a user{% endtrans %}{% endblock %} {%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('user/login.scss') }}">
{%- endblock -%}
{% block title %}{% trans %}Register{% endtrans %}{% endblock %}
{% block nav %}
{% endblock %}
{% block info_boxes %}
{% endblock %}
{% block content %} {% block content %}
<h1>{% trans %}Register a user{% endtrans %}</h1> <h1 class="title">{% trans %}Register{% endtrans %}</h1>
{% if user_registered %} {% if user_registered %}
{% trans user_name=user_registered.get_display_name() %}Welcome {{ user_name }}!{% endtrans %} {% 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 %} {% trans %}You successfully registred and you will soon receive a confirmation mail.{% endtrans %}<br>
{% trans username=user_registered.username %}Your username is {{ username }}.{% endtrans %}<br>
{% trans username=user_registered.username %}Your username is {{ username }}.{% endtrans %}
{% endif %} {% else %}
<form action="{{ url('core:register') }}" method="post">
<form action="{{ url('core:register') }}" method="post"> {% csrf_token %}
{% csrf_token %} {{ form }}
{{ form }} <input type="submit" value="{% trans %}Register{% endtrans %}" />
<p><input type="submit" value="{% trans %}Register{% endtrans %}" /></p> </form>
</form> {% endif %}
{% endblock %} {% endblock %}

View File

@ -16,6 +16,8 @@
<td>{% trans %}Role{% endtrans %}</td> <td>{% trans %}Role{% endtrans %}</td>
<td>{% trans %}Description{% endtrans %}</td> <td>{% trans %}Description{% endtrans %}</td>
<td>{% trans %}Since{% endtrans %}</td> <td>{% trans %}Since{% endtrans %}</td>
<td></td>
<td></td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -1,195 +1,231 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% from "core/macros.jinja" import show_slots, show_tokens, user_subscription %} {% from "core/macros.jinja" import show_slots, show_tokens, user_subscription %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('user/user_detail.scss') }}">
{%- endblock -%}
{% block title %} {% block title %}
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s profile{% endtrans %} {% trans user_name=profile.get_display_name() %}{{ user_name }}'s profile{% endtrans %}
{% endblock %} {% endblock %}
{% block additional_js %}
<script src="{{ static('core/js/alpinejs.min.js') }}" defer></script>
{% endblock %}
{% block content %} {% block content %}
<div id="user_profile_page"> <div class="user_profile_page" x-data>
<div id="user_profile"> <div class="user_profile">
<!-- Profile --> <!-- Profile -->
<div id="user_profile_infos"> <div class="user-name">
<h4>{{ profile.get_full_name() }}</h4> <h3>{{ profile.get_full_name() }}</h3>
{% if profile.nick_name %} {% if profile.nick_name %}
<div id="user_profile_infos_nick">&laquo; {{ profile.nick_name }} &raquo;</div> <div class="user_profile_infos_nick">&laquo; {{ profile.nick_name }} &raquo;</div>
{% endif %} {% endif %}
</div>
<div class="infos-and-picture">
<div class="user_profile_infos">
{% if profile.quote %} {% if profile.quote %}
<div id="user_profile_infos_quote"> <div class="user_profile_infos_quote">
{{ profile.quote }} {{ profile.quote }}
</div> </div>
{% endif %} {% endif %}
<div id="user_profile_infos_items"> <div class="user_profile_infos_items">
{% if profile.pronouns %} {% if profile.pronouns %}
<div> <div>
<span class="user_profile_infos_item">{% trans %}Pronouns: {% endtrans %}</span> <span class="user_profile_infos_item">{% trans %}Pronouns: {% endtrans %}</span>
<span class="user_profile_infos_item_value">{{ profile.pronouns }}</span> <span class="user_profile_infos_item_value">{{ profile.pronouns }}</span>
</div> </div>
{% endif %} {% endif %}
{% if profile.date_of_birth %} {% if profile.date_of_birth %}
<div> <div>
<span class="user_profile_infos_item">{% trans %}Born: {% endtrans %}</span> <span class="user_profile_infos_item">{% trans %}Born: {% endtrans %}</span>
<span class="user_profile_infos_item_value">{{ profile.date_of_birth|date("d/m/Y") }}</span> <span class="user_profile_infos_item_value">{{ profile.date_of_birth|date("d/m/Y") }}</span>
</div> </div>
{% endif %} {% endif %}
{% if profile.department != "NA" %} {% if profile.department != "NA" %}
<div> <div>
<span class="user_profile_infos_item">{% trans %}Department: {% endtrans %}</span> <span class="user_profile_infos_item">{% trans %}Department: {% endtrans %}</span>
<span class="user_profile_infos_item_value">{{ profile.department }}{{ profile.semester }}</span> <span class="user_profile_infos_item_value">{{ profile.department }}{{ profile.semester
}}</span>
</div> </div>
{% endif %} {% endif %}
{% if profile.dpt_option %} {% if profile.dpt_option %}
<div> <div>
<span class="user_profile_infos_item">{% trans %}Option: {% endtrans %}</span> <span class="user_profile_infos_item">{% trans %}Option: {% endtrans %}</span>
<span class="user_profile_infos_item_value">{{ profile.dpt_option }}</span> <span class="user_profile_infos_item_value">{{ profile.dpt_option }}</span>
</div> </div>
{% endif %} {% endif %}
{% if profile.phone %} {% if profile.phone %}
<div> <div>
<span class="user_profile_infos_item">{% trans %}Phone: {% endtrans %}</span> <span class="user_profile_infos_item">{% trans %}Phone: {% endtrans %}</span>
<span class="user_profile_infos_item_value">{{ profile.phone }}</span> <span class="user_profile_infos_item_value">{{ profile.phone }}</span>
</div> </div>
{% endif %} {% endif %}
{% if profile.address %} {% if profile.address %}
<div> <div>
<span class="user_profile_infos_item">{% trans %}Address: {% endtrans %}</span> <span class="user_profile_infos_item">{% trans %}Address: {% endtrans %}</span>
<span class="user_profile_infos_item_value">{{ profile.address }}</span> <span class="user_profile_infos_item_value">{{ profile.address }}</span>
</div> </div>
{% endif %} {% endif %}
{% if profile.parent_address %} {% if profile.parent_address %}
<div> <div>
<span class="user_profile_infos_item">{% trans %}Parents address: {% endtrans %}</span> <span class="user_profile_infos_item">{% trans %}Parents address: {% endtrans %}</span>
<span class="user_profile_infos_item_value">{{ profile.parent_address }}</span> <span class="user_profile_infos_item_value">{{ profile.parent_address }}</span>
</div> </div>
{% endif %} {% endif %}
</div> </div>
{% if profile.promo %} {% if profile.promo %}
<div id="user_profile_infos_promo"> <div class="user_profile_infos_promo">
<img src="{{ static('core/img/promo_%02d.png' % profile.promo) }}" alt="Promo {{ profile.promo }}" /> {% trans %}Promo: {% endtrans %}{{ profile.promo }}
{% trans %}Promo: {% endtrans %}{{ profile.promo }} <img src="{{ static('core/img/promo_%02d.png' % profile.promo) }}"
alt="Promo {{ profile.promo }}" />
</div> </div>
{% endif %}
</div>
<!-- Pictures -->
<div id="user_profile_pictures">
<div id="user_profile_pictures_bigone">
{% if profile.profile_pict %}
<img src="{{ profile.profile_pict.get_download_url() }}" alt="{% trans %}Profile{% endtrans %}"
title="{% trans %}Profile{% endtrans %}" />
{% else %}
<img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Profile{% endtrans %}"
title="{% trans %}Profile{% endtrans %}" />
{% endif %} {% endif %}
</div> </div>
<div id="user_profile_pictures_thumbnails"> <!-- Pictures -->
{% if profile.profile_pict %} <div class="user_profile_pictures">
<div class="user_profile_pictures_bigone">
{% if profile.profile_pict %}
<img src="{{ profile.profile_pict.get_download_url() }}" alt="{% trans %}Profile{% endtrans %}" <img src="{{ profile.profile_pict.get_download_url() }}" alt="{% trans %}Profile{% endtrans %}"
title="{% trans %}Profile{% endtrans %}" /> title="{% trans %}Profile{% endtrans %}" />
{% else %} {% else %}
<img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Profile{% endtrans %}" <img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Profile{% endtrans %}"
title="{% trans %}Profile{% endtrans %}" /> title="{% trans %}Profile{% endtrans %}" />
{% endif %} {% endif %}
</div>
<div class="user_profile_pictures_thumbnails">
{% if profile.profile_pict %}
<img src="{{ profile.profile_pict.get_download_url() }}" alt="{% trans %}Profile{% endtrans %}"
title="{% trans %}Profile{% endtrans %}" />
{% else %}
<img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Profile{% endtrans %}"
title="{% trans %}Profile{% endtrans %}" />
{% endif %}
{% if profile.avatar_pict %} {% if profile.avatar_pict %}
<img src="{{ profile.avatar_pict.get_download_url() }}" alt="{% trans %}Avatar{% endtrans %}" <img src="{{ profile.avatar_pict.get_download_url() }}" alt="{% trans %}Avatar{% endtrans %}"
title="{% trans %}Avatar{% endtrans %}" /> title="{% trans %}Avatar{% endtrans %}" />
{% else %} {% else %}
<img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Avatar{% endtrans %}" <img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Avatar{% endtrans %}"
title="{% trans %}Avatar{% endtrans %}" /> title="{% trans %}Avatar{% endtrans %}" />
{% endif %} {% endif %}
{% if profile.scrub_pict %} {% if profile.scrub_pict %}
<img src="{{ profile.scrub_pict.get_download_url() }}" alt="{% trans %}Scrub{% endtrans %}" <img src="{{ profile.scrub_pict.get_download_url() }}" alt="{% trans %}Scrub{% endtrans %}"
title="{% trans %}Scrub{% endtrans %}" /> title="{% trans %}Scrub{% endtrans %}" />
{% else %} {% else %}
<img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Scrub{% endtrans %}" <img src="{{ static('core/img/unknown.jpg') }}" alt="{% trans %}Scrub{% endtrans %}"
title="{% trans %}Scrub{% endtrans %}" /> title="{% trans %}Scrub{% endtrans %}" />
{% endif %} {% endif %}
</div>
</div> </div>
</div> </div>
</div> </main>
{% if user.memberships.filter(end_date=None).exists() or user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) or user ==
{% if user.memberships.filter(end_date=None).exists() or user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) or user == profile or user.is_in_group(settings.SITH_BAR_MANAGER_BOARD_GROUP) %} profile or user.is_in_group(settings.SITH_BAR_MANAGER_BOARD_GROUP) %}
{# if the user is member of a club, he can view the subscription state #} {# if the user is member of a club, he can view the subscription state #}
<hr> <hr>
{% if profile.is_subscribed %} {% if profile.is_subscribed %}
{% if user == profile or user.is_root or user.is_board_member %} {% if user == profile or user.is_root or user.is_board_member %}
<div> <div>
{{ user_subscription(profile) }} {{ user_subscription(profile) }}
</div> </div>
{% endif %} {% endif %}
{% if user == profile or user.is_root or user.is_board_member or user.is_launderette_manager %} {% if user == profile or user.is_root or user.is_board_member or user.is_launderette_manager %}
<div> <div>
{# Shows tokens bought by the user #} {# Shows tokens bought by the user #}
{{ show_tokens(profile) }} {{ show_tokens(profile) }}
{# Shows slots took by the user #} {# Shows slots took by the user #}
{{ show_slots(profile) }} {{ show_slots(profile) }}
</div> </div>
{% endif %} {% endif %}
{% else %} {% else %}
<div> <div>
{% trans %}Not subscribed{% endtrans %} {% trans %}Not subscribed{% endtrans %}
{% if user.is_board_member %} {% if user.is_board_member %}
<a href="{{ url('subscription:subscription') }}?member={{ profile.id }}">{% trans %}New subscription{% endtrans %}</a> <a href="{{ url('subscription:subscription') }}?member={{ profile.id }}">{% trans %}New subscription{% endtrans
{% endif %} %}</a>
{% endif %} {% endif %}
</div> {% endif %}
</div>
{% endif %} {% endif %}
{% if profile.was_subscribed and (user == profile or user.can_read_subscription_history)%} {% if profile.was_subscribed and (user == profile or user.can_read_subscription_history)%}
<div id="drop_subscriptions"> <div class="collapse" :class="{'shadow': collapsed}" x-data="{collapsed: false}" x-cloak>
<h5>{% trans %}Subscription history{% endtrans %}</h5> <div class="collapse-header clickable" @click="collapsed = !collapsed">
<table> <span class="collapse-header-text">
<tr> {% trans %}Subscription history{% endtrans %}
<th>{% trans %}Subscription start{% endtrans %}</th> </span>
<th>{% trans %}Subscription end{% endtrans %}</th> <span class="collapse-header-icon" :class="{'reverse': collapsed}">
<th>{% trans %}Subscription type{% endtrans %}</th> <i class="fa fa-caret-down"></i>
<th>{% trans %}Payment method{% endtrans %}</th> </span>
</tr> </div>
{% for sub in profile.subscriptions.all() %} <div class="collapse-body" x-show="collapsed" x-transition.scale.origin.top>
<tr> <table>
<td>{{ sub.subscription_start }}</td> <thead>
<td>{{ sub.subscription_end }}</td> <tr>
<td>{{ sub.subscription_type }}</td> <th>{% trans %}Subscription start{% endtrans %}</th>
<td>{{ sub.get_payment_method_display() }}</td> <th>{% trans %}Subscription end{% endtrans %}</th>
</tr> <th>{% trans %}Subscription type{% endtrans %}</th>
{% endfor %} <th>{% trans %}Payment method{% endtrans %}</th>
</table> </tr>
</thead>
{% for sub in profile.subscriptions.all() %}
<tr>
<td>{{ sub.subscription_start }}</td>
<td>{{ sub.subscription_end }}</td>
<td>{{ sub.subscription_type }}</td>
<td>{{ sub.get_payment_method_display() }}</td>
</tr>
{% endfor %}
</table>
</div>
</div> </div>
{% endif %} {% endif %}
{% if user.is_root or user.is_board_member %} {% if user.is_root or user.is_board_member %}
<hr>
<div> <div>
<hr> <form class="form-gifts" action="{{ url('core:user_gift_create', user_id=profile.id) }}" method="post">
<form style="margin-left: 0px;" action="{{ url('core:user_gift_create', user_id=profile.id) }}" method="post">
{% csrf_token %} {% csrf_token %}
{{ gift_form.label }} {{ gift_form.label }}
{{ gift_form.user }} {{ gift_form.user }}
<input type="submit" value="{% trans %}Give gift{% endtrans %}"> <input type="submit" value="{% trans %}Give gift{% endtrans %}">
</form> </form>
{% if profile.gifts.exists() %} {% if profile.gifts.exists() %}
<br> {% set gifts = profile.gifts.order_by("-date")|list %}
<div id="drop_gifts"> <br>
<h5>{% trans %}Last given gift :{% endtrans %} {{ profile.gifts.order_by('-date').first() }}</h5> <div class="collapse" :class="{'shadow': collapsed}" x-data="{collapsed: false}" x-cloak>
<div> <div class="collapse-header clickable" @click="collapsed = !collapsed">
<ul> <span class="collapse-header-text">
{% for gift in profile.gifts.all().order_by('-date') %} {% trans %}Last given gift :{% endtrans %} {{ gifts[0] }}
<li>{{ gift }} <a href="{{ url('core:user_gift_delete', user_id=profile.id, gift_id=gift.id) }}">{% trans %}Delete{% endtrans %}</a></li> </span>
{% endfor %} <span class="collapse-header-icon" :class="{'reverse': collapsed}">
</ul> <i class="fa fa-caret-down"></i>
</span>
</div> </div>
<div class="collapse-body" x-show="collapsed" x-transition.scale.origin.top>
<ul>
{% for gift in gifts %}
<li>{{ gift }}
<a href="{{ url('core:user_gift_delete', user_id=profile.id, gift_id=gift.id) }}">
<i class="fa fa-trash"></i>
</a>
</li>
{% endfor %}
</ul>
</div> </div>
</div>
{% else %} {% else %}
{% trans %}No gift given yet{% endtrans %} <em>{% trans %}No gift given yet{% endtrans %}</em>
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
@ -201,40 +237,33 @@
{% block script %} {% block script %}
{{ super() }} {{ super() }}
<script> <script>
$( function() { $(function () {
var keys = []; var keys = [];
var pattern = "71,85,89,71,85,89"; var pattern = "71,85,89,71,85,89";
$(document).keydown(function (e) { $(document).keydown(function (e) {
keys.push(e.keyCode); keys.push(e.keyCode);
if (keys.toString()==pattern) { if (keys.toString() == pattern) {
keys = []; keys = [];
$("#user_profile_pictures_bigone img").attr("src", "{{ static('core/img/yug.jpg') }}"); $("#user_profile_pictures_bigone img").attr("src", "{{ static('core/img/yug.jpg') }}");
} }
if (keys.length==6) { if (keys.length == 6) {
keys.shift(); keys.shift();
} }
});
}); });
} ); $(function () {
$(function(){ $("#user_profile_pictures_thumbnails img").click(function () {
$("#user_profile_pictures_thumbnails img").click(function () { $("#user_profile_pictures_bigone img").attr("src", $(this)[0].src);
$("#user_profile_pictures_bigone img").attr("src", $(this)[0].src); $("#user_profile_pictures_bigone img").attr("alt", $(this)[0].alt);
$("#user_profile_pictures_bigone img").attr("alt", $(this)[0].alt); $("#user_profile_pictures_bigone img").attr("title", $(this)[0].title);
$("#user_profile_pictures_bigone img").attr("title", $(this)[0].title); })
})
});
$(function(){
$("#drop_gifts").accordion({
heightStyle: "content",
collapsible: true,
active: false
}); });
}); $(function () {
$(function(){ $("#drop_gifts").accordion({
$("#drop_subscriptions").accordion({ heightStyle: "content",
heightStyle: "content", collapsible: true,
collapsible: true, active: false
active: false });
}); });
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,86 +1,184 @@
{% extends "core/base.jinja" %} {%- extends "core/base.jinja" -%}
{% block title %} {%- block title -%}
{% trans %}Edit user{% endtrans %} {%- trans -%}Edit user{%- endtrans -%}
{% endblock %} {%- endblock -%}
{% block content %} {%- block additional_css -%}
<h2>{% trans %}Edit user profile{% endtrans %}</h2> <link rel="stylesheet" href="{{ scss('user/user_edit.scss') }}">
{%- endblock -%}
{%- block content -%}
<h2 class="title">{%- trans -%}Edit user profile{%- endtrans -%}</h2>
<form action="" method="post" enctype="multipart/form-data" id="user_edit"> <form action="" method="post" enctype="multipart/form-data" id="user_edit">
{% csrf_token %}
{%- csrf_token -%}
{{ form.non_field_errors() }} {{ form.non_field_errors() }}
{% for field in form %}
<p>{{ field.errors }}<label for="{{ field.name }}">{{ field.label }} {# User Pictures #}
{%- if field.name == "profile_pict" -%} <div class="profile-pictures">
<br>{% trans %}Current profile: {% endtrans %} <div class="profile-picture">
{% if form.instance.profile_pict %} <div class="profile-picture-display">
<img src="{{ form.instance.profile_pict.get_download_url() }}" title="{% trans %}Profile{% endtrans %}" /><br>
{% if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) %} {%- if form.instance.profile_pict -%}
<a href="{{ url('core:file_delete', file_id=form.instance.profile_pict.id, popup="") }}">{% trans %}Delete{% endtrans %}</a> <img src="{{ form.instance.profile_pict.get_download_url() }}"
{% endif %} alt="{%- trans -%}Profile{%- endtrans -%}" title="{%- trans -%}Profile{%- endtrans -%}" />
{% else %} {%- else -%}
<img src="{{ static('core/img/unknown.jpg') }}" title="-" crossOrigin="Anonymous" id="new_profile"/><br> <img src="{{ static('core/img/unknown.jpg') }}" alt="{%- trans -%}Profile{%- endtrans -%}"
<div id="take_picture"> title="{%- trans -%}Profile{%- endtrans -%}" />
<div id="camera_canvas" style="width:320; height:240; margin: 0px auto;"></div> {%- endif -%}
<a href="javascript:void(take_snapshot())">{% trans %}Take picture{% endtrans %}</a> </div>
<div class="profile-picture-edit">
<p>{{ form["profile_pict"].label }}</p>
{{ form["profile_pict"] }}
{%- if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) and form.instance.profile_pict.id -%}
<a href="{{ url('core:file_delete', file_id=form.instance.profile_pict.id, popup='') }}">
{%- trans -%}Delete{%- endtrans -%}
</a>
{%- endif -%}
</div>
</div>
<div class="profile-picture">
<div class="profile-picture-display">
{%- if form.instance.avatar_pict -%}
<img src="{{ form.instance.avatar_pict.get_download_url() }}" alt="{%- trans -%}Profile{%- endtrans -%}"
title="{%- trans -%}Profile{%- endtrans -%}" />
{%- else -%}
<img src="{{ static('core/img/unknown.jpg') }}" alt="{%- trans -%}Profile{%- endtrans -%}"
title="{%- trans -%}Profile{%- endtrans -%}" />
{%- endif -%}
</div>
<div class="profile-picture-edit">
<p>{{ form["avatar_pict"].label }}</p>
{{ form["avatar_pict"] }}
{%- if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) and form.instance.avatar_pict.id -%}
<a href="{{ url('core:file_delete', file_id=form.instance.avatar_pict.id, popup='') }}">
{%- trans -%}Delete{%- endtrans -%}
</a>
{%- endif -%}
</div>
</div>
<div class="profile-picture">
<div class="profile-picture-display">
{%- if form.instance.scrub_pict -%}
<img src="{{ form.instance.scrub_pict.get_download_url() }}" alt="{%- trans -%}Profile{%- endtrans -%}"
title="{%- trans -%}Profile{%- endtrans -%}" />
{%- else -%}
<img src="{{ static('core/img/unknown.jpg') }}" alt="{%- trans -%}Profile{%- endtrans -%}"
title="{%- trans -%}Profile{%- endtrans -%}" />
{%- endif -%}
</div>
<div class="profile-picture-edit">
<p>{{ form["scrub_pict"].label }}</p>
{{ form["scrub_pict"] }}
{%- if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) and form.instance.scrub_pict.id -%}
<a href="{{ url('core:file_delete', file_id=form.instance.scrub_pict.id, popup='') }}">
{%- trans -%}Delete{%-endtrans -%}
</a>
{%- endif -%}
</div>
</div>
</div> </div>
{# All fields #}
<div class="profile-fields">
{%- for field in form -%}
{%-
if field.name in ["quote","profile_pict","avatar_pict","scrub_pict","is_subscriber_viewable","forum_signature"]
-%}
{%- continue -%}
{%- endif -%}
<div class="profile-field">
<div class="profile-field-label">{{ field.label }}</div>
<div class="profile-field-content">
{{ field }}
{%- if field.errors -%}
<div class="field-error">{{ field.errors }}</div>
{%- endif -%}
</div>
</div>
{%- endfor -%}
</div>
{# Textareas #}
<div class="profile-fields">
{%- for field in [form["quote"], form["forum_signature"]] -%}
<div class="profile-field">
<div class="profile-field-label">{{ field.label }}</div>
<div class="profile-field-content">
{{ field }}
{%- if field.errors -%}
<div class="field-error">{{ field.errors }}</div>
{%- endif -%}
</div>
</div>
{%- endfor -%}
</div>
{# Checkboxes #}
<div class="profile-visible">
{{ form["is_subscriber_viewable"] }}
{{ form["is_subscriber_viewable"].label }}
</div>
{%- if form.instance == user -%}
<p> <p>
{% endif %}<br> <a href="{{ url('core:password_change') }}">{%- trans -%}Change my password{%- endtrans -%}</a>
{%- elif field.name == "avatar_pict" and form.instance.avatar_pict -%} </p>
<br>{% trans %}Current avatar: {% endtrans %} {%- elif user.is_root -%}
<img src="{{ form.instance.avatar_pict.get_download_url() }}" title="{% trans %}Avatar{% endtrans %}" /><br> <p>
{%- elif field.name == "scrub_pict" and form.instance.scrub_pict -%} <a href="{{ url('core:password_root_change', user_id=form.instance.id) }}">{%- trans -%}Change user password{%-
<br>{% trans %}Current scrub: {% endtrans %} endtrans -%}</a>
<img src="{{ form.instance.scrub_pict.get_download_url() }}" title="{% trans %}Scrub{% endtrans %}" /><br> </p>
{%- endif %}</label> {{ field }}</p> {%- endif -%}
{% endfor %}
<p><input type="submit" value="{% trans %}Update{% endtrans %}" /></p> <p>
<p>{% trans %}Username: {% endtrans %}{{ form.instance.username }}</p> <input type="submit" value="{%- trans -%}Update{%- endtrans -%}" />
{% if form.instance.customer %} </p>
<p>{% trans %}Account number: {% endtrans %}{{ form.instance.customer.account_id }}</p>
{% endif %}
{% if form.instance == user %}
<p><a href="{{ url('core:password_change') }}">{% trans %}Change my password{% endtrans %}</a></p>
{% elif user.is_root %}
<p><a href="{{ url('core:password_root_change', user_id=form.instance.id) }}">{% trans %}Change user password{% endtrans %}</a></p>
{% endif %}
</form> </form>
{% endblock %}
{% block script %}
{{ super() }}
{% if not form.instance.profile_pict %}
<script src="{{ static('core/js/webcam.js') }}"></script>
<script language="JavaScript">
Webcam.on('error', function(msg) { console.log('Webcam.js error: ' + msg) })
Webcam.set({
width: 320,
height: 240,
dest_width: 320,
dest_height: 240,
image_format: 'jpeg',
jpeg_quality: 90,
force_flash: false
});
Webcam.attach( '#camera_canvas' );
function take_snapshot() {
var data_uri = Webcam.snap();
var url = "{{ url('core:user_profile_upload', user_id=form.instance.id) }}";
Webcam.upload( data_uri, url, function(code, text) {
if (code == 302 || code == 200) {
$('#new_profile').attr('src', data_uri);
$('#take_picture').remove();
$('#id_profile_pict').remove();
} else {
console.log("Unknown error: ");
console.log(text);
}
}, "new_profile_pict", {name: 'csrfmiddlewaretoken', value: '{{ csrf_token }}'});
}
</script>
{% endif %}
{% endblock %}
<p>
<em>{%- trans -%}Username: {%- endtrans -%}&nbsp;{{ form.instance.username }}</em>
<br />
{%- if form.instance.customer -%}
<em>{%- trans -%}Account number: {%- endtrans -%}&nbsp;{{ form.instance.customer.account_id }}</em>
{%- endif -%}
</p>
{%- endblock -%}
{%- block script -%}
{{ super() }}
{%- if not form.instance.profile_pict -%}
<script src="{{ static('core/js/webcam.js') }}"></script>
<script>
Webcam.on('error', function (msg) { console.log('Webcam.js error: ' + msg) })
Webcam.set({
width: 320,
height: 240,
dest_width: 320,
dest_height: 240,
image_format: 'jpeg',
jpeg_quality: 90,
force_flash: false
});
Webcam.attach('#camera_canvas');
function take_snapshot() {
const data_uri = Webcam.snap();
const url = "{{ url('core:user_profile_upload', user_id=form.instance.id) }}";
Webcam.upload(data_uri, url, function (code, text) {
if (code === 302 || code === 200) {
$('#new_profile').attr('src', data_uri);
$('#take_picture').remove();
$('#id_profile_pict').remove();
} else {
console.log("Unknown error: ");
console.log(text);
}
}, "new_profile_pict", { name: 'csrfmiddlewaretoken', value: '{{ csrf_token }}' });
}
</script>
{%- endif -%}
{%- endblock -%}

View File

@ -1,45 +1,67 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% from "core/macros.jinja" import user_link_with_pict, delete_godfather %} {% from "core/macros.jinja" import user_link_with_pict, delete_godfather %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('user/user_godfathers.scss') }}">
{%- endblock -%}
{% block title %} {% block title %}
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s family{% endtrans %} {% trans user_name=profile.get_display_name() %}{{ user_name }}'s family{% endtrans %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<p><a href="{{ url("core:user_godfathers_tree_pict", user_id=profile.id) }}?family"> <div class="container">
{% trans %}Show family picture{% endtrans %}</a></p> <a href="{{ url('core:user_godfathers_tree_pict', user_id=profile.id) }}?family">
{% trans %}Show family picture{% endtrans %}
</a>
<h4>{% trans %}Godfathers / Godmothers{% endtrans %}</h4>
{% if profile.godfathers.exists() %} {% if profile.godfathers.exists() %}
<h4>{% trans %}Godfathers / Godmothers{% endtrans %}</h4> <ul class="users">
<ul>
{% for u in profile.godfathers.all() %} {% for u in profile.godfathers.all() %}
<li> <a href="{{ url("core:user_godfathers", user_id=u.id) }}" class="mini_profile_link" > <li class="users-card">
{{ u.get_mini_item()|safe }} </a>{{ delete_godfather(user, profile, u, True) }}</li> <a href="{{ url('core:user_godfathers', user_id=u.id) }}" class="mini_profile_link">
{{ u.get_mini_item() | safe }}
</a>
{{ delete_godfather(user, profile, u, True) }}
</li>
{% endfor %} {% endfor %}
</ul> </ul>
<p><a href="{{ url("core:user_godfathers_tree", user_id=profile.id) }}">
{% trans %}Show ancestors tree{% endtrans %}</a></p> <a href="{{ url('core:user_godfathers_tree', user_id=profile.id) }}">
{% trans %}Show ancestors tree{% endtrans %}
</a>
{% else %} {% else %}
<p>{% trans %}No godfathers / godmothers{% endtrans %} <p>{% trans %}No godfathers / godmothers{% endtrans %}
{% endif %} {% endif %}
<h4>{% trans %}Godchildren{% endtrans %}</h4>
{% if profile.godchildren.exists() %} {% if profile.godchildren.exists() %}
<h4>{% trans %}Godchildren{% endtrans %}</h4> <ul class="users">
<ul>
{% for u in profile.godchildren.all() %} {% for u in profile.godchildren.all() %}
<li> <a href="{{ url("core:user_godfathers", user_id=u.id) }}" class="mini_profile_link" > <li class="users-card">
{{ u.get_mini_item()|safe }} </a>{{ delete_godfather(user, profile, u, False) }}</li> <a href="{{ url('core:user_godfathers', user_id=u.id) }}" class="mini_profile_link">
{{ u.get_mini_item()|safe }}
</a>
{{ delete_godfather(user, profile, u, False) }}
</li>
{% endfor %} {% endfor %}
</ul> </ul>
<p><a href="{{ url("core:user_godfathers_tree", user_id=profile.id) }}?descent">
{% trans %}Show descent tree{% endtrans %}</a></p> <a href="{{ url('core:user_godfathers_tree', user_id=profile.id) }}?descent">
{% trans %}Show descent tree{% endtrans %}
</a>
{% else %} {% else %}
<p>{% trans %}No godchildren{% endtrans %} <p>{% trans %}No godchildren{% endtrans %}
{% endif %} {% endif %}
{% if profile == user or user.is_root %}
{% if profile == user or user.is_root %}
<form action="" method="post"> <form action="" method="post">
{% csrf_token %} {% csrf_token %}
{{ form.as_p() }} {{ form.as_p() }}
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p> <p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
</form> </form>
{% endif %} {% endif %}
</div>
{% endblock %} {% endblock %}

View File

@ -1,14 +1,16 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('user/user_group.scss') }}">
{%- endblock -%}
{% block content %} {% block content %}
<h2>{% trans user_name=profile.get_full_name() %}Edit user groups for {{ user_name }}{% endtrans %}</h2> <main>
<form action="" method="post"> <h2>{% trans user_name=profile.get_full_name() %}Edit user groups for {{ user_name }}{% endtrans %}</h2>
{% csrf_token %} <form action="" method="post">
{{ form.as_p() }} {% csrf_token %}
<p><input type="submit" value="{% trans %}Update{% endtrans %}" /></p> {{ form.as_p() }}
</form> <p><input type="submit" value="{% trans %}Update{% endtrans %}" /></p>
{% endblock %} </form>
</main>
{%- endblock -%}

View File

@ -1,26 +1,48 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('sas/album.scss') }}">
{%- endblock -%}
{% block title %} {% block title %}
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s pictures{% endtrans %} {% trans user_name=profile.get_display_name() %}{{ user_name }}'s pictures{% endtrans %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<main>
{% if can_edit(profile, user) %} {% if can_edit(profile, user) %}
<button id="download_all_pictures", onclick=download_pictures()>{% trans %}Download all my pictures{% endtrans %}</button> <button id="download_all_pictures", onclick=download_pictures()>{% trans %}Download all my pictures{% endtrans %}</button>
{% endif %} {% endif %}
{% for a in albums %} {% for a in albums %}
<div style="padding: 10px">
<h4>{{ a.name }}</h4> <h4>{{ a.name }}</h4>
<hr> <div class="photos">
{% for picture in pictures[a.id] %} {% for p in pictures[a.id] %}
<div class="picture"> {% if p.can_be_viewed_by(user) %}
<a href="{{ url("sas:picture", picture_id=picture.id) }}#pict"> <a href="{{ url("sas:picture", picture_id=p.id) }}#pict">
<img src="{{ picture.get_download_thumb_url() }}" alt="{{ picture.get_display_name() }}" style="max-width: 100%" loading="lazy"/> <div
</a> class="photo{% if not p.is_moderated %} not_moderated{% endif %}"
style="background-image: url('{% if p.file %}{{ p.get_download_url() }}{% else %}{{ static('core/img/sas.jpg') }}{% endif %}');"
>
{% if not p.is_moderated %}
<div class="overlay">&nbsp;</div>
<div class="text">{% trans %}To be moderated{% endtrans %}</div>
{% else %}
<div class="text">&nbsp;</div>
{% endif %}
</div>
</a>
{% else %}
<div>
<div class="photo">
<div class="text">{% trans %}Picture Unavailable{% endtrans %}</div>
</div>
</div>
{% endif %}
{% endfor %}
</div> </div>
<br>
{% endfor %} {% endfor %}
</div> </main>
{% endfor %}
{% endblock %} {% endblock %}
{% block script %} {% block script %}

View File

@ -1,46 +1,69 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('user/user_preferences.scss') }}">
{%- endblock -%}
{% block title %} {% block title %}
{% trans %}Preferences{% endtrans %} {% trans %}Preferences{% endtrans %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h2>{% trans %}Preferences{% endtrans %}</h2> <div class="main">
<form action="" method="post" enctype="multipart/form-data"> <h2>{% trans %}Preferences{% endtrans %}</h2>
{% csrf_token %} <h3>{% trans %}General{% endtrans %}</h3>
{{ form.as_p() }} <form class="form form-general" action="" method="post" enctype="multipart/form-data">
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p> {% csrf_token %}
</form> {{ form.as_p() }}
<h4>{% trans %}Trombi{% endtrans %}</h4> <input class="form-submit-btn" type="submit" value="{% trans %}Save{% endtrans %}" />
{% if trombi_form %} </form>
<form action="{{ url('trombi:user_tools') }}" method="post" enctype="multipart/form-data">
{% csrf_token %} <h3>{% trans %}Trombi{% endtrans %}</h3>
{{ trombi_form.as_p() }}
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p> {% if trombi_form %}
</form> <form class="form form-trombi" action="{{ url('trombi:user_tools') }}" method="post" enctype="multipart/form-data">
{% else %} {% csrf_token %}
<p>{% trans trombi=user.trombi_user.trombi %}You already choose to be in that Trombi: {{ trombi }}.{% endtrans %} {{ trombi_form.as_p() }}
<a href="{{ url('trombi:user_tools') }}">{% trans %}Go to my Trombi tools{% endtrans %}</a></p> <input class="form-submit-btn" type="submit" value="{% trans %}Save{% endtrans %}" />
{% endif %} </form>
{% if profile.customer %}
<h4>{% trans %}Student cards{% endtrans %}</h4> {% else %}
<p>{% trans %}You can add a card by asking at a counter or add it yourself here. If you want to manually add a student card yourself, you'll need a NFC reader. We store the UID of the card which is 14 characters long.{% endtrans %}</p> <p>{% trans trombi=user.trombi_user.trombi %}You already choose to be in that Trombi: {{ trombi }}.{% endtrans %}
<form action="{{ url('counter:add_student_card', customer_id=profile.customer.pk) }}" method="post"> <br />
{% csrf_token %} <a href="{{ url('trombi:user_tools') }}">{% trans %}Go to my Trombi tools{% endtrans %}</a>
{{ student_card_form.as_p() }} </p>
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p> {% endif %}
</form>
{% if profile.customer.student_cards.exists() %}
<ul>
{% for card in profile.customer.student_cards.all() %}
<li>{{ card.uid }} - <a href="{{ url('counter:delete_student_card', customer_id=profile.customer.pk, card_id=card.id) }}">{% trans %}Delete{% endtrans %}</a></li>
{% endfor %}
</ul>
{% else %}
<p>{% trans %}No student cards registered.{% endtrans %}</p>
{% endif %}
{% endif %}
{% endblock %}
{% if profile.customer %}
<h3>{% trans %}Student cards{% endtrans %}</h3>
{% if profile.customer.student_cards.exists() %}
<ul class="student-cards">
{% for card in profile.customer.student_cards.all() %}
<li>
{{ card.uid }}
&nbsp;-&nbsp;
<a href="{{ url('counter:delete_student_card', customer_id=profile.customer.pk, card_id=card.id) }}">
{% trans %}Delete{% endtrans %}
</a>
</li>
{% endfor %}
</ul>
{% else %}
<em class="no-cards">{% trans %}No student card registered.{% endtrans %}</em>
<p class="justify">
{% trans %}You can add a card by asking at a counter or add it yourself here. If you want to manually
add a student card yourself, you'll need a NFC reader. We store the UID of the card which is 14 characters long.{% endtrans %}
</p>
{% endif %}
<form class="form form-cards" action="{{ url('counter:add_student_card', customer_id=profile.customer.pk) }}"
method="post">
{% csrf_token %}
{{ student_card_form.as_p() }}
<input class="form-submit-btn" type="submit" value="{% trans %}Save{% endtrans %}" />
</form>
{% endif %}
</div>
{% endblock %}

View File

@ -1,25 +1,41 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('user/user_stats.scss') }}">
{%- endblock -%}
{% block title %} {% block title %}
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s stats{% endtrans %} {% trans user_name=profile.get_display_name() %}{{ user_name }}'s stats{% endtrans %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container">
<div class="row">
{% if profile.permanencies %} {% if profile.permanencies %}
<h3>{% trans %}Permanencies{% endtrans %}</h3>
<div> <div>
<p>Total: {{ total_perm_time }}</p> <h3>{% trans %}Permanencies{% endtrans %}</h3>
<p>Foyer: {{ total_foyer_time }}</p> <div class="flexed">
<p>MDE: {{ total_mde_time }}</p> <div><span>Foyer :</span><span>{{ total_foyer_time }}</span></div>
<p>La Gommette: {{ total_gommette_time }}</p> <div><span>Gommette :</span><span>{{ total_gommette_time }}</span></div>
<div><span>MDE :</span><span>{{ total_mde_time }}</span></div>
<div><b>Total :</b><b>{{ total_perm_time }}</b></div>
</div>
</div> </div>
{% endif %} {% endif %}
<h3>{% trans %}Buyings{% endtrans %}</h3>
<div> <div>
<p>Foyer: {{ total_foyer_buyings }} €</p> <h3>{% trans %}Buyings{% endtrans %}</h3>
<p>MDE: {{ total_mde_buyings }} €</p> <div class="flexed">
<p>La Gommette: {{ total_gommette_buyings }} €</p> <div><span>Foyer :</span><span>{{ total_foyer_buyings }}&nbsp;€</span></div>
<div><span>Gommette :</span><span>{{ total_gommette_buyings }}&nbsp;€</span></div>
<div><span>MDE :</span><span>{{ total_mde_buyings }}&nbsp;€</span></div>
<div><b>Total :</b><b>{{ total_foyer_buyings + total_gommette_buyings + total_mde_buyings }}&nbsp;€</b>
</div>
</div>
</div> </div>
</div>
<div>
<h3>{% trans %}Product top 10{% endtrans %}</h3> <h3>{% trans %}Product top 10{% endtrans %}</h3>
<table> <table>
<thead> <thead>
@ -29,14 +45,14 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for p in top_product %} {% for p in top_product %}
<tr> <tr>
<td>{{ p['product__name'] }}</td> <td>{{ p['product__name'] }}</td>
<td>{{ p['product_sum'] }}</td> <td>{{ p['product_sum'] }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endblock %} </div>
</div>
{% endblock %}

View File

@ -1,137 +1,186 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ scss('user/user_tools.scss') }}">
{%- endblock -%}
{% block title %} {% block title %}
{% trans user_name=user.get_display_name() %}{{ user_name }}'s tools{% endtrans %} {% trans user_name=user.get_display_name() %}{{ user_name }}'s tools{% endtrans %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h3>{% trans %}User Tools{% endtrans %}</h3> <main>
<h3>{% trans %}User Tools{% endtrans %}</h3>
<hr> <div class="container">
<h4>{% trans %}Sith management{% endtrans %}</h4> {% if user.can_create_subscription or user.is_root or user.is_board_member %}
<ul> <div>
{% if user.is_root %} <h4>{% trans %}Sith management{% endtrans %}</h4>
<li><a href="{{ url('core:group_list') }}">{% trans %}Groups{% endtrans %}</a></li> <ul>
<li><a href="{{ url('rootplace:merge') }}">{% trans %}Merge users{% endtrans %}</a></li> {% if user.is_root %}
<li><a href="{{ url('rootplace:operation_logs') }}">{% trans %}Operation logs{% endtrans %}</a></li> <li><a href="{{ url('core:group_list') }}">{% trans %}Groups{% endtrans %}</a></li>
<li><a href="{{ url('rootplace:delete_forum_messages') }}">{% trans %}Delete user's forum messages{% endtrans %}</a></li> <li><a href="{{ url('rootplace:merge') }}">{% trans %}Merge users{% endtrans %}</a></li>
{% endif %} <li><a href="{{ url('rootplace:operation_logs') }}">{% trans %}Operation logs{% endtrans %}</a></li>
{% if user.can_create_subscription or user.is_root %} <li><a href="{{ url('rootplace:delete_forum_messages') }}">{% trans %}Delete user's forum messages{% endtrans %}</a></li>
<li><a href="{{ url('subscription:subscription') }}">{% trans %}Subscriptions{% endtrans %}</a></li> {% endif %}
{% endif %} {% if user.can_create_subscription or user.is_root %}
{% if user.is_board_member or user.is_root %} <li><a href="{{ url('subscription:subscription') }}">{% trans %}Subscriptions{% endtrans %}</a></li>
<li><a href="{{ url('subscription:stats') }}">{% trans %}Subscription stats{% endtrans %}</a></li> {% endif %}
<li><a href="{{ url('club:club_new') }}">{% trans %}New club{% endtrans %}</a></li> {% if user.is_board_member or user.is_root %}
{% endif %} <li><a href="{{ url('subscription:stats') }}">{% trans %}Subscription stats{% endtrans %}</a></li>
</ul> <li><a href="{{ url('club:club_new') }}">{% trans %}New club{% endtrans %}</a></li>
{% endif %}
<hr> </ul>
<h4>{% trans %}Counters{% endtrans %}</h4> </div>
<ul>
{% if user.is_in_group(settings.SITH_GROUP_COUNTER_ADMIN_ID) or user.is_root %}
<li><a href="{{ url('counter:admin_list') }}">{% trans %}General counters management{% endtrans %}</a></li>
<li><a href="{{ url('counter:product_list') }}">{% trans %}Products management{% endtrans %}</a></li>
<li><a href="{{ url('counter:producttype_list') }}">{% trans %}Product types management{% endtrans %}</a></li>
<li><a href="{{ url('counter:cash_summary_list') }}">{% trans %}Cash register summaries{% endtrans %}</a></li>
<li><a href="{{ url('counter:invoices_call') }}">{% trans %}Invoices call{% endtrans %}</a></li>
<li><a href="{{ url('counter:eticket_list') }}">{% trans %}Etickets{% endtrans %}</a></li>
{% endif %}
{% for b in settings.SITH_COUNTER_BARS %}
{% if user.is_in_group(b[1]+" admin") %}
<li>
<a href="{{ url('counter:details', counter_id=b[0]) }}">{{ b[1] }}</a> -
<a href="{{ url('counter:admin', counter_id=b[0]) }}">{% trans %}Edit{% endtrans %}</a> -
<a href="{{ url('counter:stats', counter_id=b[0]) }}">{% trans %}Stats{% endtrans %}</a> -
{% set c = Counter.objects.filter(id=b[0]).first() %}
{% if c.stock %}
<a href="{{ url('stock:items_list', stock_id=c.stock.id)}}">Stock</a> -
<a href="{{ url('stock:shoppinglist_list', stock_id=c.stock.id)}}">{% trans %}Shopping lists{% endtrans %}</a>
{% else %}
<a href="{{url('stock:new', counter_id=c.id)}}">{% trans %}Create new stock{% endtrans%}</a>
{% endif %} {% endif %}
</li>
{% endif %}
{% endfor %}
</ul>
<hr> {% set is_admin_on_a_counter = false %}
<h4>{% trans %}Accounting{% endtrans %}</h4> {% for b in settings.SITH_COUNTER_BARS if user.is_in_group(b[1] + " admin") %}
<ul> {% set is_admin_on_a_counter = true %}
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) or user.is_root %} {% endfor %}
<li><a href="{{ url('accounting:refound_account') }}">{% trans %}Refound Account{% endtrans %}</a></li>
<li><a href="{{ url('accounting:bank_list') }}">{% trans %}General accounting{% endtrans %}</a></li>
<li><a href="{{ url('accounting:co_list') }}">{% trans %}Company list{% endtrans %}</a></li>
{% endif %}
{% for m in user.memberships.filter(end_date=None).filter(role__gte=7).all() -%}
{%- for b in m.club.bank_accounts.all() %}
<li><strong>{% trans %}Bank account: {% endtrans %}</strong>
<a href="{{ url('accounting:bank_details', b_account_id=b.id) }}">{{ b }}</a></li>
{%- endfor %}
{% if m.club.club_account.exists() -%}
{% for ca in m.club.club_account.all() %}
<li><strong>{% trans %}Club account: {% endtrans %}</strong> <a href="{{ url('accounting:club_details', c_account_id=ca.id) }}">{{ ca }}</a></li>
{%- endfor %}
{%- endif -%}
{%- endfor %}
</ul>
<hr> {% if
<h4>{% trans %}Communication{% endtrans %}</h4> user.is_in_group(settings.SITH_GROUP_COUNTER_ADMIN_ID) or user.is_root
<ul> or is_admin_on_a_counter
{% if user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) or user.is_root %} %}
<li><a href="{{ url('com:weekmail_article') }}">{% trans %}Create weekmail article{% endtrans %}</a></li> <div>
<li><a href="{{ url('com:weekmail') }}">{% trans %}Weekmail{% endtrans %}</a></li> <h4>{% trans %}Counters{% endtrans %}</h4>
<li><a href="{{ url('com:weekmail_destinations') }}">{% trans %}Weekmail destinations{% endtrans %}</a></li> <ul>
<li><a href="{{ url('com:news_new') }}">{% trans %}Create news{% endtrans %}</a></li> {% if user.is_in_group(settings.SITH_GROUP_COUNTER_ADMIN_ID) or user.is_root %}
<li><a href="{{ url('com:news_admin_list') }}">{% trans %}Moderate news{% endtrans %}</a></li> <li><a href="{{ url('counter:admin_list') }}">{% trans %}General counters management{% endtrans %}</a></li>
<li><a href="{{ url('com:alert_edit') }}">{% trans %}Edit alert message{% endtrans %}</a></li> <li><a href="{{ url('counter:product_list') }}">{% trans %}Products management{% endtrans %}</a></li>
<li><a href="{{ url('com:info_edit') }}">{% trans %}Edit information message{% endtrans %}</a></li> <li><a href="{{ url('counter:producttype_list') }}">{% trans %}Product types management{% endtrans %}</a></li>
<li><a href="{{ url('core:file_moderation') }}">{% trans %}Moderate files{% endtrans %}</a></li> <li><a href="{{ url('counter:cash_summary_list') }}">{% trans %}Cash register summaries{% endtrans %}</a></li>
<li><a href="{{ url('com:mailing_admin') }}">{% trans %}Mailing lists administration{% endtrans %}</a></li> <li><a href="{{ url('counter:invoices_call') }}">{% trans %}Invoices call{% endtrans %}</a></li>
<li><a href="{{ url('com:poster_list') }}">{% trans %}Posters{% endtrans %}</a></li> <li><a href="{{ url('counter:eticket_list') }}">{% trans %}Etickets{% endtrans %}</a></li>
<li><a href="{{ url('com:screen_list') }}">{% trans %}Screens{% endtrans %}</a></li> {% endif %}
{% endif %} </ul>
{% if user.is_in_group(settings.SITH_GROUP_SAS_ADMIN_ID) %} <ul>
<li><a href="{{ url('sas:moderation') }}">{% trans %}Moderate pictures{% endtrans %}</a></li> {% for b in settings.SITH_COUNTER_BARS %}
{% endif %} {% if user.is_in_group(b[1]+" admin") %}
</ul> {% set c = Counter.objects.filter(id=b[0]).first() %}
<li class="rows counter">
<a href="{{ url('counter:details', counter_id=b[0]) }}">{{ b[1] }}</a>
<hr> <span>
<h4>{% trans %}Club tools{% endtrans %}</h4> <span>
<ul> <a class="button" href="{{ url('counter:admin', counter_id=b[0]) }}">{% trans %}Edit{% endtrans %}</a>
{% for m in user.memberships.filter(end_date=None).all() %} <a class="button" href="{{ url('counter:stats', counter_id=b[0]) }}">{% trans %}Stats{% endtrans %}</a>
<li><a href="{{ url('club:tools', club_id=m.club.id) }}">{{ m.club }}</a></li> {% if c.stock %}
{% endfor %} <a class="button" href="{{ url('stock:items_list', stock_id=c.stock.id)}}">Stock</a>
</ul> {% endif %}
</span>
{% if c.stock %}
<a class="button" href="{{ url('stock:shoppinglist_list', stock_id=c.stock.id)}}">{% trans %}Shopping lists{% endtrans %}</a>
{% else %}
<a class="button" href="{{url('stock:new', counter_id=c.id)}}">{% trans %}Create new stock{% endtrans%}</a>
{% endif %}
</span>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
<hr> {% if
<h4>{% trans %}Pedagogy{% endtrans %}</h4> user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) or user.is_root
<ul> or user.memberships.filter(end_date=None).filter(role__gte=7).all() | length > 10
{% if user.is_in_group(settings.SITH_GROUP_PEDAGOGY_ADMIN_ID) or user.is_root %} %}
<li><a href="{{ url('pedagogy:uv_create') }}">{% trans %}Create UV{% endtrans %}</a></li> <div>
<li><a href="{{ url('pedagogy:moderation') }}">{% trans %}Moderate comments{% endtrans %}</a></li> <h4>{% trans %}Accounting{% endtrans %}</h4>
{% endif %} <ul>
</ul> {% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) or user.is_root %}
<li><a href="{{ url('accounting:refound_account') }}">{% trans %}Refound Account{% endtrans %}</a></li>
<li><a href="{{ url('accounting:bank_list') }}">{% trans %}General accounting{% endtrans %}</a></li>
<li><a href="{{ url('accounting:co_list') }}">{% trans %}Company list{% endtrans %}</a></li>
{% endif %}
<hr> {% for m in user.memberships.filter(end_date=None).filter(role__gte=7).all() -%}
<h4>{% trans %}Elections{% endtrans %}</h4> {%- for b in m.club.bank_accounts.all() %}
<ul> <li class="rows">
<li><a href="{{ url('election:list') }}">{% trans %}See available elections{% endtrans %}</a></li> <strong>{% trans %}Bank account: {% endtrans %}</strong>
<li><a href="{{ url('election:list_archived') }}">{% trans %}See archived elections{% endtrans %}</a></li> <a href="{{ url('accounting:bank_details', b_account_id=b.id) }}">{{ b }}</a>
{%- if user.is_subscribed -%} </li>
<li><a href="{{ url('election:create') }}">{% trans %}Create a new election{% endtrans %}</a></li> {%- endfor %}
{%- endif -%}
</ul>
<hr> {% if m.club.club_account.exists() -%}
<h4>{% trans %}Other tools{% endtrans %}</h4> {% for ca in m.club.club_account.all() %}
<ul> <li class="rows">
<li><a href="{{ url('core:to_markdown') }}">{% trans %}Convert dokuwiki/BBcode syntax to Markdown{% endtrans %}</a></li> <strong>{% trans %}Club account: {% endtrans %}</strong>
<li><a href="{{ url('trombi:user_tools') }}">{% trans %}Trombi tools{% endtrans %}</a></li> <a href="{{ url('accounting:club_details', c_account_id=ca.id) }}">{{ ca }}</a>
</ul> </li>
{%- endfor %}
{%- endif -%}
{%- endfor %}
</ul>
</div>
{% endif %}
{% endblock %} {% if user.is_in_group(settings.SITH_GROUP_SAS_ADMIN_ID) or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) or user.is_root %}
<div>
<h4>{% trans %}Communication{% endtrans %}</h4>
<ul>
{% if user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) or user.is_root %}
<li><a href="{{ url('com:weekmail_article') }}">{% trans %}Create weekmail article{% endtrans %}</a></li>
<li><a href="{{ url('com:weekmail') }}">{% trans %}Weekmail{% endtrans %}</a></li>
<li><a href="{{ url('com:weekmail_destinations') }}">{% trans %}Weekmail destinations{% endtrans %}</a></li>
<li><a href="{{ url('com:news_new') }}">{% trans %}Create news{% endtrans %}</a></li>
<li><a href="{{ url('com:news_admin_list') }}">{% trans %}Moderate news{% endtrans %}</a></li>
<li><a href="{{ url('com:alert_edit') }}">{% trans %}Edit alert message{% endtrans %}</a></li>
<li><a href="{{ url('com:info_edit') }}">{% trans %}Edit information message{% endtrans %}</a></li>
<li><a href="{{ url('core:file_moderation') }}">{% trans %}Moderate files{% endtrans %}</a></li>
<li><a href="{{ url('com:mailing_admin') }}">{% trans %}Mailing lists administration{% endtrans %}</a></li>
<li><a href="{{ url('com:poster_list') }}">{% trans %}Posters{% endtrans %}</a></li>
<li><a href="{{ url('com:screen_list') }}">{% trans %}Screens{% endtrans %}</a></li>
{% endif %}
{% if user.is_in_group(settings.SITH_GROUP_SAS_ADMIN_ID) %}
<li><a href="{{ url('sas:moderation') }}">{% trans %}Moderate pictures{% endtrans %}</a></li>
{% endif %}
</ul>
</div>
{% endif %}
{% if user.memberships.filter(end_date=None).all().count() > 0 %}
<div>
<h4>{% trans %}Club tools{% endtrans %}</h4>
<ul>
{% for m in user.memberships.filter(end_date=None).all() %}
<li><a href="{{ url('club:tools', club_id=m.club.id) }}">{{ m.club }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if user.is_in_group(settings.SITH_GROUP_PEDAGOGY_ADMIN_ID) or user.is_root %}
<div>
<h4>{% trans %}Pedagogy{% endtrans %}</h4>
<ul>
<li><a href="{{ url('pedagogy:uv_create') }}">{% trans %}Create UV{% endtrans %}</a></li>
<li><a href="{{ url('pedagogy:moderation') }}">{% trans %}Moderate comments{% endtrans %}</a></li>
</ul>
</div>
{% endif %}
<div>
<h4>{% trans %}Elections{% endtrans %}</h4>
<ul>
<li><a href="{{ url('election:list') }}">{% trans %}See available elections{% endtrans %}</a></li>
<li><a href="{{ url('election:list_archived') }}">{% trans %}See archived elections{% endtrans %}</a></li>
{%- if user.is_subscribed -%}
<li><a href="{{ url('election:create') }}">{% trans %}Create a new election{% endtrans %}</a></li>
{%- endif -%}
</ul>
</div>
<div>
<h4>{% trans %}Other tools{% endtrans %}</h4>
<ul>
<li><a href="{{ url('core:to_markdown') }}">{% trans %}Convert dokuwiki/BBcode syntax to Markdown{% endtrans %}</a></li>
<li><a href="{{ url('trombi:user_tools') }}">{% trans %}Trombi tools{% endtrans %}</a></li>
</ul>
</div>
</div>
</main>
{% endblock %}

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -23,11 +23,13 @@
# #
# #
import datetime
import phonenumbers import phonenumbers
from django import template from django import template
from django.template.defaultfilters import stringfilter from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ngettext
from core.scss.processor import ScssProcessor from core.scss.processor import ScssProcessor
from core.markdown import markdown as md from core.markdown import markdown as md
@ -54,41 +56,26 @@ def phonenumber(value, country="FR", format=phonenumbers.PhoneNumberFormat.NATIO
return value return value
@register.filter() @register.filter(name="truncate_time")
@stringfilter def truncate_time(value, time_unit):
def datetime_format_python_to_PHP(python_format_string): value = str(value)
""" return {
Given a python datetime format string, attempts to convert it to the nearest PHP datetime format string possible. "millis": lambda: value.split(".")[0],
""" "seconds": lambda: value.rsplit(":", maxsplit=1)[0],
python2PHP = { "minutes": lambda: value.split(":", maxsplit=1)[0],
"%a": "D", "hours": lambda: value.rsplit(" ")[0],
"%a": "D", }[time_unit]()
"%A": "l",
"%b": "M",
"%B": "F",
"%c": "",
"%d": "d",
"%H": "H",
"%I": "h",
"%j": "z",
"%m": "m",
"%M": "i",
"%p": "A",
"%S": "s",
"%U": "",
"%w": "w",
"%W": "W",
"%x": "",
"%X": "",
"%y": "y",
"%Y": "Y",
"%Z": "e",
}
php_format_string = python_format_string
for py, php in python2PHP.items(): @register.filter(name="format_timedelta")
php_format_string = php_format_string.replace(py, php) def format_timedelta(value: datetime.timedelta) -> str:
return php_format_string days = value.days
if days == 0:
return str(value)
remainder = value - datetime.timedelta(days=days)
return ngettext(
"%(nb_days)d day, %(remainder)s", "%(nb_days)d days, %(remainder)s", days
) % {"nb_days": days, "remainder": str(remainder)}
@register.simple_tag() @register.simple_tag()

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
@ -272,7 +264,7 @@ class UserRegistrationTest(TestCase):
) )
self.assertTrue(response.status_code == 200) self.assertTrue(response.status_code == 200)
self.assertTrue( self.assertTrue(
"""<p>Votre nom d\\'utilisateur et votre mot de passe ne correspondent pas. Merci de r\\xc3\\xa9essayer.</p>""" """<p class="alert alert-red">Votre nom d\\'utilisateur et votre mot de passe ne correspondent pas. Merci de r\\xc3\\xa9essayer.</p>"""
in str(response.content) in str(response.content)
) )

View File

@ -1,27 +1,20 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
import subprocess
import re import re
# Image utils # Image utils
@ -31,13 +24,23 @@ from datetime import date
from PIL import ExifTags from PIL import ExifTags
# from exceptions import IOError
import PIL import PIL
from django.conf import settings from django.conf import settings
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
def get_git_revision_short_hash() -> str:
"""
Return the short hash of the current commit
"""
return (
subprocess.check_output(["git", "rev-parse", "--short", "HEAD"])
.decode("ascii")
.strip()
)
def get_start_of_semester(d=date.today()): def get_start_of_semester(d=date.today()):
""" """
This function computes the start date of the semester with respect to the given date (default is today), This function computes the start date of the semester with respect to the given date (default is today),
@ -52,14 +55,12 @@ def get_start_of_semester(d=date.today()):
year = today.year year = today.year
start = date(year, settings.SITH_START_DATE[0], settings.SITH_START_DATE[1]) start = date(year, settings.SITH_START_DATE[0], settings.SITH_START_DATE[1])
start2 = start.replace(month=(start.month + 6) % 12) start2 = start.replace(month=(start.month + 6) % 12)
if start > start2: spring, autumn = min(start, start2), max(start, start2)
start, start2 = start2, start if today > autumn: # autumn semester
if today < start: return autumn
return start2.replace(year=year - 1) if today > spring: # spring semester
elif today < start2: return spring
return start return autumn.replace(year=year - 1) # autumn semester of last year
else:
return start2
def get_semester(d=date.today()): def get_semester(d=date.today()):

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -250,6 +250,7 @@ class UserProfileForm(forms.ModelForm):
"scrub_pict": forms.ClearableFileInput, "scrub_pict": forms.ClearableFileInput,
"phone": PhoneNumberInternationalFallbackWidget, "phone": PhoneNumberInternationalFallbackWidget,
"parent_phone": PhoneNumberInternationalFallbackWidget, "parent_phone": PhoneNumberInternationalFallbackWidget,
"quote": forms.Textarea,
} }
labels = { labels = {
"profile_pict": _( "profile_pict": _(

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
from ajax_select import make_ajax_form from ajax_select import make_ajax_form

View File

@ -1,34 +1,25 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
from __future__ import annotations from __future__ import annotations
from django.db.models import Sum, F
from typing import Tuple from typing import Tuple
from django.db import models from django.db import models
from django.db.models import OuterRef, Exists from django.db.models import F, Value, Sum, QuerySet, OuterRef, Exists
from django.db.models.functions import Length from django.db.models.functions import Concat, Length
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.conf import settings from django.conf import settings
@ -37,14 +28,14 @@ from django.core.validators import MinLengthValidator
from django.forms import ValidationError from django.forms import ValidationError
from django.utils.functional import cached_property from django.utils.functional import cached_property
from datetime import timedelta, date from datetime import timedelta, date, datetime
import random import random
import string import string
import os import os
import base64 import base64
import datetime
from dict2xml import dict2xml from dict2xml import dict2xml
from core.utils import get_start_of_semester
from sith.settings import SITH_COUNTER_OFFICES, SITH_MAIN_CLUB from sith.settings import SITH_COUNTER_OFFICES, SITH_MAIN_CLUB
from club.models import Club, Membership from club.models import Club, Membership
from accounting.models import CurrencyField from accounting.models import CurrencyField
@ -92,8 +83,9 @@ class Customer(models.Model):
don't mix them) and a Product. don't mix them) and a Product.
""" """
subscription = self.user.subscriptions.order_by("subscription_end").last() subscription = self.user.subscriptions.order_by("subscription_end").last()
time_diff = date.today() - subscription.subscription_end if subscription is None:
return subscription is not None and time_diff < timedelta(days=90) return False
return (date.today() - subscription.subscription_end) < timedelta(days=90)
@classmethod @classmethod
def get_or_create(cls, user: User) -> Tuple[Customer, bool]: def get_or_create(cls, user: User) -> Tuple[Customer, bool]:
@ -491,7 +483,7 @@ class Counter(models.Model):
""" """
return self.is_open() and ( return self.is_open() and (
(timezone.now() - self.permanencies.order_by("-activity").first().activity) (timezone.now() - self.permanencies.order_by("-activity").first().activity)
> datetime.timedelta(minutes=settings.SITH_COUNTER_MINUTE_INACTIVE) > timedelta(minutes=settings.SITH_COUNTER_MINUTE_INACTIVE)
) )
def barman_list(self): def barman_list(self):
@ -517,6 +509,77 @@ class Counter(models.Model):
is_ae_member = True is_ae_member = True
return is_ae_member return is_ae_member
def get_top_barmen(self) -> QuerySet:
"""
Return a QuerySet querying the office hours stats of all the barmen of all time
of this counter, ordered by descending number of hours.
Each element of the QuerySet corresponds to a barman and has the following data :
- the full name (first name + last name) of the barman
- the nickname of the barman
- the promo of the barman
- the total number of office hours the barman did attend
"""
return (
self.permanencies.exclude(end=None)
.annotate(
name=Concat(F("user__first_name"), Value(" "), F("user__last_name"))
)
.annotate(nickname=F("user__nick_name"))
.annotate(promo=F("user__promo"))
.values("user", "name", "nickname", "promo")
.annotate(perm_sum=Sum(F("end") - F("start")))
.exclude(perm_sum=None)
.order_by("-perm_sum")
)
def get_top_customers(self, since=get_start_of_semester()) -> QuerySet:
"""
Return a QuerySet querying the money spent by customers of this counter
since the specified date, ordered by descending amount of money spent.
Each element of the QuerySet corresponds to a customer and has the following data :
- the full name (first name + last name) of the customer
- the nickname of the customer
- the amount of money spent by the customer
"""
return (
self.sellings.filter(date__gte=since)
.annotate(
name=Concat(
F("customer__user__first_name"),
Value(" "),
F("customer__user__last_name"),
)
)
.annotate(nickname=F("customer__user__nick_name"))
.annotate(promo=F("customer__user__promo"))
.values("customer__user", "name", "nickname")
.annotate(
selling_sum=Sum(
F("unit_price") * F("quantity"), output_field=CurrencyField()
)
)
.filter(selling_sum__gt=0)
.order_by("-selling_sum")
)
def get_total_sales(self, since=get_start_of_semester()) -> CurrencyField:
"""
Compute and return the total turnover of this counter
since the date specified in parameter (by default, since the start of the current
semester)
:param since: timestamp from which to perform the calculation
:type since: datetime | date
:return: Total revenue earned at this counter
"""
if isinstance(since, date):
since = datetime.combine(since, datetime.min.time())
total = self.sellings.filter(date__gte=since).aggregate(
total=Sum(F("quantity") * F("unit_price"), output_field=CurrencyField())
)["total"]
return total if total is not None else CurrencyField(0)
class Refilling(models.Model): class Refilling(models.Model):
""" """

View File

@ -5,23 +5,41 @@
{% trans counter_name=counter %}{{ counter_name }} activity{% endtrans %} {% trans counter_name=counter %}{{ counter_name }} activity{% endtrans %}
{% endblock %} {% endblock %}
{% block content %} {%- block additional_css -%}
<h3>{% trans counter_name=counter %}{{ counter_name }} activity{% endtrans %}</h3> <link rel="stylesheet" href="{{ scss('counter/activity.scss') }}">
{% if counter.type == 'BAR' %} {%- endblock -%}
<h4>{% trans %}Barmen list{% endtrans %}</h4>
<ul>
{% for b in counter.get_barmen_list() %}
<li>{{ user_profile_link(b) }}</li>
{% endfor %}
</ul>
{% endif %}
<h5>{% trans %}Legend{% endtrans %}</h5> {% block content %}
<span style="color: green">&#x2713;</span> : {% trans %}counter is open, there's at least one barman connected{% endtrans %} <h3>{% trans counter_name=counter %}{{ counter_name }} activity{% endtrans %}</h3>
<br> {% if counter.type == 'BAR' %}
<span style="color: orange">&#x3f;</span> : {% trans minutes=settings.SITH_COUNTER_MINUTE_INACTIVE %}counter is open but not active, the last sale was done at least {{ minutes }} minutes ago {% endtrans %} <h4>{% trans %}Barmen list{% endtrans %}</h4>
<br> <ul>
<span style="color: red">&#10007;</span> : {% trans %}counter is not open : no one is connected{% endtrans %} {% set barmans_list = counter.get_barmen_list() %}
{% if barmans_list | length > 0 %}
{% for b in barmans_list %}
<li>{{ user_profile_link(b) }}</li>
{% endfor %}
{% else %}
{% trans %}There is currently no barman connected.{% endtrans %}
{% endif %}
</ul>
{% endif %}
<h5>{% trans %}Legend{% endtrans %}</h5>
<div class="activity-description">
<div>
<i class="fa fa-check" style="color: #2ecc71"></i>
<span>{% trans %}counter is open, there's at least one barman connected{% endtrans %}</span>
</div>
<div>
<i class="fa fa-question" style="color: #f39c12"></i>
<span>{% trans minutes=settings.SITH_COUNTER_MINUTE_INACTIVE %}counter is open but not active, the last sale was done at least {{ minutes }} minutes ago {% endtrans %}</span>
</div>
<div>
<i class="fa fa-times" style="color: #eb2f06"></i>
<span>{% trans %}counter is not open : no one is connected{% endtrans %}</span>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -2,43 +2,34 @@
{% from 'core/macros.jinja' import user_profile_link %} {% from 'core/macros.jinja' import user_profile_link %}
{% block title %} {% block title %}
{% trans counter_name=counter %}{{ counter_name }} stats{% endtrans %} {% trans counter_name=counter %}{{ counter_name }} stats{% endtrans %}
{% endblock %}
{% block jquery_css %}
{# Remove jquery_css #}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h3>{% trans counter_name=counter %}{{ counter_name }} stats{% endtrans %}</h3> <h3>{% trans counter_name=counter %}{{ counter_name }} stats{% endtrans %}</h3>
<h4>{% trans counter_name=counter.name %}Top 100 {{ counter_name }}{% endtrans %}</h4> <h4>{% trans counter_name=counter.name %}Top 100 {{ counter_name }}{% endtrans %}</h4>
<table> <table>
<thead> <thead>
<tr> <tr>
<td>{% trans %}Nb{% endtrans %}</td> <td>N°</td>
<td>{% trans %}User{% endtrans %}</td> <td>{% trans %}User{% endtrans %}</td>
<td>{% trans %}Promo{% endtrans %}</td> <td>{% trans %}Promo{% endtrans %}</td>
<td>{% trans %}Clubs{% endtrans %}</td> <td>{% trans %}Total{% endtrans %}</td>
<td>{% trans %}Total{% endtrans %}</td> <td>{% trans %}Percentage{% endtrans %}</td>
<td>{% trans %}Percentage{% endtrans %}</td> </tr>
</tr>
</thead> </thead>
<tbody> <tbody>
{% for r in top %} {% for customer in top_customers %}
{% set customer=Customer.objects.filter(user__id=r.customer__user).first() %} <tr class="{% if customer.user == request.user.id %}highlight{% endif %}">
{% if customer.user == user %}
<tr class="highlight">
{% else %}
<tr>
{% endif %}
<td>{{ loop.index }}</td> <td>{{ loop.index }}</td>
<td>{{ customer.user.get_display_name() }}</td> <td>{{ customer.name }} {% if customer.nickname %} ({{ customer.nickname }}) {% endif %}</td>
<td>{{ customer.user.promo or '' }}</td> <td>{{ customer.promo or '' }}</td>
<td> <td>{{ "%.2f"|format(customer.selling_sum) }} €</td>
{% for m in customer.user.memberships.filter(club__parent=None, end_date=None, <td>{{ '%.2f'|format(100 * customer.selling_sum / total_sellings) }}%</td>
role__gt=settings.SITH_MAXIMUM_FREE_ROLE).all() -%}
{%- if loop.index>1 -%}, {% endif -%}
{{ m.club.name }}
{%- endfor %}
</td>
<td>{{ r.selling_sum }} €</td>
<td>{{ '%.2f'|format(100 * r.selling_sum / total_sellings) }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -47,23 +38,20 @@
<h4>{% trans counter_name=counter.name %}Top 100 barman {{ counter_name }}{% endtrans %}</h4> <h4>{% trans counter_name=counter.name %}Top 100 barman {{ counter_name }}{% endtrans %}</h4>
<table> <table>
<thead> <thead>
<tr> <tr>
<td>{% trans %}Nb{% endtrans %}</td> <td>N°</td>
<td>{% trans %}User{% endtrans %}</td> <td>{% trans %}User{% endtrans %}</td>
<td>{% trans %}Time{% endtrans %}</td> <td>{% trans %}Promo{% endtrans %}</td>
</tr> <td>{% trans %}Time{% endtrans %}</td>
</tr>
</thead> </thead>
<tbody> <tbody>
{% for r in top_barman_semester %} {% for barman in top_barman_semester %}
{% set u=User.objects.filter(id=r.user).first() %} <tr {% if barman.user == request.user.id %}class="highlight"{% endif %}>
{% if u == user %}
<tr class="highlight">
{% else %}
<tr>
{% endif %}
<td>{{ loop.index }}</td> <td>{{ loop.index }}</td>
<td>{{ u.get_display_name() }}</td> <td>{{ barman.name }} {% if barman.nickname %}({{ barman.nickname }}){% endif %}</td>
<td>{{ r.perm_sum }}</td> <td>{{ barman.promo or '' }}</td>
<td>{{ barman.perm_sum|format_timedelta|truncate_time("millis") }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -72,23 +60,20 @@
<h4>{% trans counter_name=counter.name %}Top 100 barman {{ counter_name }} (all semesters){% endtrans %}</h4> <h4>{% trans counter_name=counter.name %}Top 100 barman {{ counter_name }} (all semesters){% endtrans %}</h4>
<table> <table>
<thead> <thead>
<tr> <tr>
<td>{% trans %}Nb{% endtrans %}</td> <td>N°</td>
<td>{% trans %}User{% endtrans %}</td> <td>{% trans %}User{% endtrans %}</td>
<td>{% trans %}Time{% endtrans %}</td> <td>{% trans %}Promo{% endtrans %}</td>
</tr> <td>{% trans %}Time{% endtrans %}</td>
</tr>
</thead> </thead>
<tbody> <tbody>
{% for r in top_barman %} {% for barman in top_barman %}
{% set u=User.objects.filter(id=r.user).first() %} <tr {% if barman.user == request.user.id %}class="highlight"{% endif %}>
{% if u == user %}
<tr class="highlight">
{% else %}
<tr>
{% endif %}
<td>{{ loop.index }}</td> <td>{{ loop.index }}</td>
<td>{{ u.get_display_name() }}</td> <td>{{ barman.name }} {% if barman.nickname %}({{ barman.nickname }}){% endif %}</td>
<td>{{ r.perm_sum }}</td> <td>{{ barman.promo or '' }}</td>
<td>{{ barman.perm_sum|format_timedelta|truncate_time("millis") }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
import json import json
@ -28,9 +20,13 @@ import string
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from django.core.management import call_command from django.core.management import call_command
from django.utils import timezone
from django.utils.timezone import timedelta
from club.models import Club
from core.models import User from core.models import User
from counter.models import Counter, Customer, BillingInfo from counter.models import Counter, Customer, BillingInfo, Permanency, Selling, Product
from sith.settings import SITH_MAIN_CLUB
class CounterTest(TestCase): class CounterTest(TestCase):
@ -164,15 +160,211 @@ class CounterTest(TestCase):
class CounterStatsTest(TestCase): class CounterStatsTest(TestCase):
def setUp(self): @classmethod
def setUpClass(cls):
super().setUpClass()
call_command("populate") call_command("populate")
self.counter = Counter.objects.filter(id=2).first() cls.counter = Counter.objects.filter(id=2).first()
cls.krophil = User.objects.get(username="krophil")
cls.skia = User.objects.get(username="skia")
cls.sli = User.objects.get(username="sli")
cls.root = User.objects.get(username="root")
cls.subscriber = User.objects.get(username="subscriber")
cls.old_subscriber = User.objects.get(username="old_subscriber")
cls.counter.sellers.add(cls.sli)
cls.counter.sellers.add(cls.root)
cls.counter.sellers.add(cls.skia)
cls.counter.sellers.add(cls.krophil)
def test_unauthorised_user_fail(self): barbar = Product.objects.get(code="BARB")
# remove everything to make sure the fixtures bring no side effect
Permanency.objects.all().delete()
Selling.objects.all().delete()
now = timezone.now()
# total of sli : 5 hours
Permanency.objects.create(
user=cls.sli, start=now, end=now + timedelta(hours=1), counter=cls.counter
)
Permanency.objects.create(
user=cls.sli,
start=now + timedelta(hours=4),
end=now + timedelta(hours=6),
counter=cls.counter,
)
Permanency.objects.create(
user=cls.sli,
start=now + timedelta(hours=7),
end=now + timedelta(hours=9),
counter=cls.counter,
)
# total of skia : 16 days, 2 hours, 35 minutes and 54 seconds
Permanency.objects.create(
user=cls.skia, start=now, end=now + timedelta(hours=1), counter=cls.counter
)
Permanency.objects.create(
user=cls.skia,
start=now + timedelta(days=4, hours=1),
end=now + timedelta(days=20, hours=2, minutes=35, seconds=54),
counter=cls.counter,
)
# total of root : 1 hour + 20 hours (but the 20 hours were on last year)
Permanency.objects.create(
user=cls.root,
start=now + timedelta(days=5),
end=now + timedelta(days=5, hours=1),
counter=cls.counter,
)
Permanency.objects.create(
user=cls.root,
start=now - timedelta(days=300, hours=20),
end=now - timedelta(days=300),
counter=cls.counter,
)
# total of krophil : 0 hour
s = Selling(
label=barbar.name,
product=barbar,
club=Club.objects.get(name=SITH_MAIN_CLUB["name"]),
counter=cls.counter,
unit_price=2,
seller=cls.skia,
)
krophil_customer = Customer.get_or_create(cls.krophil)[0]
sli_customer = Customer.get_or_create(cls.sli)[0]
skia_customer = Customer.get_or_create(cls.skia)[0]
root_customer = Customer.get_or_create(cls.root)[0]
# moderate drinker. Total : 100 €
s.quantity = 50
s.customer = krophil_customer
s.save(allow_negative=True)
# Sli is a drunkard. Total : 2000 €
s.quantity = 100
s.customer = sli_customer
for _ in range(10):
# little trick to make sure the instance is duplicated in db
s.pk = None
s.save(allow_negative=True) # save ten different sales
# Skia is a heavy drinker too. Total : 1000 €
s.customer = skia_customer
for _ in range(5):
s.pk = None
s.save(allow_negative=True)
# Root is quite an abstemious one. Total : 2 €
s.pk = None
s.quantity = 1
s.customer = root_customer
s.save(allow_negative=True)
def test_not_authenticated_user_fail(self):
# Test with not login user # Test with not login user
response = self.client.get(reverse("counter:stats", args=[self.counter.id])) response = self.client.get(reverse("counter:stats", args=[self.counter.id]))
self.assertTrue(response.status_code == 403) self.assertTrue(response.status_code == 403)
def test_unauthorized_user_fails(self):
user = User.objects.get(username="public")
self.client.login(username=user.username, password="plop")
response = self.client.get(reverse("counter:stats", args=[self.counter.id]))
self.assertTrue(response.status_code == 403)
def test_get_total_sales(self):
"""
Test the result of the Counter.get_total_sales() method
"""
total = self.counter.get_total_sales()
self.assertEqual(total, 3102)
def test_top_barmen(self):
"""
Test the result of Counter.get_top_barmen() is correct
"""
top = iter(self.counter.get_top_barmen())
self.assertEqual(
next(top),
{
"user": self.skia.id,
"name": f"{self.skia.first_name} {self.skia.last_name}",
"promo": self.skia.promo,
"nickname": self.skia.nick_name,
"perm_sum": timedelta(days=16, hours=2, minutes=35, seconds=54),
},
)
self.assertEqual(
next(top),
{
"user": self.root.id,
"name": f"{self.root.first_name} {self.root.last_name}",
"promo": self.root.promo,
"nickname": self.root.nick_name,
"perm_sum": timedelta(hours=21),
},
)
self.assertEqual(
next(top),
{
"user": self.sli.id,
"name": f"{self.sli.first_name} {self.sli.last_name}",
"promo": self.sli.promo,
"nickname": self.sli.nick_name,
"perm_sum": timedelta(hours=5),
},
)
self.assertIsNone(
next(top, None), msg="barmen with no office hours should not be in the top"
)
def test_top_customer(self):
"""
Test the result of Counter.get_top_customers() is correct
"""
top = iter(self.counter.get_top_customers())
self.assertEqual(
next(top),
{
"customer__user": self.sli.id,
"name": f"{self.sli.first_name} {self.sli.last_name}",
"nickname": self.sli.nick_name,
"selling_sum": 2000,
},
)
self.assertEqual(
next(top),
{
"customer__user": self.skia.id,
"name": f"{self.skia.first_name} {self.skia.last_name}",
"nickname": self.skia.nick_name,
"selling_sum": 1000,
},
)
self.assertEqual(
next(top),
{
"customer__user": self.krophil.id,
"name": f"{self.krophil.first_name} {self.krophil.last_name}",
"nickname": self.krophil.nick_name,
"selling_sum": 100,
},
)
self.assertEqual(
next(top),
{
"customer__user": self.root.id,
"name": f"{self.root.first_name} {self.root.last_name}",
"nickname": self.root.nick_name,
"selling_sum": 2,
},
)
self.assertIsNone(next(top, None))
class BillingInfoTest(TestCase): class BillingInfoTest(TestCase):
@classmethod @classmethod

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
import json import json
@ -48,13 +40,15 @@ from django.utils import timezone
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.conf import settings from django.conf import settings
from django.db import DataError, transaction, models from django.db import DataError, transaction
import json
import re import re
import pytz import pytz
from datetime import date, timedelta, datetime from datetime import timedelta, datetime
from http import HTTPStatus from http import HTTPStatus
from core.utils import get_start_of_semester
from core.views import CanViewMixin, TabedViewMixin, CanEditMixin from core.views import CanViewMixin, TabedViewMixin, CanEditMixin
from core.views.forms import LoginForm from core.views.forms import LoginForm
from core.models import User from core.models import User
@ -68,7 +62,6 @@ from counter.forms import (
CashSummaryFormBase, CashSummaryFormBase,
EticketForm, EticketForm,
) )
from subscription.models import Subscription
from counter.models import ( from counter.models import (
Counter, Counter,
Customer, Customer,
@ -80,7 +73,6 @@ from counter.models import (
CashRegisterSummary, CashRegisterSummary,
CashRegisterSummaryItem, CashRegisterSummaryItem,
Eticket, Eticket,
Permanency,
BillingInfo, BillingInfo,
) )
from accounting.models import CurrencyField from accounting.models import CurrencyField
@ -1365,80 +1357,21 @@ class CounterStatView(DetailView, CounterAdminMixin):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
"""Add stats to the context""" """Add stats to the context"""
from django.db.models import Sum, Case, When, F counter = self.object
semester_start = get_start_of_semester()
office_hours = counter.get_top_barmen()
kwargs = super(CounterStatView, self).get_context_data(**kwargs) kwargs = super(CounterStatView, self).get_context_data(**kwargs)
kwargs["Customer"] = Customer kwargs.update(
kwargs["User"] = User {
semester_start = Subscription.compute_start(d=date.today(), duration=3) "counter": counter,
kwargs["total_sellings"] = Selling.objects.filter( "total_sellings": counter.get_total_sales(since=semester_start),
date__gte=semester_start, counter=self.object "top_customers": counter.get_top_customers(since=semester_start)[:100],
).aggregate( "top_barman": office_hours[:100],
total_sellings=Sum( "top_barman_semester": (
F("quantity") * F("unit_price"), output_field=CurrencyField() office_hours.filter(start__gt=semester_start)[:100]
) ),
)[ }
"total_sellings"
]
kwargs["top"] = (
Selling.objects.values("customer__user")
.annotate(
selling_sum=Sum(
Case(
When(
counter=self.object,
date__gte=semester_start,
unit_price__gt=0,
then=F("unit_price") * F("quantity"),
),
output_field=CurrencyField(),
)
)
)
.exclude(selling_sum=None)
.order_by("-selling_sum")
.all()[:100]
) )
kwargs["top_barman"] = (
Permanency.objects.values("user")
.annotate(
perm_sum=Sum(
Case(
When(
counter=self.object,
end__gt=datetime(year=1999, month=1, day=1),
then=F("end") - F("start"),
),
output_field=models.DateTimeField(),
)
)
)
.exclude(perm_sum=None)
.order_by("-perm_sum")
.all()[:100]
)
kwargs["top_barman_semester"] = (
Permanency.objects.values("user")
.annotate(
perm_sum=Sum(
Case(
When(
counter=self.object,
start__gt=semester_start,
end__gt=datetime(year=1999, month=1, day=1),
then=F("end") - F("start"),
),
output_field=models.DateTimeField(),
)
)
)
.exclude(perm_sum=None)
.order_by("-perm_sum")
.all()[:100]
)
kwargs["sith_date"] = settings.SITH_START_DATE[0]
kwargs["semester_start"] = semester_start
return kwargs return kwargs
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):

View File

@ -1,24 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
#
#

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
from ajax_select import make_ajax_form from ajax_select import make_ajax_form

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
import hmac import hmac

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,23 +1,15 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #
from ajax_select import make_ajax_form from ajax_select import make_ajax_form

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

View File

@ -1,24 +1,16 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,17 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2023 © AE UTBM
# - Skia <skia@libskia.so> # ae@utbm.fr / ae.info@utbm.fr
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # This file is part of the website of the UTBM Student Association (AE UTBM),
# http://ae.utbm.fr. # https://ae.utbm.fr.
# #
# This program is free software; you can redistribute it and/or modify it under # You can find the source code of the website at https://github.com/ae-utbm/sith3
# 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.
# #
# This program is distributed in the hope that it will be useful, but WITHOUT # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # OR WITHIN THE LOCAL FILE "LICENSE"
# 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.
# #
# #

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