Unifomize license headers
This commit is contained in:
parent
9dc40279fa
commit
8d44182af8
51 changed files with 249 additions and 135 deletions
|
|
@ -1,4 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Backup script to put in /etc/cron.montly/
|
# Backup script to put in /etc/cron.montly/
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
rsync -avP /var/www/photos/photo21 /backup/
|
rsync -avP /var/www/photos/photo21 /backup/
|
||||||
sudo -u postgres pg_dump photo21 > /backup/pg_dump_photo21.sql
|
sudo -u postgres pg_dump photo21 > /backup/pg_dump_photo21.sql
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
[uwsgi]
|
[uwsgi]
|
||||||
# www-data can write media
|
# www-data can write media
|
||||||
uid = www-data
|
uid = www-data
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'photo21.settings')
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "photo21.settings")
|
||||||
try:
|
try:
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
|
|
@ -17,5 +17,5 @@ def main():
|
||||||
execute_from_command_line(sys.argv)
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
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 allauth.account.forms import SignupForm
|
from allauth.account.forms import SignupForm
|
||||||
|
|
@ -18,7 +22,9 @@ class CustomSignupForm(SignupForm):
|
||||||
Check that the email address ends with a trusted domain.
|
Check that the email address ends with a trusted domain.
|
||||||
"""
|
"""
|
||||||
email = super().clean_email()
|
email = super().clean_email()
|
||||||
if not email.endswith("@crans.org") and not email.endswith("@ens-paris-saclay.fr"):
|
if not email.endswith("@crans.org") and not email.endswith(
|
||||||
|
"@ens-paris-saclay.fr"
|
||||||
|
):
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
_("Must end with `@crans.org` or `@ens-paris-saclay.fr`.")
|
_("Must end with `@crans.org` or `@ens-paris-saclay.fr`.")
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import base64
|
import base64
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
@ -15,11 +19,12 @@ class SHA512PasswordHasher(BasePasswordHasher):
|
||||||
It is used to migrate passwords from old Symfony2 photos server.
|
It is used to migrate passwords from old Symfony2 photos server.
|
||||||
https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php
|
https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php
|
||||||
"""
|
"""
|
||||||
|
|
||||||
algorithm = "sha512"
|
algorithm = "sha512"
|
||||||
|
|
||||||
def encode(self, password, iteration, salt):
|
def encode(self, password, iteration, salt):
|
||||||
assert password is not None
|
assert password is not None
|
||||||
assert salt and '$' not in salt
|
assert salt and "$" not in salt
|
||||||
salted = force_bytes(password + "{" + salt + "}")
|
salted = force_bytes(password + "{" + salt + "}")
|
||||||
digest = hashlib.sha512(salted).digest()
|
digest = hashlib.sha512(salted).digest()
|
||||||
# "stretch" hash
|
# "stretch" hash
|
||||||
|
|
@ -30,19 +35,21 @@ class SHA512PasswordHasher(BasePasswordHasher):
|
||||||
return encoded[:128]
|
return encoded[:128]
|
||||||
|
|
||||||
def verify(self, password, encoded):
|
def verify(self, password, encoded):
|
||||||
algorithm, iteration, salt, hash = encoded.split('$', 3)
|
algorithm, iteration, salt, hash = encoded.split("$", 3)
|
||||||
assert algorithm == self.algorithm
|
assert algorithm == self.algorithm
|
||||||
encoded_2 = self.encode(password, iteration, salt)
|
encoded_2 = self.encode(password, iteration, salt)
|
||||||
return constant_time_compare(encoded, encoded_2)
|
return constant_time_compare(encoded, encoded_2)
|
||||||
|
|
||||||
def safe_summary(self, encoded):
|
def safe_summary(self, encoded):
|
||||||
algorithm, iteration, salt, hash = encoded.split('$', 3)
|
algorithm, iteration, salt, hash = encoded.split("$", 3)
|
||||||
assert algorithm == self.algorithm
|
assert algorithm == self.algorithm
|
||||||
return OrderedDict([
|
return OrderedDict(
|
||||||
(_('algorithm'), algorithm),
|
[
|
||||||
(_('salt'), mask_hash(salt, show=2)),
|
(_("algorithm"), algorithm),
|
||||||
(_('hash'), mask_hash(hash)),
|
(_("salt"), mask_hash(salt, show=2)),
|
||||||
])
|
(_("hash"), mask_hash(hash)),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
def harden_runtime(self, password, encoded):
|
def harden_runtime(self, password, encoded):
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# This file is part of photo21
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# This file is part of photo21
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# This file is part of photo21
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Django settings for photo21 project.
|
Django settings for photo21 project.
|
||||||
|
|
||||||
Generated by 'django-admin startproject' using Django 2.2.24.
|
|
||||||
|
|
||||||
For more information on this file, see
|
For more information on this file, see
|
||||||
https://docs.djangoproject.com/en/2.2/topics/settings/
|
https://docs.djangoproject.com/en/2.2/topics/settings/
|
||||||
|
|
||||||
|
|
@ -23,7 +25,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
||||||
|
|
||||||
# SECURITY WARNING: keep the secret key used in production secret!
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
SECRET_KEY = 'CHANGE ME'
|
SECRET_KEY = "CHANGE ME"
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
@ -38,7 +40,7 @@ ALLOWED_HOSTS = [
|
||||||
# Admins receive server errors, this is useful to be notified of potential bugs
|
# Admins receive server errors, this is useful to be notified of potential bugs
|
||||||
# By default MANAGERS=ADMINS, so admins also receive upload notifications
|
# By default MANAGERS=ADMINS, so admins also receive upload notifications
|
||||||
ADMINS = [
|
ADMINS = [
|
||||||
('admin', 'photos-admin@lists.crans.org'),
|
("admin", "photos-admin@lists.crans.org"),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Use secure cookies in production
|
# Use secure cookies in production
|
||||||
|
|
@ -53,47 +55,47 @@ SECURE_HSTS_PRELOAD = True
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
'django.contrib.admin',
|
"django.contrib.admin",
|
||||||
'django.contrib.admindocs',
|
"django.contrib.admindocs",
|
||||||
'django.contrib.auth',
|
"django.contrib.auth",
|
||||||
'django.contrib.contenttypes',
|
"django.contrib.contenttypes",
|
||||||
'django.contrib.sessions',
|
"django.contrib.sessions",
|
||||||
'django.contrib.sites',
|
"django.contrib.sites",
|
||||||
'django.contrib.messages',
|
"django.contrib.messages",
|
||||||
'django.contrib.staticfiles',
|
"django.contrib.staticfiles",
|
||||||
'allauth',
|
"allauth",
|
||||||
'allauth.account',
|
"allauth.account",
|
||||||
'allauth.socialaccount',
|
"allauth.socialaccount",
|
||||||
'allauth_note_kfet',
|
"allauth_note_kfet",
|
||||||
'crispy_forms',
|
"crispy_forms",
|
||||||
'photologue',
|
"photologue",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
"django.middleware.security.SecurityMiddleware",
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
'django.middleware.common.CommonMiddleware',
|
"django.middleware.common.CommonMiddleware",
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
"django.middleware.locale.LocaleMiddleware",
|
||||||
'django.contrib.sites.middleware.CurrentSiteMiddleware',
|
"django.contrib.sites.middleware.CurrentSiteMiddleware",
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'photo21.urls'
|
ROOT_URLCONF = "photo21.urls"
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
'DIRS': [os.path.join(BASE_DIR, 'photo21/templates')],
|
"DIRS": [os.path.join(BASE_DIR, "photo21/templates")],
|
||||||
'APP_DIRS': True,
|
"APP_DIRS": True,
|
||||||
'OPTIONS': {
|
"OPTIONS": {
|
||||||
'context_processors': [
|
"context_processors": [
|
||||||
'django.template.context_processors.debug',
|
"django.template.context_processors.debug",
|
||||||
'django.template.context_processors.request',
|
"django.template.context_processors.request",
|
||||||
'django.contrib.auth.context_processors.auth',
|
"django.contrib.auth.context_processors.auth",
|
||||||
'django.contrib.messages.context_processors.messages',
|
"django.contrib.messages.context_processors.messages",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -101,22 +103,21 @@ TEMPLATES = [
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = [
|
AUTHENTICATION_BACKENDS = [
|
||||||
# Needed to login by username in Django admin, regardless of `allauth`
|
# Needed to login by username in Django admin, regardless of `allauth`
|
||||||
'django.contrib.auth.backends.ModelBackend',
|
"django.contrib.auth.backends.ModelBackend",
|
||||||
|
|
||||||
# `allauth` specific authentication methods, such as login by e-mail
|
# `allauth` specific authentication methods, such as login by e-mail
|
||||||
'allauth.account.auth_backends.AuthenticationBackend',
|
"allauth.account.auth_backends.AuthenticationBackend",
|
||||||
]
|
]
|
||||||
|
|
||||||
WSGI_APPLICATION = 'photo21.wsgi.application'
|
WSGI_APPLICATION = "photo21.wsgi.application"
|
||||||
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
"default": {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
"ENGINE": "django.db.backends.sqlite3",
|
||||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,38 +127,38 @@ DATABASES = {
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
PASSWORD_HASHERS = [
|
PASSWORD_HASHERS = [
|
||||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
|
||||||
'photo21.hashers.SHA512PasswordHasher',
|
"photo21.hashers.SHA512PasswordHasher",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = "UTC"
|
||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
# Limit available languages to this subset
|
# Limit available languages to this subset
|
||||||
LANGUAGES = [
|
LANGUAGES = [
|
||||||
('de', _('German')),
|
("de", _("German")),
|
||||||
('en', _('English')),
|
("en", _("English")),
|
||||||
('es', _('Spanish')),
|
("es", _("Spanish")),
|
||||||
('fr', _('French')),
|
("fr", _("French")),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Allow more fields in URL to edit large galleries
|
# Allow more fields in URL to edit large galleries
|
||||||
|
|
@ -166,9 +167,9 @@ DATA_UPLOAD_MAX_NUMBER_FIELDS = 10240
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = "/static/"
|
||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [
|
||||||
os.path.join(BASE_DIR, 'photo21/static'),
|
os.path.join(BASE_DIR, "photo21/static"),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Collect statics to /static/
|
# Collect statics to /static/
|
||||||
|
|
@ -177,48 +178,48 @@ STATIC_ROOT = os.path.join(BASE_DIR, "static/")
|
||||||
|
|
||||||
# Use /media/ for user uploaded media
|
# Use /media/ for user uploaded media
|
||||||
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = "/media/"
|
||||||
|
|
||||||
LOCALE_PATHS = [os.path.join(BASE_DIR, 'photo21/locale')]
|
LOCALE_PATHS = [os.path.join(BASE_DIR, "photo21/locale")]
|
||||||
|
|
||||||
FIXTURE_DIRS = [os.path.join(BASE_DIR, 'photo21/fixtures')]
|
FIXTURE_DIRS = [os.path.join(BASE_DIR, "photo21/fixtures")]
|
||||||
|
|
||||||
# Do not send email during debug
|
# Do not send email during debug
|
||||||
# By default Django sends mails to localhost:25 without authentification
|
# By default Django sends mails to localhost:25 without authentification
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||||
|
|
||||||
# Mail will be sent from this address
|
# Mail will be sent from this address
|
||||||
SERVER_EMAIL = "photos@crans.org"
|
SERVER_EMAIL = "photos@crans.org"
|
||||||
DEFAULT_FROM_EMAIL = f"Serveur photos <{SERVER_EMAIL}>"
|
DEFAULT_FROM_EMAIL = f"Serveur photos <{SERVER_EMAIL}>"
|
||||||
EMAIL_SUBJECT_PREFIX = '[Serveur photos] '
|
EMAIL_SUBJECT_PREFIX = "[Serveur photos] "
|
||||||
|
|
||||||
# After login redirect user to transfer page
|
# After login redirect user to transfer page
|
||||||
LOGIN_REDIRECT_URL = '/'
|
LOGIN_REDIRECT_URL = "/"
|
||||||
|
|
||||||
# Use only one Django Sites
|
# Use only one Django Sites
|
||||||
SITE_ID = 1
|
SITE_ID = 1
|
||||||
|
|
||||||
# Django message
|
# Django message
|
||||||
MESSAGE_TAGS = {
|
MESSAGE_TAGS = {
|
||||||
messages.DEBUG: 'alert-secondary',
|
messages.DEBUG: "alert-secondary",
|
||||||
messages.INFO: 'alert-info',
|
messages.INFO: "alert-info",
|
||||||
messages.SUCCESS: 'alert-success',
|
messages.SUCCESS: "alert-success",
|
||||||
messages.WARNING: 'alert-warning',
|
messages.WARNING: "alert-warning",
|
||||||
messages.ERROR: 'alert-danger',
|
messages.ERROR: "alert-danger",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Allauth configuration
|
# Allauth configuration
|
||||||
ACCOUNT_EMAIL_REQUIRED = True
|
ACCOUNT_EMAIL_REQUIRED = True
|
||||||
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
||||||
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
|
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
|
||||||
ACCOUNT_FORMS = {'signup': 'photo21.forms.CustomSignupForm'}
|
ACCOUNT_FORMS = {"signup": "photo21.forms.CustomSignupForm"}
|
||||||
SOCIALACCOUNT_PROVIDERS = {
|
SOCIALACCOUNT_PROVIDERS = {
|
||||||
'notekfet': {
|
"notekfet": {
|
||||||
# Fetch user profile
|
# Fetch user profile
|
||||||
'SCOPE': ['1_1'],
|
"SCOPE": ["1_1"],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use Bootstrap forms
|
# Use Bootstrap forms
|
||||||
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
CRISPY_TEMPLATE_PACK = "bootstrap4"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
|
|
||||||
{% block title %}{% block head_title %}{% endblock %}{% endblock title %}
|
{% block title %}{% block head_title %}{% endblock %}{% endblock title %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{% extends "account/base.html" %}
|
{% extends "account/base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n crispy_forms_tags %}
|
{% load i18n crispy_forms_tags %}
|
||||||
{% block head_title %}{% trans "E-mail Addresses" %}{% endblock %}
|
{% block head_title %}{% trans "E-mail Addresses" %}{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{% extends "account/base.html" %}
|
{% extends "account/base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n crispy_forms_tags account socialaccount %}
|
{% load i18n crispy_forms_tags account socialaccount %}
|
||||||
{% block head_title %}{% trans "Sign In" %}{% endblock %}
|
{% block head_title %}{% trans "Sign In" %}{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{% extends "account/base.html" %}
|
{% extends "account/base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block head_title %}{% trans "Sign Out" %}{% endblock %}
|
{% block head_title %}{% trans "Sign Out" %}{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{% extends "account/base.html" %}
|
{% extends "account/base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n crispy_forms_tags %}
|
{% load i18n crispy_forms_tags %}
|
||||||
{% block head_title %}{% trans "Signup" %}{% endblock %}
|
{% block head_title %}{% trans "Signup" %}{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load static i18n %}
|
{% load static i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{% extends "socialaccount/base.html" %}
|
{% extends "socialaccount/base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block head_title %}{% trans "Account Connections" %}{% endblock %}
|
{% block head_title %}{% trans "Account Connections" %}{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,13 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
"""photo21 URL Configuration
|
"""photo21 URL Configuration
|
||||||
|
|
||||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
https://docs.djangoproject.com/en/2.2/topics/http/urls/
|
https://docs.djangoproject.com/en/2.2/topics/http/urls/
|
||||||
Examples:
|
|
||||||
Function views
|
|
||||||
1. Add an import: from my_app import views
|
|
||||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
|
||||||
Class-based views
|
|
||||||
1. Add an import: from other_app.views import Home
|
|
||||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
|
||||||
Including another URLconf
|
|
||||||
1. Import the include() function: from django.urls import include, path
|
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import include, path, re_path
|
from django.urls import include, path, re_path
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
@ -21,16 +16,18 @@ from django.conf.urls.static import static
|
||||||
from .views import IndexView, MediaAccess
|
from .views import IndexView, MediaAccess
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', IndexView.as_view(), name='index'),
|
path("", IndexView.as_view(), name="index"),
|
||||||
path('', include('photologue.urls', namespace='photologue')),
|
path("", include("photologue.urls", namespace="photologue")),
|
||||||
path('accounts/', include('allauth.urls')),
|
path("accounts/", include("allauth.urls")),
|
||||||
path('i18n/', include('django.conf.urls.i18n')),
|
path("i18n/", include("django.conf.urls.i18n")),
|
||||||
path('admin/doc/', include('django.contrib.admindocs.urls')),
|
path("admin/doc/", include("django.contrib.admindocs.urls")),
|
||||||
path('admin/', admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
]
|
]
|
||||||
|
|
||||||
# In production media are served through NGINX with X-Accel-Redirect
|
# In production media are served through NGINX with X-Accel-Redirect
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
else:
|
else:
|
||||||
urlpatterns.append(re_path('^media/(?P<path>.*)', MediaAccess.as_view(), name='media'))
|
urlpatterns.append(
|
||||||
|
re_path("^media/(?P<path>.*)", MediaAccess.as_view(), name="media")
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# Copyright (C) 2021 by BDE ENS Paris-Saclay
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2021-2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
|
@ -11,8 +12,8 @@ class MediaAccess(LoginRequiredMixin, View):
|
||||||
def get(self, request, path):
|
def get(self, request, path):
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
# Content-type will be detected by nginx
|
# Content-type will be detected by nginx
|
||||||
del response['Content-Type']
|
del response["Content-Type"]
|
||||||
response['X-Accel-Redirect'] = '/protected/media/' + path
|
response["X-Accel-Redirect"] = "/protected/media/" + path
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
"""
|
"""
|
||||||
WSGI config for photo21 project.
|
WSGI config for photo21 project.
|
||||||
|
|
||||||
|
|
@ -11,6 +15,6 @@ import os
|
||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'photo21.settings')
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "photo21.settings")
|
||||||
|
|
||||||
application = get_wsgi_application()
|
application = get_wsgi_application()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from crispy_forms.helper import FormHelper
|
from crispy_forms.helper import FormHelper
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# This file is part of photo21
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Translators:
|
# Translators:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# This file is part of photo21
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Translators:
|
# Translators:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# This file is part of photo21
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Translators:
|
# Translators:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
# Generated by Django 3.2.11 on 2022-01-30 10:14
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import django.core.validators
|
import django.core.validators
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
# Generated by Django 3.2.11 on 2022-01-30 10:20
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
# Generated by Django 3.2.11 on 2022-01-30 12:14
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Custom LightGallery plugin to add some buttons for administration
|
* Custom LightGallery plugin to add some buttons for administration
|
||||||
*
|
*
|
||||||
|
* This file is part of photo21
|
||||||
|
* Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load static i18n %}
|
{% load static i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<div class="card text-white bg-dark">
|
<div class="card text-white bg-dark">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}{{ object.name }}{% endblock %}
|
{% block title %}{{ object.name }}{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
|
This file is part of photo21
|
||||||
|
Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n crispy_forms_tags %}
|
{% load i18n crispy_forms_tags %}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from django.urls import path, re_path
|
from django.urls import path, re_path
|
||||||
|
|
||||||
from .views import (
|
from .views import (
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# Copyright (C) 2021 by BDE ENS Paris-Saclay
|
# This file is part of photo21
|
||||||
|
# Copyright (C) 2021-2022 Amicale des élèves de l'ENS Paris-Saclay
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue