mirror of
				https://github.com/ae-utbm/sith.git
				synced 2025-10-31 17:13:08 +00:00 
			
		
		
		
	Merge pull request #971 from ae-utbm/environ
Use .env for project configuration
This commit is contained in:
		
							
								
								
									
										11
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| HTTPS=off | ||||
| SITH_DEBUG=true | ||||
|  | ||||
| # This is not the real key used in prod | ||||
| SECRET_KEY=(4sjxvhz@m5$0a$j0_pqicnc$s!vbve)z+&++m%g%bjhlz4+g2 | ||||
|  | ||||
| # comment the sqlite line and uncomment the postgres one to switch the dbms | ||||
| DATABASE_URL=sqlite:///db.sqlite3 | ||||
| #DATABASE_URL=postgres://user:password@127.0.0.1:5432/sith | ||||
|  | ||||
| CACHE_URL=redis://127.0.0.1:6379/0 | ||||
							
								
								
									
										4
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -7,6 +7,10 @@ on: | ||||
|     branches: [master, taiste] | ||||
|   workflow_dispatch: | ||||
|  | ||||
| env: | ||||
|   SECRET_KEY: notTheRealOne | ||||
|   DATABASE_URL: sqlite:///db.sqlite3 | ||||
|  | ||||
| jobs: | ||||
|   pre-commit: | ||||
|     name: Launch pre-commits checks (ruff) | ||||
|   | ||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -21,3 +21,4 @@ node_modules/ | ||||
|  | ||||
| # compiled documentation | ||||
| site/ | ||||
| .env | ||||
|   | ||||
| @@ -2,13 +2,13 @@ | ||||
|  | ||||
| Pour connecter l'application à une instance de sentry (ex: https://sentry.io), | ||||
| il est nécessaire de configurer la variable `SENTRY_DSN` | ||||
| dans le fichier `settings_custom.py`. | ||||
| dans le fichier `.env`. | ||||
| Cette variable est composée d'un lien complet vers votre projet sentry. | ||||
|  | ||||
| ## Récupérer les statiques | ||||
|  | ||||
| Nous utilisons du SCSS dans le projet. | ||||
| En environnement de développement (`DEBUG=True`), | ||||
| En environnement de développement (`SITH_DEBUG=true`), | ||||
| le SCSS est compilé à chaque fois que le fichier est demandé. | ||||
| Pour la production, le projet considère  | ||||
| que chacun des fichiers est déjà compilé. | ||||
|   | ||||
| @@ -47,19 +47,19 @@ Commencez par installer les dépendances système : | ||||
|     === "Debian/Ubuntu" | ||||
|  | ||||
|         ```bash | ||||
|         sudo apt install postgresql redis libq-dev nginx | ||||
|         sudo apt install postgresql libq-dev nginx | ||||
|         ``` | ||||
|  | ||||
|     === "Arch Linux" | ||||
|      | ||||
|         ```bash | ||||
|         sudo pacman -S postgresql redis nginx | ||||
|         sudo pacman -S postgresql nginx | ||||
|         ``` | ||||
|  | ||||
| === "macOS" | ||||
|  | ||||
|     ```bash | ||||
|     brew install postgresql redis lipbq nginx | ||||
|     brew install postgresql lipbq nginx | ||||
|     export PATH="/usr/local/opt/libpq/bin:$PATH" | ||||
|     source ~/.zshrc | ||||
|     ``` | ||||
| @@ -77,34 +77,6 @@ uv sync --group prod | ||||
|     C'est parce que ces dépendances compilent certains modules | ||||
|     à l'installation. | ||||
|  | ||||
| ## Configurer Redis | ||||
|  | ||||
| Redis est utilisé comme cache. | ||||
| Assurez-vous qu'il tourne : | ||||
|  | ||||
| ```bash | ||||
| sudo systemctl redis status | ||||
| ``` | ||||
|  | ||||
| Et s'il ne tourne pas, démarrez-le : | ||||
|  | ||||
| ```bash | ||||
| sudo systemctl start redis | ||||
| sudo systemctl enable redis  # si vous voulez que redis démarre automatiquement au boot | ||||
| ``` | ||||
|  | ||||
| Puis ajoutez le code suivant à la fin de votre fichier | ||||
| `settings_custom.py` : | ||||
|  | ||||
| ```python | ||||
| CACHES = { | ||||
|     "default": { | ||||
|         "BACKEND": "django.core.cache.backends.redis.RedisCache", | ||||
|         "LOCATION": "redis://127.0.0.1:6379", | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Configurer PostgreSQL | ||||
|  | ||||
| PostgreSQL est utilisé comme base de données. | ||||
| @@ -139,26 +111,19 @@ en étant connecté en tant que postgres : | ||||
| psql -d sith -c "GRANT ALL PRIVILEGES ON SCHEMA public to sith"; | ||||
| ``` | ||||
|  | ||||
| Puis ajoutez le code suivant à la fin de votre | ||||
| `settings_custom.py` : | ||||
| Puis modifiez votre `.env`. | ||||
| Dedans, décommentez l'url de la base de données | ||||
| de postgres et commentez l'url de sqlite : | ||||
|  | ||||
| ```python | ||||
| DATABASES = { | ||||
|     "default": { | ||||
|         "ENGINE": "django.db.backends.postgresql", | ||||
|         "NAME": "sith", | ||||
|         "USER": "sith", | ||||
|         "PASSWORD": "password", | ||||
|         "HOST": "localhost", | ||||
|         "PORT": "",  # laissez ce champ vide pour que le choix du port soit automatique | ||||
|     } | ||||
| } | ||||
| ```dotenv | ||||
| #DATABASE_URL=sqlite:///db.sqlite3 | ||||
| DATABASE_URL=postgres://sith:password@localhost:5432/sith | ||||
| ``` | ||||
|  | ||||
| Enfin, créez vos données : | ||||
|  | ||||
| ```bash | ||||
| uv run ./manage.py populate | ||||
| uv run ./manage.py setup | ||||
| ``` | ||||
|  | ||||
| !!! note | ||||
| @@ -247,7 +212,7 @@ Puis lancez ou relancez nginx : | ||||
| sudo systemctl restart nginx | ||||
| ``` | ||||
|  | ||||
| Dans votre `settings_custom.py`, remplacez `DEBUG=True` par `DEBUG=False`. | ||||
| Dans votre `.env`, remplacez `SITH_DEBUG=true` par `SITH_DEBUG=false`. | ||||
|  | ||||
| Enfin, démarrez le serveur Django : | ||||
|  | ||||
| @@ -259,7 +224,7 @@ uv run ./manage.py runserver 8001 | ||||
| Et c'est bon, votre reverse-proxy est prêt à tourner devant votre serveur. | ||||
| Nginx écoutera sur le port 8000. | ||||
| Toutes les requêtes vers des fichiers statiques et les medias publiques | ||||
| seront seront servies directement par nginx. | ||||
| seront servies directement par nginx. | ||||
| Toutes les autres requêtes seront transmises au serveur django. | ||||
|  | ||||
|  | ||||
| @@ -273,3 +238,64 @@ un cron pour la mettre à jour au moins une fois par jour. | ||||
| ```bash | ||||
| python manage.py update_spam_database | ||||
| ``` | ||||
|  | ||||
| ## Personnaliser l'environnement | ||||
|  | ||||
| Le site utilise beaucoup de variables configurables via l'environnement. | ||||
| Cependant, pour des raisons de maintenabilité et de simplicité | ||||
| pour les nouveaux développeurs, nous n'avons mis dans le fichier | ||||
| `.env.example` que celles qui peuvent nécessiter d'être fréquemment modifiées | ||||
| (par exemple, l'url de connexion à la db, ou l'activation du mode debug). | ||||
|  | ||||
| Cependant, il en existe beaucoup d'autres, que vous pouvez trouver | ||||
| dans le `settings.py` en recherchant `env.`  | ||||
| (avec `grep` ou avec un ++ctrl+f++ dans votre éditeur). | ||||
|  | ||||
| Si le besoin de les modifier se présente, c'est chose possible. | ||||
| Il suffit de rajouter la paire clef-valeur correspondante dans le `.env`. | ||||
|  | ||||
| !!!tip | ||||
|  | ||||
|     Si vous utilisez nushell,  | ||||
|     vous pouvez automatiser le processus avec | ||||
|     avec le script suivant, qui va parser le `settings.py` | ||||
|     pour récupérer toutes les variables d'environnement qui ne sont pas | ||||
|     définies dans le .env puis va les rajouter : | ||||
|  | ||||
|     ```nu | ||||
|     # si le fichier .env n'existe pas, on le crée | ||||
|     if not (".env" | path exists) { | ||||
|         cp .env.example .env | ||||
|     } | ||||
|      | ||||
|     # puis on récupère les variables d'environnement déjà existantes | ||||
|     let existing = open .env  | ||||
|      | ||||
|     # on récupère toutes les variables d'environnement utilisées | ||||
|     # dans le settings.py qui ne sont pas encore définies dans le .env, | ||||
|     # on les convertit dans un format .env, | ||||
|     # puis on les ajoute à la fin du .env | ||||
|     let regex = '(env\.)(?<method>\w+)\(\s*"(?<env_name>\w+)"(\s*(, default=)(?<value>.+))?\s*\)'; | ||||
|     let content = open sith/settings.py; | ||||
|     let vars = $content | ||||
|         | parse --regex $regex  | ||||
|         | filter { |i| $i.env_name not-in $existing } | ||||
|         | each { |i| | ||||
|             let parsed_value = match [$i.method, $i.value] { | ||||
|                 ["str", "None"] => "" | ||||
|                 ["bool", $val] => ($val | str downcase) | ||||
|                 ["list", $val] => ($val | str trim -c '[' | str trim -c ']') | ||||
|                 ["path", $val] => ($val | str replace 'BASE_DIR / "' $'"(pwd)/') | ||||
|                 [_, $val] => $val | ||||
|             } | ||||
|             $"($i.env_name)=($parsed_value)" | ||||
|         } | ||||
|      | ||||
|     if ($vars | is-not-empty) { | ||||
|         # on ajoute les nouvelles valeurs,  | ||||
|         # en mettant une ligne vide de séparation avec les anciennes | ||||
|         ["", ...$vars] | save --append .env | ||||
|     } | ||||
|      | ||||
|     print $"($vars | length) values added to .env" | ||||
|     ``` | ||||
| @@ -7,6 +7,7 @@ Certaines dépendances sont nécessaires niveau système : | ||||
| - libjpeg | ||||
| - zlib1g-dev | ||||
| - gettext | ||||
| - redis | ||||
|  | ||||
| ### Installer WSL | ||||
|  | ||||
| @@ -65,8 +66,8 @@ cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab | ||||
|          | ||||
|         ```bash | ||||
|         sudo apt install curl build-essential libssl-dev \ | ||||
|         libjpeg-dev zlib1g-dev npm libffi-dev pkg-config \ | ||||
|         gettext git | ||||
|             libjpeg-dev zlib1g-dev npm libffi-dev pkg-config \ | ||||
|             gettext git redis | ||||
|         curl -LsSf https://astral.sh/uv/install.sh | sh | ||||
|         ``` | ||||
|  | ||||
| @@ -75,7 +76,7 @@ cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab | ||||
|         ```bash | ||||
|         sudo pacman -Syu  # on s'assure que les dépôts et le système sont à jour | ||||
|  | ||||
|         sudo pacman -S uv gcc git gettext pkgconf npm | ||||
|         sudo pacman -S uv gcc git gettext pkgconf npm redis | ||||
|         ``` | ||||
|  | ||||
| === "macOS" | ||||
| @@ -84,7 +85,7 @@ cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab | ||||
|     Il est également nécessaire d'avoir installé xcode | ||||
|      | ||||
|     ```bash     | ||||
|     brew install git uv npm | ||||
|     brew install git uv npm redis | ||||
|      | ||||
|     # Pour bien configurer gettext | ||||
|     brew link gettext # (suivez bien les instructions supplémentaires affichées) | ||||
| @@ -99,6 +100,15 @@ cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab | ||||
|     Python ne fait pas parti des dépendances puisqu'il est automatiquement | ||||
|     installé par uv. | ||||
|  | ||||
| Parmi les dépendances installées se trouve redis (que nous utilisons comme cache). | ||||
| Redis est un service qui doit être activé pour être utilisé. | ||||
| Pour cela, effectuez les commandes : | ||||
|  | ||||
| ```bash | ||||
| sudo systemctl start redis | ||||
| sudo systemctl enable redis  # si vous voulez que redis démarre automatiquement au boot | ||||
| ``` | ||||
|  | ||||
| ## Finaliser l'installation | ||||
|  | ||||
| Clonez le projet (depuis votre console WSL, si vous utilisez WSL) | ||||
| @@ -120,20 +130,24 @@ uv run ./manage.py install_xapian | ||||
|     de texte à l'écran. | ||||
|     C'est normal, il ne faut pas avoir peur. | ||||
|  | ||||
| Maintenant que les dépendances sont installées, nous | ||||
| allons créer la base de données, la remplir avec des données de test, | ||||
| et compiler les traductions. | ||||
| Cependant, avant de faire cela, il est nécessaire de modifier | ||||
| la configuration pour signifier que nous sommes en mode développement. | ||||
| Pour cela, nous allons créer un fichier `sith/settings_custom.py` | ||||
| et l'utiliser pour surcharger les settings de base. | ||||
| Une fois les dépendances installées, il faut encore | ||||
| mettre en place quelques éléments de configuration, | ||||
| qui peuvent varier d'un environnement à l'autre. | ||||
| Ces variables sont stockées dans un fichier `.env`. | ||||
| Pour le créer, vous pouvez copier le fichier `.env.example` : | ||||
|  | ||||
| ```bash | ||||
| echo "DEBUG=True" > sith/settings_custom.py | ||||
| echo 'SITH_URL = "localhost:8000"' >> sith/settings_custom.py | ||||
| cp .env.example .env | ||||
| ``` | ||||
|  | ||||
| Enfin, nous pouvons lancer les commandes suivantes : | ||||
| Les variables par défaut contenues dans le fichier `.env` | ||||
| devraient convenir pour le développement, sans modification. | ||||
|  | ||||
| Maintenant que les dépendances sont installées | ||||
| et la configuration remplie, nous allons pouvoir générer | ||||
| des données utiles pendant le développement. | ||||
|  | ||||
| Pour cela, lancez les commandes suivantes : | ||||
|  | ||||
| ```bash | ||||
| # Prépare la base de données | ||||
| @@ -171,6 +185,30 @@ uv run ./manage.py runserver | ||||
|     [http://localhost:8000/api/docs](http://localhost:8000/api/docs), | ||||
|     une interface swagger, avec toutes les routes de l'API. | ||||
|  | ||||
| !!! question "Pourquoi l'installation est aussi complexe ?" | ||||
|  | ||||
|     Cette question nous a été posée de nombreuses fois par des personnes | ||||
|     essayant d'installer le projet. | ||||
|     Il y a en effet un certain nombre d'étapes à suivre, | ||||
|     de paquets à installer et de commandes à exécuter. | ||||
|      | ||||
|     Le processus d'installation peut donc sembler complexe. | ||||
|  | ||||
|     En réalité, il est difficile de faire plus simple. | ||||
|     En effet, un site web a besoin de beaucoup de composants | ||||
|     pour être développé : il lui faut au minimum | ||||
|     une base de données, un cache, un bundler Javascript | ||||
|     et un interpréteur pour le code du serveur. | ||||
|     Pour nos besoin particuliers, nous utilisons également | ||||
|     un moteur de recherche full-text. | ||||
|      | ||||
|     Nous avons tenté au maximum de limiter le nombre de dépendances | ||||
|     et de sélecionner les plus simples à installer. | ||||
|     Cependant, il est impossible de retirer l'intégralité | ||||
|     de la complexité du processus. | ||||
|     Si vous rencontrez des difficulté lors de l'installation, | ||||
|     n'hésitez pas à demander de l'aide. | ||||
|  | ||||
| ## Générer la documentation | ||||
|  | ||||
| La documentation est automatiquement mise en ligne à chaque envoi de code sur GitHub. | ||||
|   | ||||
| @@ -72,12 +72,14 @@ sith/ | ||||
| ├── .gitattributes | ||||
| ├── .gitignore | ||||
| ├── .mailmap | ||||
| ├── manage.py (26) | ||||
| ├── mkdocs.yml (27) | ||||
| ├── .env (26) | ||||
| ├── .env.example (27) | ||||
| ├── manage.py (28) | ||||
| ├── mkdocs.yml (29) | ||||
| ├── uv.lock | ||||
| ├── pyproject.toml (28) | ||||
| ├── .venv/ (29) | ||||
| ├── .python-version (30) | ||||
| ├── pyproject.toml (30) | ||||
| ├── .venv/ (31) | ||||
| ├── .python-version (32) | ||||
| └── README.md | ||||
| ``` | ||||
| </div> | ||||
| @@ -121,15 +123,19 @@ sith/ | ||||
|     de manière transparente pour l'utilisateur.  | ||||
| 24. Fichier de configuration de coverage.  | ||||
| 25. Fichier de configuration de direnv.  | ||||
| 26. Fichier généré automatiquement par Django. C'est lui | ||||
| 26. Contient les variables d'environnement, qui sont susceptibles | ||||
|     de varier d'une machine à l'autre. | ||||
| 27. Contient des valeurs par défaut pour le `.env` | ||||
|     pouvant convenir à un environnment de développement local | ||||
| 28. Fichier généré automatiquement par Django. C'est lui | ||||
|     qui permet d'appeler des commandes de gestion du projet | ||||
|     avec la syntaxe `python ./manage.py <nom de la commande>` | ||||
| 27. Le fichier de configuration de la documentation, | ||||
| 29. Le fichier de configuration de la documentation, | ||||
|     avec ses plugins et sa table des matières.  | ||||
| 28. Le fichier où sont déclarés les dépendances et la configuration | ||||
| 30. Le fichier où sont déclarés les dépendances et la configuration | ||||
|     de certaines d'entre elles. | ||||
| 29. Dossier d'environnement virtuel généré par uv | ||||
| 30. Fichier qui contrôle quel version de python utiliser pour le projet | ||||
| 31. Dossier d'environnement virtuel généré par uv | ||||
| 32. Fichier qui contrôle quelle version de python utiliser pour le projet | ||||
|      | ||||
|  | ||||
| ## L'application principale | ||||
| @@ -144,10 +150,9 @@ Il est organisé comme suit : | ||||
| ``` | ||||
| sith/ | ||||
| ├── settings.py (1) | ||||
| ├── settings_custom.py (2) | ||||
| ├── toolbar_debug.py (3) | ||||
| ├── urls.py (4) | ||||
| └── wsgi.py (5) | ||||
| ├── toolbar_debug.py (2) | ||||
| ├── urls.py (3) | ||||
| └── wsgi.py (4) | ||||
| ``` | ||||
| </div> | ||||
|  | ||||
| @@ -155,13 +160,10 @@ sith/ | ||||
|    Ce fichier contient les paramètres de configuration du projet. | ||||
|    Par exemple, il contient la liste des applications | ||||
|    installées dans le projet. | ||||
| 2. Configuration maison pour votre environnement. | ||||
|    Toute variable que vous définissez dans ce fichier sera prioritaire | ||||
|    sur la configuration donnée dans `settings.py`. | ||||
| 3. Configuration de la barre de debug. | ||||
| 2. Configuration de la barre de debug. | ||||
|    C'est inutilisé en prod, mais c'est très pratique en développement. | ||||
| 4. Fichier de configuration des urls du projet. | ||||
| 5. Fichier de configuration pour le serveur WSGI. | ||||
| 3. Fichier de configuration des urls du projet. | ||||
| 4. Fichier de configuration pour le serveur WSGI. | ||||
|    WSGI est un protocole de communication entre le serveur | ||||
|    et les applications. | ||||
|    Ce fichier ne vous servira sans doute pas sur un environnement | ||||
|   | ||||
| @@ -157,6 +157,7 @@ markdown_extensions: | ||||
|   - md_in_html | ||||
|   - pymdownx.details | ||||
|   - pymdownx.inlinehilite | ||||
|   - pymdownx.keys | ||||
|   - pymdownx.superfences: | ||||
|       custom_fences: | ||||
|         - name: mermaid | ||||
|   | ||||
| @@ -44,6 +44,8 @@ dependencies = [ | ||||
|     "django-honeypot<2.0.0,>=1.2.1", | ||||
|     "pydantic-extra-types<3.0.0,>=2.10.1", | ||||
|     "ical<9.0.0,>=8.3.0", | ||||
|     "redis[hiredis]<6.0.0,>=5.2.0", | ||||
|     "environs[django]<15.0.0,>=14.1.0", | ||||
|     "requests>=2.32.3", | ||||
| ] | ||||
|  | ||||
| @@ -54,7 +56,6 @@ documentation = "https://sith-ae.readthedocs.io/" | ||||
| [dependency-groups] | ||||
| prod = [ | ||||
|     "psycopg[c]<4.0.0,>=3.2.3", | ||||
|     "redis[hiredis]<6.0.0,>=5.2.0", | ||||
| ] | ||||
| dev = [ | ||||
|     "django-debug-toolbar<5.0.0,>=4.4.6", | ||||
|   | ||||
							
								
								
									
										154
									
								
								sith/settings.py
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								sith/settings.py
									
									
									
									
									
								
							| @@ -34,7 +34,6 @@ https://docs.djangoproject.com/en/1.8/ref/settings/ | ||||
| """ | ||||
|  | ||||
| import binascii | ||||
| import logging | ||||
| import os | ||||
| import sys | ||||
| from datetime import timedelta | ||||
| @@ -43,25 +42,33 @@ from pathlib import Path | ||||
| import sentry_sdk | ||||
| from dateutil.relativedelta import relativedelta | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from environs import Env | ||||
| from sentry_sdk.integrations.django import DjangoIntegration | ||||
|  | ||||
| from .honeypot import custom_honeypot_error | ||||
|  | ||||
| BASE_DIR = Path(__file__).parent.parent.resolve() | ||||
| env = Env() | ||||
| env.read_env() | ||||
|  | ||||
| os.environ["HTTPS"] = "off" | ||||
| BASE_DIR = Path(__file__).parent.parent.resolve() | ||||
|  | ||||
| # Quick-start development settings - unsuitable for production | ||||
| # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ | ||||
|  | ||||
| # SECURITY WARNING: keep the secret key used in production secret! | ||||
| SECRET_KEY = "(4sjxvhz@m5$0a$j0_pqicnc$s!vbve)z+&++m%g%bjhlz4+g2" | ||||
| SECRET_KEY = env.str("SECRET_KEY") | ||||
|  | ||||
| # SECURITY WARNING: don't run with debug turned on in production! | ||||
| DEBUG = False | ||||
| DEBUG = env.bool("SITH_DEBUG", default=False) | ||||
| TESTING = "pytest" in sys.modules | ||||
| INTERNAL_IPS = ["127.0.0.1"] | ||||
|  | ||||
| # force csrf tokens and cookies to be secure when in https | ||||
| CSRF_COOKIE_SECURE = env.bool("HTTPS", default=True) | ||||
| CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS", default=[]) | ||||
| SESSION_COOKIE_SECURE = env.bool("HTTPS", default=True) | ||||
| X_FRAME_OPTIONS = "SAMEORIGIN" | ||||
|  | ||||
| ALLOWED_HOSTS = ["*"] | ||||
|  | ||||
| # Application definition | ||||
| @@ -208,12 +215,12 @@ WSGI_APPLICATION = "sith.wsgi.application" | ||||
| # Database | ||||
|  | ||||
| DATABASES = { | ||||
|     "default": { | ||||
|         "ENGINE": "django.db.backends.sqlite3", | ||||
|         "NAME": BASE_DIR / "db.sqlite3", | ||||
|     }, | ||||
|     "default": env.dj_db_url("DATABASE_URL", conn_max_age=None, conn_health_checks=True) | ||||
| } | ||||
|  | ||||
| if "CACHE_URL" in os.environ: | ||||
|     CACHES = {"default": env.dj_cache_url("CACHE_URL")} | ||||
|  | ||||
| SESSION_ENGINE = "django.contrib.sessions.backends.cached_db" | ||||
|  | ||||
| # Logging | ||||
| @@ -265,13 +272,13 @@ PHONENUMBER_DEFAULT_REGION = "FR" | ||||
|  | ||||
| # Medias | ||||
| MEDIA_URL = "/data/" | ||||
| MEDIA_ROOT = BASE_DIR / "data" | ||||
| MEDIA_ROOT = env.path("MEDIA_ROOT", default=BASE_DIR / "data") | ||||
|  | ||||
| # Static files (CSS, JavaScript, Images) | ||||
| # https://docs.djangoproject.com/en/1.8/howto/static-files/ | ||||
|  | ||||
| STATIC_URL = "/static/" | ||||
| STATIC_ROOT = BASE_DIR / "static" | ||||
| STATIC_ROOT = env.path("STATIC_ROOT", default=BASE_DIR / "static") | ||||
|  | ||||
| # Static files finders which allow to see static folder in all apps | ||||
| STATICFILES_FINDERS = [ | ||||
| @@ -295,24 +302,28 @@ AUTHENTICATION_BACKENDS = ["core.auth.backends.SithModelBackend"] | ||||
| LOGIN_URL = "/login/" | ||||
| LOGOUT_URL = "/logout/" | ||||
| LOGIN_REDIRECT_URL = "/" | ||||
| DEFAULT_FROM_EMAIL = "bibou@git.an" | ||||
| SITH_COM_EMAIL = "bibou_com@git.an" | ||||
| DEFAULT_FROM_EMAIL = env.str("DEFAULT_FROM_EMAIL", default="bibou@git.an") | ||||
| SITH_COM_EMAIL = env.str("SITH_COM_EMAIL", default="bibou_com@git.an") | ||||
|  | ||||
| # Those values are to be changed in production to be more effective | ||||
| HONEYPOT_FIELD_NAME = "body2" | ||||
| HONEYPOT_VALUE = "content" | ||||
| HONEYPOT_FIELD_NAME = env.str("HONEYPOT_FIELD_NAME", default="body2") | ||||
| HONEYPOT_VALUE = env.str("HONEYPOT_VALUE", default="content") | ||||
| HONEYPOT_RESPONDER = custom_honeypot_error  # Make honeypot errors less suspicious | ||||
| HONEYPOT_FIELD_NAME_FORUM = "message2"  # Only used on forum | ||||
| HONEYPOT_FIELD_NAME_FORUM = env.str( | ||||
|     "HONEYPOT_FIELD_NAME_FORUM", default="message2" | ||||
| )  # Only used on forum | ||||
|  | ||||
| # Email | ||||
| EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" | ||||
| EMAIL_HOST = "localhost" | ||||
| EMAIL_PORT = 25 | ||||
| EMAIL_BACKEND = env.str( | ||||
|     "EMAIL_BACKEND", default="django.core.mail.backends.dummy.EmailBackend" | ||||
| ) | ||||
| EMAIL_HOST = env.str("EMAIL_HOST", default="localhost") | ||||
| EMAIL_PORT = env.int("EMAIL_PORT", default=25) | ||||
|  | ||||
| # Below this line, only Sith-specific variables are defined | ||||
|  | ||||
| SITH_URL = "my.url.git.an" | ||||
| SITH_NAME = "Sith website" | ||||
| SITH_URL = env.str("SITH_URL", default="127.0.0.1:8000") | ||||
| SITH_NAME = env.str("SITH_NAME", default="AE UTBM") | ||||
| SITH_TWITTER = "@ae_utbm" | ||||
|  | ||||
| # Enable experimental features | ||||
| @@ -321,7 +332,7 @@ SITH_ENABLE_GALAXY = False | ||||
|  | ||||
| # AE configuration | ||||
| # TODO: keep only that first setting, with the ID, and do the same for the other clubs | ||||
| SITH_MAIN_CLUB_ID = 1 | ||||
| SITH_MAIN_CLUB_ID = env.int("SITH_MAIN_CLUB_ID", default=1) | ||||
| SITH_MAIN_CLUB = { | ||||
|     "name": "AE", | ||||
|     "unix_name": "ae", | ||||
| @@ -356,26 +367,28 @@ SITH_SCHOOL_START_YEAR = 1999 | ||||
| # id of the Root account | ||||
| SITH_ROOT_USER_ID = 0 | ||||
|  | ||||
| SITH_GROUP_ROOT_ID = 1 | ||||
| SITH_GROUP_PUBLIC_ID = 2 | ||||
| SITH_GROUP_SUBSCRIBERS_ID = 3 | ||||
| SITH_GROUP_OLD_SUBSCRIBERS_ID = 4 | ||||
| SITH_GROUP_ACCOUNTING_ADMIN_ID = 5 | ||||
| SITH_GROUP_COM_ADMIN_ID = 6 | ||||
| SITH_GROUP_COUNTER_ADMIN_ID = 7 | ||||
| SITH_GROUP_SAS_ADMIN_ID = 8 | ||||
| SITH_GROUP_FORUM_ADMIN_ID = 9 | ||||
| SITH_GROUP_PEDAGOGY_ADMIN_ID = 10 | ||||
| SITH_GROUP_ROOT_ID = env.int("SITH_GROUP_ROOT_ID", default=1) | ||||
| SITH_GROUP_PUBLIC_ID = env.int("SITH_GROUP_PUBLIC_ID", default=2) | ||||
| SITH_GROUP_SUBSCRIBERS_ID = env.int("SITH_GROUP_SUBSCRIBERS_ID", default=3) | ||||
| SITH_GROUP_OLD_SUBSCRIBERS_ID = env.int("SITH_GROUP_OLD_SUBSCRIBERS_ID", default=4) | ||||
| SITH_GROUP_ACCOUNTING_ADMIN_ID = env.int("SITH_GROUP_ACCOUNTING_ADMIN_ID", default=5) | ||||
| SITH_GROUP_COM_ADMIN_ID = env.int("SITH_GROUP_COM_ADMIN_ID", default=6) | ||||
| SITH_GROUP_COUNTER_ADMIN_ID = env.int("SITH_GROUP_COUNTER_ADMIN_ID", default=7) | ||||
| SITH_GROUP_SAS_ADMIN_ID = env.int("SITH_GROUP_SAS_ADMIN_ID", default=8) | ||||
| SITH_GROUP_FORUM_ADMIN_ID = env.int("SITH_GROUP_FORUM_ADMIN_ID", default=9) | ||||
| SITH_GROUP_PEDAGOGY_ADMIN_ID = env.int("SITH_GROUP_PEDAGOGY_ADMIN_ID", default=10) | ||||
|  | ||||
| SITH_GROUP_BANNED_ALCOHOL_ID = 11 | ||||
| SITH_GROUP_BANNED_COUNTER_ID = 12 | ||||
| SITH_GROUP_BANNED_SUBSCRIPTION_ID = 13 | ||||
| SITH_GROUP_BANNED_ALCOHOL_ID = env.int("SITH_GROUP_BANNED_ALCOHOL_ID", default=11) | ||||
| SITH_GROUP_BANNED_COUNTER_ID = env.int("SITH_GROUP_BANNED_COUNTER_ID", default=12) | ||||
| SITH_GROUP_BANNED_SUBSCRIPTION_ID = env.int( | ||||
|     "SITH_GROUP_BANNED_SUBSCRIPTION_ID", default=13 | ||||
| ) | ||||
|  | ||||
| SITH_CLUB_REFOUND_ID = 89 | ||||
| SITH_COUNTER_REFOUND_ID = 38 | ||||
| SITH_PRODUCT_REFOUND_ID = 5 | ||||
| SITH_CLUB_REFOUND_ID = env.int("SITH_CLUB_REFOUND_ID", default=89) | ||||
| SITH_COUNTER_REFOUND_ID = env.int("SITH_COUNTER_REFOUND_ID", default=38) | ||||
| SITH_PRODUCT_REFOUND_ID = env.int("SITH_PRODUCT_REFOUND_ID", default=5) | ||||
|  | ||||
| SITH_COUNTER_ACCOUNT_DUMP_ID = 39 | ||||
| SITH_COUNTER_ACCOUNT_DUMP_ID = env.int("SITH_COUNTER_ACCOUNT_DUMP_ID", default=39) | ||||
|  | ||||
| # Pages | ||||
| SITH_CORE_PAGE_SYNTAX = "Aide_sur_la_syntaxe" | ||||
| @@ -385,7 +398,7 @@ SITH_CORE_PAGE_SYNTAX = "Aide_sur_la_syntaxe" | ||||
| SITH_FORUM_PAGE_LENGTH = 30 | ||||
|  | ||||
| # SAS variables | ||||
| SITH_SAS_ROOT_DIR_ID = 4 | ||||
| SITH_SAS_ROOT_DIR_ID = env.int("SITH_SAS_ROOT_DIR_ID", default=4) | ||||
| SITH_SAS_IMAGES_PER_PAGE = 60 | ||||
|  | ||||
| SITH_BOARD_SUFFIX = "-bureau" | ||||
| @@ -492,9 +505,9 @@ SITH_LOG_OPERATION_TYPE = [ | ||||
|  | ||||
| SITH_PEDAGOGY_UTBM_API = "https://extranet1.utbm.fr/gpedago/api/guide" | ||||
|  | ||||
| SITH_ECOCUP_CONS = 1152 | ||||
| SITH_ECOCUP_CONS = env.int("SITH_ECOCUP_CONS", default=1151) | ||||
|  | ||||
| SITH_ECOCUP_DECO = 1151 | ||||
| SITH_ECOCUP_DECO = env.int("SITH_ECOCUP_DECO", default=1152) | ||||
|  | ||||
| # The limit is the maximum difference between cons and deco possible for a customer | ||||
| SITH_ECOCUP_LIMIT = 3 | ||||
| @@ -509,13 +522,19 @@ SITH_ACCOUNT_DUMP_DELTA = timedelta(days=30) | ||||
|  | ||||
| # Defines which product type is the refilling type, | ||||
| # and thus increases the account amount | ||||
| SITH_COUNTER_PRODUCTTYPE_REFILLING = 3 | ||||
| SITH_COUNTER_PRODUCTTYPE_REFILLING = env.int( | ||||
|     "SITH_COUNTER_PRODUCTTYPE_REFILLING", default=3 | ||||
| ) | ||||
|  | ||||
| # Defines which product is the one year subscription | ||||
| # and which one is the six month subscription | ||||
| SITH_PRODUCT_SUBSCRIPTION_ONE_SEMESTER = 1 | ||||
| SITH_PRODUCT_SUBSCRIPTION_TWO_SEMESTERS = 2 | ||||
| SITH_PRODUCTTYPE_SUBSCRIPTION = 2 | ||||
| SITH_PRODUCT_SUBSCRIPTION_ONE_SEMESTER = env.int( | ||||
|     "SITH_PRODUCT_SUBSCRIPTION_ONE_SEMESTER", default=1 | ||||
| ) | ||||
| SITH_PRODUCT_SUBSCRIPTION_TWO_SEMESTERS = env.int( | ||||
|     "SITH_PRODUCT_SUBSCRIPTION_TWO_SEMESTERS", default=2 | ||||
| ) | ||||
| SITH_PRODUCTTYPE_SUBSCRIPTION = env.int("SITH_PRODUCTTYPE_SUBSCRIPTION", default=2) | ||||
|  | ||||
| # Number of weeks before the end of a subscription when the subscriber can resubscribe | ||||
| SITH_SUBSCRIPTION_END = 10 | ||||
| @@ -624,21 +643,29 @@ SITH_BARMAN_TIMEOUT = 30 | ||||
| SITH_LAST_OPERATIONS_LIMIT = 10 | ||||
|  | ||||
| # ET variables | ||||
| SITH_EBOUTIC_CB_ENABLED = True | ||||
| SITH_EBOUTIC_ET_URL = ( | ||||
|     "https://preprod-tpeweb.e-transactions.fr/cgi/MYchoix_pagepaiement.cgi" | ||||
| SITH_EBOUTIC_CB_ENABLED = env.bool("SITH_EBOUTIC_CB_ENABLED", default=True) | ||||
| SITH_EBOUTIC_ET_URL = env.str( | ||||
|     "SITH_EBOUTIC_ET_URL", | ||||
|     default="https://preprod-tpeweb.e-transactions.fr/cgi/MYchoix_pagepaiement.cgi", | ||||
| ) | ||||
| SITH_EBOUTIC_PBX_SITE = "1999888" | ||||
| SITH_EBOUTIC_PBX_RANG = "32" | ||||
| SITH_EBOUTIC_PBX_IDENTIFIANT = "2" | ||||
| SITH_EBOUTIC_PBX_SITE = env.str("SITH_EBOUTIC_PBX_SITE", default="1999888") | ||||
| SITH_EBOUTIC_PBX_RANG = env.str("SITH_EBOUTIC_PBX_RANG", default="32") | ||||
| SITH_EBOUTIC_PBX_IDENTIFIANT = env.str("SITH_EBOUTIC_PBX_IDENTIFIANT", default="2") | ||||
| SITH_EBOUTIC_HMAC_KEY = binascii.unhexlify( | ||||
|     "0123456789ABCDEF0123456789ABCDEF" | ||||
|     "0123456789ABCDEF0123456789ABCDEF" | ||||
|     "0123456789ABCDEF0123456789ABCDEF" | ||||
|     "0123456789ABCDEF0123456789ABCDEF" | ||||
|     env.str( | ||||
|         "SITH_EBOUTIC_HMAC_KEY", | ||||
|         default=( | ||||
|             "0123456789ABCDEF0123456789ABCDEF" | ||||
|             "0123456789ABCDEF0123456789ABCDEF" | ||||
|             "0123456789ABCDEF0123456789ABCDEF" | ||||
|             "0123456789ABCDEF0123456789ABCDEF" | ||||
|         ), | ||||
|     ) | ||||
| ) | ||||
| SITH_EBOUTIC_PUB_KEY = "" | ||||
| with open(os.path.join(os.path.dirname(__file__), "et_keys/pubkey.pem")) as f: | ||||
| with open( | ||||
|     env.path("SITH_EBOUTIC_PUB_KEY_PATH", default=BASE_DIR / "sith/et_keys/pubkey.pem") | ||||
| ) as f: | ||||
|     SITH_EBOUTIC_PUB_KEY = f.read() | ||||
|  | ||||
| # Launderette variables | ||||
| @@ -680,24 +707,17 @@ SITH_QUICK_NOTIF = { | ||||
| # Mailing related settings | ||||
|  | ||||
| SITH_MAILING_DOMAIN = "utbm.fr" | ||||
| SITH_MAILING_FETCH_KEY = "IloveMails" | ||||
| SITH_MAILING_FETCH_KEY = env.str("SITH_MAILING_FETCH_KEY", default="ILoveMails") | ||||
|  | ||||
| SITH_GIFT_LIST = [("AE Tee-shirt", _("AE tee-shirt"))] | ||||
|  | ||||
| SENTRY_DSN = "" | ||||
| SENTRY_ENV = "production" | ||||
| SENTRY_DSN = env.str("SENTRY_DSN", default=None) | ||||
| SENTRY_ENV = env.str("SENTRY_ENV", default="production") | ||||
|  | ||||
| TOXIC_DOMAINS_PROVIDERS = [ | ||||
|     "https://www.stopforumspam.com/downloads/toxic_domains_whole.txt", | ||||
| ] | ||||
|  | ||||
| try: | ||||
|     from .settings_custom import *  # noqa F403 (this star-import is actually useful) | ||||
|  | ||||
|     logging.getLogger("django").info("Custom settings imported") | ||||
| except ImportError: | ||||
|     logging.getLogger("django").warning("Custom settings failed") | ||||
|  | ||||
| if DEBUG: | ||||
|     INSTALLED_APPS += ("debug_toolbar",) | ||||
|     MIDDLEWARE = ("debug_toolbar.middleware.DebugToolbarMiddleware", *MIDDLEWARE) | ||||
|   | ||||
| @@ -81,7 +81,7 @@ def sentry_debug(request): | ||||
|     The error will be displayed on Sentry | ||||
|     inside the "development" environment | ||||
|  | ||||
|     NOTE : you need to specify the SENTRY_DSN setting in settings_custom.py | ||||
|     NOTE : you need to specify the SENTRY_DSN setting in .env | ||||
|     """ | ||||
|     if settings.SENTRY_ENV != "development" or not settings.SENTRY_DSN: | ||||
|         raise Http404 | ||||
|   | ||||
							
								
								
									
										82
									
								
								uv.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										82
									
								
								uv.lock
									
									
									
										generated
									
									
									
								
							| @@ -276,6 +276,28 @@ wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "dj-database-url" | ||||
| version = "2.3.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "django" }, | ||||
|     { name = "typing-extensions" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/98/9f/fc9905758256af4f68a55da94ab78a13e7775074edfdcaddd757d4921686/dj_database_url-2.3.0.tar.gz", hash = "sha256:ae52e8e634186b57e5a45e445da5dc407a819c2ceed8a53d1fac004cc5288787", size = 10980 } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/e5/91/641a4e5c8903ed59f6cbcce571003bba9c5d2f731759c31db0ba83bb0bdb/dj_database_url-2.3.0-py3-none-any.whl", hash = "sha256:bb0d414ba0ac5cd62773ec7f86f8cc378a9dbb00a80884c2fc08cc570452521e", size = 7793 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "dj-email-url" | ||||
| version = "1.0.6" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/14/ef/8eb478accd9b0369d46a98d1b43027ee0c254096149265c78e6b2e2fa3b0/dj-email-url-1.0.6.tar.gz", hash = "sha256:55ffe3329e48f54f8a75aa36ece08f365e09d61f8a209773ef09a1d4760e699a", size = 15590 } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/8a/f9/fcb9745099d821f9a26092d3d6f4df8f10049885045c3a93ff726d2e40a6/dj_email_url-1.0.6-py2.py3-none-any.whl", hash = "sha256:cbd08327fbb08b104eac160fb4703f375532e4c0243eb230f5b960daee7a96db", size = 6296 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "django" | ||||
| version = "4.2.17" | ||||
| @@ -290,6 +312,15 @@ wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/5e/85/457360cb3de496382e35db4c2af054066df5c40e26df31400d0109a0500c/Django-4.2.17-py3-none-any.whl", hash = "sha256:3a93350214ba25f178d4045c0786c61573e7dbfa3c509b3551374f1e11ba8de0", size = 7993390 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "django-cache-url" | ||||
| version = "3.4.5" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/20/28/d420aaa89028d2ec0cf17c1510d06ff6a8ed0bf1abfb7f33c999e1c5befa/django-cache-url-3.4.5.tar.gz", hash = "sha256:eb9fb194717524348c95cad9905b70b647452741c1d9e481fac6d2125f0ad917", size = 7230 } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/48/90/01755e4a42558b763f7021e9369aa6aa94c2ede7313deed56cb7483834ab/django_cache_url-3.4.5-py2.py3-none-any.whl", hash = "sha256:5f350759978483ab85dc0e3e17b3d53eed3394a28148f6bf0f53d11d0feb5b3c", size = 4760 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "django-countries" | ||||
| version = "7.6.1" | ||||
| @@ -439,6 +470,26 @@ wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/93/69/e391bd51bc08ed9141ecd899a0ddb61ab6465309f1eb470905c0c8868081/docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc", size = 570472 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "environs" | ||||
| version = "14.1.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "marshmallow" }, | ||||
|     { name = "python-dotenv" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/3c/8f/952bd034eac79c8b68b6c770cb78c2bdcb3140d31ff224847f3520077d75/environs-14.1.0.tar.gz", hash = "sha256:a5f2afe9d5a21b468e74a3cceacf5d2371fd67dbb9a7e54fe62290c75a09cdfa", size = 30985 } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/d5/ad/57cfa3e8a006df88e723524127dbab2971a4877c97e7bad070257e15cb6c/environs-14.1.0-py3-none-any.whl", hash = "sha256:a7edda1668ddf1fbfcb7662bdc242dac25648eff2c7fdbaa5d959693afed7a3e", size = 15332 }, | ||||
| ] | ||||
|  | ||||
| [package.optional-dependencies] | ||||
| django = [ | ||||
|     { name = "dj-database-url" }, | ||||
|     { name = "dj-email-url" }, | ||||
|     { name = "django-cache-url" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "executing" | ||||
| version = "2.1.0" | ||||
| @@ -708,6 +759,18 @@ wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "marshmallow" | ||||
| version = "3.25.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "packaging" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/bd/5c/cbfa41491d6c83b36471f2a2f75602349d20a8f88afd94f83c1e68bbc298/marshmallow-3.25.0.tar.gz", hash = "sha256:5ba94a4eb68894ad6761a505eb225daf7e5cb7b4c32af62d4a45e9d42665bc31", size = 176751 } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/76/26/b347619b719d4c048e038929769f8f6b28c6d930149b40d950bbdde31d48/marshmallow-3.25.0-py3-none-any.whl", hash = "sha256:50894cd57c6b097a6c6ed2bf216af47d10146990a54db52d03e32edb0448c905", size = 49480 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "matplotlib-inline" | ||||
| version = "0.1.7" | ||||
| @@ -1229,6 +1292,15 @@ wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "python-dotenv" | ||||
| version = "1.0.1" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "pyyaml" | ||||
| version = "6.0.2" | ||||
| @@ -1428,6 +1500,7 @@ dependencies = [ | ||||
|     { name = "django-ordered-model" }, | ||||
|     { name = "django-phonenumber-field" }, | ||||
|     { name = "django-simple-captcha" }, | ||||
|     { name = "environs", extra = ["django"] }, | ||||
|     { name = "ical" }, | ||||
|     { name = "jinja2" }, | ||||
|     { name = "libsass" }, | ||||
| @@ -1436,6 +1509,7 @@ dependencies = [ | ||||
|     { name = "pillow" }, | ||||
|     { name = "pydantic-extra-types" }, | ||||
|     { name = "python-dateutil" }, | ||||
|     { name = "redis", extra = ["hiredis"] }, | ||||
|     { name = "reportlab" }, | ||||
|     { name = "requests" }, | ||||
|     { name = "sentry-sdk" }, | ||||
| @@ -1463,7 +1537,6 @@ docs = [ | ||||
| ] | ||||
| prod = [ | ||||
|     { name = "psycopg", extra = ["c"] }, | ||||
|     { name = "redis", extra = ["hiredis"] }, | ||||
| ] | ||||
| tests = [ | ||||
|     { name = "freezegun" }, | ||||
| @@ -1487,6 +1560,7 @@ requires-dist = [ | ||||
|     { name = "django-ordered-model", specifier = ">=3.7.4,<4.0.0" }, | ||||
|     { name = "django-phonenumber-field", specifier = ">=8.0.0,<9.0.0" }, | ||||
|     { name = "django-simple-captcha", specifier = ">=0.6.0,<1.0.0" }, | ||||
|     { name = "environs", extras = ["django"], specifier = ">=14.1.0,<15.0.0" }, | ||||
|     { name = "ical", specifier = ">=8.3.0,<9.0.0" }, | ||||
|     { name = "jinja2", specifier = ">=3.1.4,<4.0.0" }, | ||||
|     { name = "libsass", specifier = ">=0.23.0,<1.0.0" }, | ||||
| @@ -1495,6 +1569,7 @@ requires-dist = [ | ||||
|     { name = "pillow", specifier = ">=11.0.0,<12.0.0" }, | ||||
|     { name = "pydantic-extra-types", specifier = ">=2.10.1,<3.0.0" }, | ||||
|     { name = "python-dateutil", specifier = ">=2.9.0.post0,<3.0.0.0" }, | ||||
|     { name = "redis", extras = ["hiredis"], specifier = ">=5.2.0,<6.0.0" }, | ||||
|     { name = "reportlab", specifier = ">=4.2.5,<5.0.0" }, | ||||
|     { name = "requests", specifier = ">=2.32.3" }, | ||||
|     { name = "sentry-sdk", specifier = ">=2.19.2,<3.0.0" }, | ||||
| @@ -1520,10 +1595,7 @@ docs = [ | ||||
|     { name = "mkdocstrings", specifier = ">=0.27.0,<1.0.0" }, | ||||
|     { name = "mkdocstrings-python", specifier = ">=1.12.2,<2.0.0" }, | ||||
| ] | ||||
| prod = [ | ||||
|     { name = "psycopg", extras = ["c"], specifier = ">=3.2.3,<4.0.0" }, | ||||
|     { name = "redis", extras = ["hiredis"], specifier = ">=5.2.0,<6.0.0" }, | ||||
| ] | ||||
| prod = [{ name = "psycopg", extras = ["c"], specifier = ">=3.2.3,<4.0.0" }] | ||||
| tests = [ | ||||
|     { name = "freezegun", specifier = ">=1.5.1,<2.0.0" }, | ||||
|     { name = "model-bakery", specifier = ">=1.20.0,<2.0.0" }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user