diff --git a/.credentials/HCAPTCHA_SECRET b/.credentials/HCAPTCHA_SECRET new file mode 100644 index 00000000..7daa69d3 --- /dev/null +++ b/.credentials/HCAPTCHA_SECRET @@ -0,0 +1 @@ +0x0000000000000000000000000000000000000000 diff --git a/.credentials/HCAPTCHA_SITEKEY b/.credentials/HCAPTCHA_SITEKEY new file mode 100644 index 00000000..f5093057 --- /dev/null +++ b/.credentials/HCAPTCHA_SITEKEY @@ -0,0 +1 @@ +10000000-ffff-ffff-ffff-000000000001 diff --git a/.credentials/KFETOPEN_TOKEN b/.credentials/KFETOPEN_TOKEN new file mode 100644 index 00000000..4cbb2bf5 --- /dev/null +++ b/.credentials/KFETOPEN_TOKEN @@ -0,0 +1 @@ +k-feste_token diff --git a/.credentials/SECRET_KEY b/.credentials/SECRET_KEY new file mode 100644 index 00000000..de873cc2 --- /dev/null +++ b/.credentials/SECRET_KEY @@ -0,0 +1 @@ +insecure-key diff --git a/gestioasso/settings/cof_prod.py b/gestioasso/settings/cof_prod.py index 58496057..91bee648 100644 --- a/gestioasso/settings/cof_prod.py +++ b/gestioasso/settings/cof_prod.py @@ -67,8 +67,8 @@ INSTALLED_APPS = ( "wagtail.images", "wagtail.search", "wagtail.admin", - "wagtail.core", - "wagtail.contrib.modeladmin", + "wagtail", + # "wagtail.contrib.modeladmin", "wagtail.contrib.routable_page", "wagtailmenus", "modelcluster", diff --git a/gestioasso/settings_bds.py b/gestioasso/settings_bds.py new file mode 100644 index 00000000..231ae101 --- /dev/null +++ b/gestioasso/settings_bds.py @@ -0,0 +1,194 @@ +""" +Django settings for the gestioBDS project. +""" + +import os +from pathlib import Path + +from loadcredential import Credentials + +credentials = Credentials(env_prefix="GESTIOBDS_") + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +# WARNING: keep the secret key used in production secret! +SECRET_KEY = credentials["SECRET_KEY"] + +# WARNING: don't run with debug turned on in production! +DEBUG = credentials.get_json("DEBUG", False) + +ALLOWED_HOSTS = credentials.get_json("ALLOWED_HOSTS", []) +ADMINS = credentials.get_json("ADMINS", []) + +SERVER_EMAIL = credentials.get("SERVER_EMAIL") +EMAIL_HOST = credentials.get("EMAIL_HOST") + +DEFAULT_AUTO_FIELD = "django.db.models.AutoField" + + +## +# Installed Apps configuration + +INSTALLED_APPS = [ + "shared", + # Must be before 'django.contrib.admin'. + # https://django-autocomplete-light.readthedocs.io/en/master/install.html + "dal", + "dal_select2", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.sites", + "django.contrib.messages", + "django.contrib.admin", + "django.contrib.admindocs", + "gestioasso.apps.IgnoreSrcStaticFilesConfig", + "django_cas_ng", + "bootstrapform", + "widget_tweaks", + "bds", + "events", + "clubs", + "authens", +] + + +## +# Middleware configuration + +MIDDLEWARE = [ + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "django.middleware.security.SecurityMiddleware", + "django.middleware.locale.LocaleMiddleware", +] + + +## +# URL configuration + +ROOT_URLCONF = "gestioasso.urls" + + +## +# Templates configuration + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + "django.template.context_processors.i18n", + "django.template.context_processors.media", + "django.template.context_processors.static", + ] + }, + } +] + + +## +# Database configuration + +DATABASES = credentials.get_json( + "DATABASES", + default={ + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": (BASE_DIR / "db.sqlite3"), + } + }, +) + +CACHES = credentials.get_json( + "CACHES", + default={ + "default": { + "BACKEND": "django.core.cache.backends.locmem.LocMemCache", + }, + }, +) + +CORS_ORIGIN_WHITELIST = credentials.get("CORS_ORIGIN_WHITELIST", []) + + +SITE_ID = 1 + + +### +# Staticfiles configuration + +STATIC_ROOT = credentials["STATIC_ROOT"] +STATIC_URL = "/static/" + +MEDIA_ROOT = credentials.get("MEDIA_ROOT", (BASE_DIR / "media")) +MEDIA_URL = "/media/" + + +## +# Authens and Authentication configuration + +AUTHENTICATION_BACKENDS = [ + "django.contrib.auth.backends.ModelBackend", + "authens.backends.ENSCASBackend", + "authens.backends.OldCASBackend", +] + +AUTHENS_USE_OLDCAS = False + +LOGIN_URL = "authens:login" +LOGIN_REDIRECT_URL = "bds:home" +LOGOUT_REDIRECT_URL = "bds:home" + + +# --- +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ +# --- + +LANGUAGE_CODE = "fr-fr" +TIME_ZONE = "Europe/Paris" +USE_I18N = True +USE_L10N = True +USE_TZ = True +LANGUAGES = (("fr", "Français"), ("en", "English")) +FORMAT_MODULE_PATH = "gestioasso.locale" + +## +# Development configuration + +if DEBUG: + EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" + + def show_toolbar(request): + """ + On active la debug-toolbar en mode développement local sauf : + - dans l'admin où ça ne sert pas à grand chose; + - si la variable d'environnement DJANGO_NO_DDT est à 1 → ça permet de la désactiver + sans modifier ce fichier en exécutant `export DJANGO_NO_DDT=1` dans le terminal + qui lance `./manage.py runserver`. + + Autre side effect de cette fonction : on ne fait pas la vérification de INTERNAL_IPS + que ferait la debug-toolbar par défaut, ce qui la fait fonctionner aussi à + l'intérieur de Vagrant (comportement non testé depuis un moment…) + """ + + env_no_ddt = bool(os.environ.get("DJANGO_NO_DDT", None)) + return not (env_no_ddt or request.path.startswith("/admin/")) + + ## + # Django Debug Toolbar configuration + + DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": show_toolbar} + INSTALLED_APPS += ["debug_toolbar"] + MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE diff --git a/gestioasso/settings_cof.py b/gestioasso/settings_cof.py new file mode 100644 index 00000000..4d24caf2 --- /dev/null +++ b/gestioasso/settings_cof.py @@ -0,0 +1,318 @@ +""" +Django settings for the gestioCOF project. +""" + +import os +from datetime import datetime, timedelta +from pathlib import Path + +from django.urls import reverse_lazy +from loadcredential import Credentials + +credentials = Credentials(env_prefix="GESTIOCOF_") + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +# WARNING: keep the secret key used in production secret! +SECRET_KEY = credentials["SECRET_KEY"] + +# WARNING: don't run with debug turned on in production! +DEBUG = credentials.get_json("DEBUG", False) + +ALLOWED_HOSTS = credentials.get_json("ALLOWED_HOSTS", []) +ADMINS = credentials.get_json("ADMINS", []) + +SERVER_EMAIL = credentials.get("SERVER_EMAIL") +EMAIL_HOST = credentials.get("EMAIL_HOST") + +LDAP_SERVER_URL = credentials.get("LDAP_SERVER_URL") + +DEFAULT_AUTO_FIELD = "django.db.models.AutoField" + + +## +# Installed Apps configuration + +INSTALLED_APPS = [ + "gestioncof", + # Must be before django admin + # https://github.com/infoportugal/wagtail-modeltranslation/issues/193 + "wagtail_modeltranslation", + "wagtail_modeltranslation.makemigrations", + "wagtail_modeltranslation.migrate", + "modeltranslation", + "shared", + # Must be before 'django.contrib.admin'. + # https://django-autocomplete-light.readthedocs.io/en/master/install.html + "dal", + "dal_select2", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.sites", + "django.contrib.messages", + "django.contrib.admin", + "django.contrib.admindocs", + "gestioasso.apps.IgnoreSrcStaticFilesConfig", + "django_cas_ng", + "bootstrapform", + "widget_tweaks", + "bda", + "petitscours", + "hcaptcha", + "kfet", + "kfet.open", + "channels", + "djconfig", + "wagtail.contrib.forms", + "wagtail.contrib.redirects", + "wagtail.embeds", + "wagtail.sites", + "wagtail.users", + "wagtail.snippets", + "wagtail.documents", + "wagtail.images", + "wagtail.search", + "wagtail.admin", + "wagtail", + # "wagtail.contrib.modeladmin", + "wagtail.contrib.routable_page", + "wagtailmenus", + "modelcluster", + "taggit", + "kfet.auth", + "kfet.cms", + "gestioncof.cms", + "django_js_reverse", +] + + +## +# Middleware configuration + +MIDDLEWARE = [ + "corsheaders.middleware.CorsMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "django.middleware.security.SecurityMiddleware", + "django.middleware.locale.LocaleMiddleware", + "djconfig.middleware.DjConfigMiddleware", + "wagtail.contrib.redirects.middleware.RedirectMiddleware", +] + + +## +# URL configuration + +ROOT_URLCONF = "gestioasso.urls" + + +## +# Templates configuration + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "wagtailmenus.context_processors.wagtailmenus", + "djconfig.context_processors.config", + "gestioncof.shared.context_processor", + "kfet.auth.context_processors.temporary_auth", + "kfet.context_processors.config", + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + "django.template.context_processors.i18n", + "django.template.context_processors.media", + "django.template.context_processors.static", + ] + }, + } +] + + +## +# Wagtail configuration + +WAGTAIL_SITE_NAME = "GestioCOF" +WAGTAIL_ENABLE_UPDATE_CHECK = False +TAGGIT_CASE_INSENSITIVE = True + +## +# Django-js-reverse settings + +JS_REVERSE_JS_VAR_NAME = "django_urls" +# Quand on aura namespace les urls... +# JS_REVERSE_INCLUDE_ONLY_NAMESPACES = ['k-fet'] + +## +# K-Fêt history configuration + +# L'historique n'est accesible que d'aujourd'hui +# à aujourd'hui - KFET_HISTORY_DATE_LIMIT +KFET_HISTORY_DATE_LIMIT = timedelta(days=7) + +# Limite plus longue pour les chefs/trez +# (qui ont la permission kfet.access_old_history) +KFET_HISTORY_LONG_DATE_LIMIT = timedelta(days=30) + +# These accounts don't represent actual people and can be freely accessed +# Identification based on trigrammes +KFET_HISTORY_NO_DATE_LIMIT_TRIGRAMMES = ["LIQ", "#13"] +KFET_HISTORY_NO_DATE_LIMIT = datetime(1794, 10, 30) # AKA the distant past + + +## +# Database configuration + +DATABASES = credentials.get_json( + "DATABASES", + default={ + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": (BASE_DIR / "db.sqlite3"), + } + }, +) + +CACHES = credentials.get_json( + "CACHES", + default={ + "default": { + "BACKEND": "django.core.cache.backends.locmem.LocMemCache", + }, + }, +) + +CHANNEL_LAYERS = credentials.get_json( + "CHANNEL_LAYERS", + default={ + "default": { + "BACKEND": "channels.layers.InMemoryChannelLayer", + } + }, +) + +CORS_ORIGIN_WHITELIST = credentials.get("CORS_ORIGIN_WHITELIST", []) + + +SITE_ID = 1 + + +### +# Staticfiles configuration + +STATIC_ROOT = credentials["STATIC_ROOT"] +STATIC_URL = "/static/" + +MEDIA_ROOT = credentials.get("MEDIA_ROOT", (BASE_DIR / "media")) +MEDIA_URL = "/media/" + + +## +# Authentication configuration + +AUTHENTICATION_BACKENDS = [ + "kfet.auth.backends.BlockFrozenAccountBackend", # Must be in first + "django.contrib.auth.backends.ModelBackend", + "gestioncof.shared.COFCASBackend", + "kfet.auth.backends.GenericBackend", +] + +LOGIN_URL = "cof-login" +LOGIN_REDIRECT_URL = reverse_lazy("home") + +# FIXME: Switch to authens +CAS_SERVER_URL = "https://cas.eleves.ens.fr/" +CAS_VERSION = "2" +CAS_LOGIN_MSG = None +CAS_IGNORE_REFERER = True +CAS_REDIRECT_URL = "/" +CAS_EMAIL_FORMAT = "%s@clipper.ens.fr" + + +## +# h-captcha configuration + +HCAPTCHA_SITEKEY = credentials["HCAPTCHA_SITEKEY"] +HCAPTCHA_SECRET = credentials["HCAPTCHA_SECRET"] + +## +# K-Fêt token for the openness indicator + +KFETOPEN_TOKEN = credentials["KFETOPEN_TOKEN"] + + +## +# Mail configuration + +MAIL_DATA = { + "petits_cours": { + "FROM": "Le COF ", + "BCC": "archivescof@gmail.com", + "REPLYTO": "cof@ens.fr", + }, + "rappels": { + "FROM": "Le BdA ", + "REPLYTO": "Le BdA ", + }, + "rappel_negatif": { + "FROM": "La K-Fêt ", + "REPLYTO": "La K-Fêt ", + }, + "revente": { + "FROM": "BdA-Revente ", + "REPLYTO": "BdA-Revente ", + }, +} + + +# --- +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ +# --- + +LANGUAGE_CODE = "fr-fr" +TIME_ZONE = "Europe/Paris" +USE_I18N = True +USE_L10N = True +USE_TZ = True +LANGUAGES = (("fr", "Français"), ("en", "English")) +FORMAT_MODULE_PATH = "gestioasso.locale" + +## +# Development configuration + +if DEBUG: + EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" + + def show_toolbar(request): + """ + On active la debug-toolbar en mode développement local sauf : + - dans l'admin où ça ne sert pas à grand chose; + - si la variable d'environnement DJANGO_NO_DDT est à 1 → ça permet de la désactiver + sans modifier ce fichier en exécutant `export DJANGO_NO_DDT=1` dans le terminal + qui lance `./manage.py runserver`. + + Autre side effect de cette fonction : on ne fait pas la vérification de INTERNAL_IPS + que ferait la debug-toolbar par défaut, ce qui la fait fonctionner aussi à + l'intérieur de Vagrant (comportement non testé depuis un moment…) + """ + + env_no_ddt = bool(os.environ.get("DJANGO_NO_DDT", None)) + return not (env_no_ddt or request.path.startswith("/admin/")) + + ## + # Django Debug Toolbar configuration + + DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": show_toolbar} + INSTALLED_APPS += ["debug_toolbar"] + MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE diff --git a/gestioasso/urls.py b/gestioasso/urls.py index 10173fbb..cd1ccc47 100644 --- a/gestioasso/urls.py +++ b/gestioasso/urls.py @@ -1,6 +1,7 @@ """ Fichier principal de configuration des urls du projet GestioCOF """ + from django.conf import settings from django.conf.urls.i18n import i18n_patterns from django.conf.urls.static import static @@ -58,10 +59,10 @@ if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) -# Wagtail URLs (wagtail.core urls must be last, as catch-all) -if "wagtail.core" in settings.INSTALLED_APPS: +# Wagtail URLs (wagtail urls must be last, as catch-all) +if "wagtail" in settings.INSTALLED_APPS: + from wagtail import urls as wagtail_urls from wagtail.admin import urls as wagtailadmin_urls - from wagtail.core import urls as wagtail_urls from wagtail.documents import urls as wagtaildocs_urls urlpatterns += [ diff --git a/gestioncof/cms/migrations/0001_initial.py b/gestioncof/cms/migrations/0001_initial.py index 36a3ff1f..ef024c74 100644 --- a/gestioncof/cms/migrations/0001_initial.py +++ b/gestioncof/cms/migrations/0001_initial.py @@ -3,9 +3,9 @@ from __future__ import unicode_literals import django.db.models.deletion +import wagtail.blocks import wagtail.contrib.routable_page.models -import wagtail.core.blocks -import wagtail.core.fields +import wagtail.fields import wagtail.images.blocks from django.db import migrations, models @@ -72,18 +72,14 @@ class Migration(migrations.Migration): blank=True, null=True, verbose_name="Description rapide" ), ), - ("body", wagtail.core.fields.RichTextField(verbose_name="Contenu")), + ("body", wagtail.fields.RichTextField(verbose_name="Contenu")), ( "body_fr", - wagtail.core.fields.RichTextField( - null=True, verbose_name="Contenu" - ), + wagtail.fields.RichTextField(null=True, verbose_name="Contenu"), ), ( "body_en", - wagtail.core.fields.RichTextField( - null=True, verbose_name="Contenu" - ), + wagtail.fields.RichTextField(null=True, verbose_name="Contenu"), ), ( "is_event", @@ -138,46 +134,40 @@ class Migration(migrations.Migration): to="wagtailcore.Page", ), ), - ("body", wagtail.core.fields.RichTextField(verbose_name="Description")), + ("body", wagtail.fields.RichTextField(verbose_name="Description")), ( "body_fr", - wagtail.core.fields.RichTextField( - null=True, verbose_name="Description" - ), + wagtail.fields.RichTextField(null=True, verbose_name="Description"), ), ( "body_en", - wagtail.core.fields.RichTextField( - null=True, verbose_name="Description" - ), + wagtail.fields.RichTextField(null=True, verbose_name="Description"), ), ( "links", - wagtail.core.fields.StreamField( + wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "url", - wagtail.core.blocks.URLBlock(required=True), + wagtail.blocks.URLBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock( - required=True - ), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), @@ -186,31 +176,29 @@ class Migration(migrations.Migration): ), ( "links_fr", - wagtail.core.fields.StreamField( + wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "url", - wagtail.core.blocks.URLBlock(required=True), + wagtail.blocks.URLBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock( - required=True - ), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), @@ -220,31 +208,29 @@ class Migration(migrations.Migration): ), ( "links_en", - wagtail.core.fields.StreamField( + wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "url", - wagtail.core.blocks.URLBlock(required=True), + wagtail.blocks.URLBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock( - required=True - ), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), @@ -286,17 +272,17 @@ class Migration(migrations.Migration): ), ( "introduction", - wagtail.core.fields.RichTextField(verbose_name="Introduction"), + wagtail.fields.RichTextField(verbose_name="Introduction"), ), ( "introduction_fr", - wagtail.core.fields.RichTextField( + wagtail.fields.RichTextField( null=True, verbose_name="Introduction" ), ), ( "introduction_en", - wagtail.core.fields.RichTextField( + wagtail.fields.RichTextField( null=True, verbose_name="Introduction" ), ), @@ -329,27 +315,27 @@ class Migration(migrations.Migration): ), ( "body", - wagtail.core.fields.StreamField( + wagtail.fields.StreamField( [ ( "heading", - wagtail.core.blocks.CharBlock(classname="full title"), + wagtail.blocks.CharBlock(classname="full title"), ), - ("paragraph", wagtail.core.blocks.RichTextBlock()), + ("paragraph", wagtail.blocks.RichTextBlock()), ("image", wagtail.images.blocks.ImageChooserBlock()), ( "iframe", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "url", - wagtail.core.blocks.URLBlock( + wagtail.blocks.URLBlock( "Adresse de la page" ), ), ( "height", - wagtail.core.blocks.CharBlock( + wagtail.blocks.CharBlock( "Hauteur (en pixels)" ), ), @@ -361,27 +347,27 @@ class Migration(migrations.Migration): ), ( "body_fr", - wagtail.core.fields.StreamField( + wagtail.fields.StreamField( [ ( "heading", - wagtail.core.blocks.CharBlock(classname="full title"), + wagtail.blocks.CharBlock(classname="full title"), ), - ("paragraph", wagtail.core.blocks.RichTextBlock()), + ("paragraph", wagtail.blocks.RichTextBlock()), ("image", wagtail.images.blocks.ImageChooserBlock()), ( "iframe", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "url", - wagtail.core.blocks.URLBlock( + wagtail.blocks.URLBlock( "Adresse de la page" ), ), ( "height", - wagtail.core.blocks.CharBlock( + wagtail.blocks.CharBlock( "Hauteur (en pixels)" ), ), @@ -394,27 +380,27 @@ class Migration(migrations.Migration): ), ( "body_en", - wagtail.core.fields.StreamField( + wagtail.fields.StreamField( [ ( "heading", - wagtail.core.blocks.CharBlock(classname="full title"), + wagtail.blocks.CharBlock(classname="full title"), ), - ("paragraph", wagtail.core.blocks.RichTextBlock()), + ("paragraph", wagtail.blocks.RichTextBlock()), ("image", wagtail.images.blocks.ImageChooserBlock()), ( "iframe", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "url", - wagtail.core.blocks.URLBlock( + wagtail.blocks.URLBlock( "Adresse de la page" ), ), ( "height", - wagtail.core.blocks.CharBlock( + wagtail.blocks.CharBlock( "Hauteur (en pixels)" ), ), @@ -448,17 +434,17 @@ class Migration(migrations.Migration): ), ( "introduction", - wagtail.core.fields.RichTextField(verbose_name="Introduction"), + wagtail.fields.RichTextField(verbose_name="Introduction"), ), ( "introduction_fr", - wagtail.core.fields.RichTextField( + wagtail.fields.RichTextField( null=True, verbose_name="Introduction" ), ), ( "introduction_en", - wagtail.core.fields.RichTextField( + wagtail.fields.RichTextField( null=True, verbose_name="Introduction" ), ), diff --git a/gestioncof/cms/migrations/0003_directory_entry_optional_links.py b/gestioncof/cms/migrations/0003_directory_entry_optional_links.py index 6555236b..22533193 100644 --- a/gestioncof/cms/migrations/0003_directory_entry_optional_links.py +++ b/gestioncof/cms/migrations/0003_directory_entry_optional_links.py @@ -1,7 +1,7 @@ # Generated by Django 2.2.8 on 2019-12-20 16:22 -import wagtail.core.blocks -import wagtail.core.fields +import wagtail.blocks +import wagtail.fields from django.db import migrations @@ -14,26 +14,26 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="cofdirectoryentrypage", name="links", - field=wagtail.core.fields.StreamField( + field=wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("url", wagtail.core.blocks.URLBlock(required=True)), - ("texte", wagtail.core.blocks.CharBlock()), + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock(required=True), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), @@ -44,26 +44,26 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="cofdirectoryentrypage", name="links_en", - field=wagtail.core.fields.StreamField( + field=wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("url", wagtail.core.blocks.URLBlock(required=True)), - ("texte", wagtail.core.blocks.CharBlock()), + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock(required=True), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), @@ -75,26 +75,26 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="cofdirectoryentrypage", name="links_fr", - field=wagtail.core.fields.StreamField( + field=wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("url", wagtail.core.blocks.URLBlock(required=True)), - ("texte", wagtail.core.blocks.CharBlock()), + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock(required=True), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), diff --git a/gestioncof/cms/migrations/0004_auto_20200829_2314.py b/gestioncof/cms/migrations/0004_auto_20200829_2314.py index dd525a2c..eb660ad9 100644 --- a/gestioncof/cms/migrations/0004_auto_20200829_2314.py +++ b/gestioncof/cms/migrations/0004_auto_20200829_2314.py @@ -1,7 +1,7 @@ # Generated by Django 2.2.15 on 2020-08-29 21:14 -import wagtail.core.blocks -import wagtail.core.fields +import wagtail.blocks +import wagtail.fields from django.db import migrations @@ -14,35 +14,35 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="cofdirectoryentrypage", name="links", - field=wagtail.core.fields.StreamField( + field=wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("url", wagtail.core.blocks.URLBlock(required=True)), - ("texte", wagtail.core.blocks.CharBlock()), + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock(required=True), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "info", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("nom", wagtail.core.blocks.CharBlock(required=False)), - ("texte", wagtail.core.blocks.CharBlock(required=True)), + ("nom", wagtail.blocks.CharBlock(required=False)), + ("texte", wagtail.blocks.CharBlock(required=True)), ] ), ), @@ -53,35 +53,35 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="cofdirectoryentrypage", name="links_en", - field=wagtail.core.fields.StreamField( + field=wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("url", wagtail.core.blocks.URLBlock(required=True)), - ("texte", wagtail.core.blocks.CharBlock()), + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock(required=True), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "info", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("nom", wagtail.core.blocks.CharBlock(required=False)), - ("texte", wagtail.core.blocks.CharBlock(required=True)), + ("nom", wagtail.blocks.CharBlock(required=False)), + ("texte", wagtail.blocks.CharBlock(required=True)), ] ), ), @@ -93,35 +93,35 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="cofdirectoryentrypage", name="links_fr", - field=wagtail.core.fields.StreamField( + field=wagtail.fields.StreamField( [ ( "lien", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("url", wagtail.core.blocks.URLBlock(required=True)), - ("texte", wagtail.core.blocks.CharBlock()), + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "contact", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ ( "email", - wagtail.core.blocks.EmailBlock(required=True), + wagtail.blocks.EmailBlock(required=True), ), - ("texte", wagtail.core.blocks.CharBlock()), + ("texte", wagtail.blocks.CharBlock()), ] ), ), ( "info", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( [ - ("nom", wagtail.core.blocks.CharBlock(required=False)), - ("texte", wagtail.core.blocks.CharBlock(required=True)), + ("nom", wagtail.blocks.CharBlock(required=False)), + ("texte", wagtail.blocks.CharBlock(required=True)), ] ), ), diff --git a/gestioncof/cms/migrations/0005_alter_cofdirectoryentrypage_links_and_more.py b/gestioncof/cms/migrations/0005_alter_cofdirectoryentrypage_links_and_more.py new file mode 100644 index 00000000..5b563942 --- /dev/null +++ b/gestioncof/cms/migrations/0005_alter_cofdirectoryentrypage_links_and_more.py @@ -0,0 +1,203 @@ +# Generated by Django 4.2.17 on 2024-12-19 12:27 + +import wagtail.blocks +import wagtail.fields +import wagtail.images.blocks +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("cofcms", "0004_auto_20200829_2314"), + ] + + operations = [ + migrations.AlterField( + model_name="cofdirectoryentrypage", + name="links", + field=wagtail.fields.StreamField( + [ + ( + "lien", + wagtail.blocks.StructBlock( + [ + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), + ] + ), + ), + ( + "contact", + wagtail.blocks.StructBlock( + [ + ("email", wagtail.blocks.EmailBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), + ] + ), + ), + ( + "info", + wagtail.blocks.StructBlock( + [ + ("nom", wagtail.blocks.CharBlock(required=False)), + ("texte", wagtail.blocks.CharBlock(required=True)), + ] + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="cofdirectoryentrypage", + name="links_en", + field=wagtail.fields.StreamField( + [ + ( + "lien", + wagtail.blocks.StructBlock( + [ + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), + ] + ), + ), + ( + "contact", + wagtail.blocks.StructBlock( + [ + ("email", wagtail.blocks.EmailBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), + ] + ), + ), + ( + "info", + wagtail.blocks.StructBlock( + [ + ("nom", wagtail.blocks.CharBlock(required=False)), + ("texte", wagtail.blocks.CharBlock(required=True)), + ] + ), + ), + ], + blank=True, + null=True, + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="cofdirectoryentrypage", + name="links_fr", + field=wagtail.fields.StreamField( + [ + ( + "lien", + wagtail.blocks.StructBlock( + [ + ("url", wagtail.blocks.URLBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), + ] + ), + ), + ( + "contact", + wagtail.blocks.StructBlock( + [ + ("email", wagtail.blocks.EmailBlock(required=True)), + ("texte", wagtail.blocks.CharBlock()), + ] + ), + ), + ( + "info", + wagtail.blocks.StructBlock( + [ + ("nom", wagtail.blocks.CharBlock(required=False)), + ("texte", wagtail.blocks.CharBlock(required=True)), + ] + ), + ), + ], + blank=True, + null=True, + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="cofpage", + name="body", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(form_classname="full title")), + ("paragraph", wagtail.blocks.RichTextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ("url", wagtail.blocks.URLBlock("Adresse de la page")), + ( + "height", + wagtail.blocks.CharBlock("Hauteur (en pixels)"), + ), + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="cofpage", + name="body_en", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(form_classname="full title")), + ("paragraph", wagtail.blocks.RichTextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ("url", wagtail.blocks.URLBlock("Adresse de la page")), + ( + "height", + wagtail.blocks.CharBlock("Hauteur (en pixels)"), + ), + ] + ), + ), + ], + null=True, + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="cofpage", + name="body_fr", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(form_classname="full title")), + ("paragraph", wagtail.blocks.RichTextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ("url", wagtail.blocks.URLBlock("Adresse de la page")), + ( + "height", + wagtail.blocks.CharBlock("Hauteur (en pixels)"), + ), + ] + ), + ), + ], + null=True, + use_json_field=True, + ), + ), + ] diff --git a/gestioncof/cms/models.py b/gestioncof/cms/models.py index 57881084..6e9e8715 100644 --- a/gestioncof/cms/models.py +++ b/gestioncof/cms/models.py @@ -1,12 +1,11 @@ from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db import models -from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel +from wagtail import blocks +from wagtail.admin.panels import FieldPanel from wagtail.contrib.routable_page.models import RoutablePageMixin, route -from wagtail.core import blocks -from wagtail.core.fields import RichTextField, StreamField -from wagtail.core.models import Page +from wagtail.fields import RichTextField, StreamField from wagtail.images.blocks import ImageChooserBlock -from wagtail.images.edit_handlers import ImageChooserPanel +from wagtail.models import Page # Page pouvant afficher des actualités @@ -69,10 +68,11 @@ class COFPage(Page): ("paragraph", blocks.RichTextBlock()), ("image", ImageChooserBlock()), ("iframe", IFrameBlock()), - ] + ], + use_json_field=True, ) - content_panels = Page.content_panels + [StreamFieldPanel("body")] + content_panels = Page.content_panels + [FieldPanel("body")] subpage_types = ["COFDirectoryPage", "COFPage"] parent_page_types = ["COFPage", "COFRootPage"] @@ -127,7 +127,7 @@ class COFActuPage(RoutablePageMixin, Page): all_day = models.BooleanField("Toute la journée", default=False, blank=True) content_panels = Page.content_panels + [ - ImageChooserPanel("image"), + FieldPanel("image"), FieldPanel("chapo"), FieldPanel("body", classname="full"), FieldPanel("is_event"), @@ -204,6 +204,7 @@ class COFDirectoryEntryPage(Page): ), ], blank=True, + use_json_field=True, ) image = models.ForeignKey( @@ -216,9 +217,9 @@ class COFDirectoryEntryPage(Page): ) content_panels = Page.content_panels + [ - ImageChooserPanel("image"), + FieldPanel("image"), FieldPanel("body", classname="full"), - StreamFieldPanel("links"), + FieldPanel("links"), ] subpage_types = [] diff --git a/gestioncof/migrations/0020_merge_20241218_2240.py b/gestioncof/migrations/0020_merge_20241218_2240.py new file mode 100644 index 00000000..af017d4c --- /dev/null +++ b/gestioncof/migrations/0020_merge_20241218_2240.py @@ -0,0 +1,13 @@ +# Generated by Django 3.2.25 on 2024-12-18 21:40 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("gestioncof", "0019_auto_20220630_1241"), + ("gestioncof", "0019_cofprofile_date_adhesion"), + ] + + operations = [] diff --git a/kfet/cms/hooks.py b/kfet/cms/hooks.py index 67261c74..df400e0f 100644 --- a/kfet/cms/hooks.py +++ b/kfet/cms/hooks.py @@ -1,6 +1,6 @@ from django.templatetags.static import static from django.utils.html import format_html -from wagtail.core import hooks +from wagtail import hooks @hooks.register("insert_editor_css") diff --git a/kfet/cms/management/commands/kfet_loadwagtail.py b/kfet/cms/management/commands/kfet_loadwagtail.py index 17ed842a..fd04e8e3 100644 --- a/kfet/cms/management/commands/kfet_loadwagtail.py +++ b/kfet/cms/management/commands/kfet_loadwagtail.py @@ -1,7 +1,7 @@ from django.contrib.auth.models import Group from django.core.management import call_command from django.core.management.base import BaseCommand -from wagtail.core.models import Page, Site +from wagtail.models import Page, Site class Command(BaseCommand): diff --git a/kfet/cms/migrations/0001_initial.py b/kfet/cms/migrations/0001_initial.py index af3a1f09..b19f0db5 100644 --- a/kfet/cms/migrations/0001_initial.py +++ b/kfet/cms/migrations/0001_initial.py @@ -2,8 +2,8 @@ from __future__ import unicode_literals import django.db.models.deletion -import wagtail.core.blocks -import wagtail.core.fields +import wagtail.blocks +import wagtail.fields import wagtail.snippets.blocks from django.db import migrations, models @@ -41,20 +41,20 @@ class Migration(migrations.Migration): ), ( "content", - wagtail.core.fields.StreamField( + wagtail.fields.StreamField( ( ( "rich", - wagtail.core.blocks.RichTextBlock(label="Éditeur"), + wagtail.blocks.RichTextBlock(label="Éditeur"), ), ("carte", kfet.cms.models.MenuBlock()), ( "group_team", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( ( ( "show_only", - wagtail.core.blocks.IntegerBlock( + wagtail.blocks.IntegerBlock( help_text="Nombre initial de membres affichés. Laisser vide pour tou-te-s les afficher.", # noqa required=False, label="Montrer seulement", @@ -62,7 +62,7 @@ class Migration(migrations.Migration): ), ( "members", - wagtail.core.blocks.ListBlock( + wagtail.blocks.ListBlock( wagtail.snippets.blocks.SnippetChooserBlock( # noqa kfet.cms.models.MemberTeam ), @@ -75,22 +75,22 @@ class Migration(migrations.Migration): ), ( "group", - wagtail.core.blocks.StreamBlock( + wagtail.blocks.StreamBlock( ( ( "rich", - wagtail.core.blocks.RichTextBlock( + wagtail.blocks.RichTextBlock( label="Éditeur" ), ), ("carte", kfet.cms.models.MenuBlock()), ( "group_team", - wagtail.core.blocks.StructBlock( + wagtail.blocks.StructBlock( ( ( "show_only", - wagtail.core.blocks.IntegerBlock( # noqa + wagtail.blocks.IntegerBlock( # noqa help_text="Nombre initial de membres affichés. Laisser vide pour tou-te-s les afficher.", # noqa required=False, label="Montrer seulement", @@ -98,7 +98,7 @@ class Migration(migrations.Migration): ), ( "members", - wagtail.core.blocks.ListBlock( + wagtail.blocks.ListBlock( wagtail.snippets.blocks.SnippetChooserBlock( # noqa kfet.cms.models.MemberTeam # noqa ), diff --git a/kfet/cms/migrations/0003_alter_kfetpage_content.py b/kfet/cms/migrations/0003_alter_kfetpage_content.py new file mode 100644 index 00000000..7e41eab4 --- /dev/null +++ b/kfet/cms/migrations/0003_alter_kfetpage_content.py @@ -0,0 +1,90 @@ +# Generated by Django 4.2.17 on 2024-12-19 12:27 + +import wagtail.blocks +import wagtail.fields +import wagtail.snippets.blocks +from django.db import migrations + +import kfet.cms.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("kfetcms", "0002_alter_kfetpage_colcount"), + ] + + operations = [ + migrations.AlterField( + model_name="kfetpage", + name="content", + field=wagtail.fields.StreamField( + [ + ("rich", wagtail.blocks.RichTextBlock(label="Éditeur")), + ("carte", kfet.cms.models.MenuBlock()), + ( + "group_team", + wagtail.blocks.StructBlock( + [ + ( + "show_only", + wagtail.blocks.IntegerBlock( + help_text="Nombre initial de membres affichés. Laisser vide pour tou-te-s les afficher.", + label="Montrer seulement", + required=False, + ), + ), + ( + "members", + wagtail.blocks.ListBlock( + wagtail.snippets.blocks.SnippetChooserBlock( + kfet.cms.models.MemberTeam + ), + form_classname="team-group", + label="K-Fêt-eux-ses", + ), + ), + ] + ), + ), + ( + "group", + wagtail.blocks.StreamBlock( + [ + ("rich", wagtail.blocks.RichTextBlock(label="Éditeur")), + ("carte", kfet.cms.models.MenuBlock()), + ( + "group_team", + wagtail.blocks.StructBlock( + [ + ( + "show_only", + wagtail.blocks.IntegerBlock( + help_text="Nombre initial de membres affichés. Laisser vide pour tou-te-s les afficher.", + label="Montrer seulement", + required=False, + ), + ), + ( + "members", + wagtail.blocks.ListBlock( + wagtail.snippets.blocks.SnippetChooserBlock( + kfet.cms.models.MemberTeam + ), + form_classname="team-group", + label="K-Fêt-eux-ses", + ), + ), + ] + ), + ), + ], + label="Contenu groupé", + ), + ), + ], + use_json_field=True, + verbose_name="Contenu", + ), + ), + ] diff --git a/kfet/cms/models.py b/kfet/cms/models.py index 8747c280..6ba36940 100644 --- a/kfet/cms/models.py +++ b/kfet/cms/models.py @@ -1,15 +1,9 @@ from django.db import models from django.utils.translation import gettext_lazy as _ -from wagtail.admin.edit_handlers import ( - FieldPanel, - FieldRowPanel, - MultiFieldPanel, - StreamFieldPanel, -) -from wagtail.core import blocks -from wagtail.core.fields import StreamField -from wagtail.core.models import Page -from wagtail.images.edit_handlers import ImageChooserPanel +from wagtail import blocks +from wagtail.admin.panels import FieldPanel, FieldRowPanel, MultiFieldPanel +from wagtail.fields import StreamField +from wagtail.models import Page from wagtail.snippets.blocks import SnippetChooserBlock from wagtail.snippets.models import register_snippet @@ -43,7 +37,7 @@ class MemberTeam(models.Model): FieldPanel("first_name"), FieldPanel("last_name"), FieldPanel("nick_name"), - ImageChooserPanel("photo"), + FieldPanel("photo"), ] def __str__(self): @@ -97,7 +91,9 @@ class KFetStreamBlock(ChoicesStreamBlock): class KFetPage(Page): - content = StreamField(KFetStreamBlock, verbose_name=_("Contenu")) + content = StreamField( + KFetStreamBlock, verbose_name=_("Contenu"), use_json_field=True + ) # Layout fields @@ -135,7 +131,7 @@ class KFetPage(Page): # Panels - content_panels = Page.content_panels + [StreamFieldPanel("content")] + content_panels = Page.content_panels + [FieldPanel("content")] layout_panel = [ FieldPanel("no_header"), diff --git a/kfet/migrations/0040_auto_20160829_2035.py b/kfet/migrations/0040_auto_20160829_2035.py index dc1aeeab..15f972f4 100644 --- a/kfet/migrations/0040_auto_20160829_2035.py +++ b/kfet/migrations/0040_auto_20160829_2035.py @@ -4,7 +4,6 @@ from __future__ import unicode_literals import datetime from django.db import migrations, models -from django.utils.timezone import utc class Migration(migrations.Migration): @@ -17,7 +16,9 @@ class Migration(migrations.Migration): name="at", field=models.DateTimeField( auto_now_add=True, - default=datetime.datetime(2016, 8, 29, 18, 35, 3, 419033, tzinfo=utc), + default=datetime.datetime( + 2016, 8, 29, 18, 35, 3, 419033, tzinfo=datetime.timezone.utc + ), ), preserve_default=False, ), diff --git a/kfet/models.py b/kfet/models.py index 003609a4..f30e093e 100644 --- a/kfet/models.py +++ b/kfet/models.py @@ -283,9 +283,13 @@ class Account(models.Model): context={ "account": self, "site": Site.objects.get_current(), - "url_read": reverse("kfet.account.read", args=(self.trigramme)), - "url_update": reverse("kfet.account.update", args=(self.trigramme)), - "url_delete": reverse("kfet.account.delete", args=(self.trigramme)) + "url_read": reverse("kfet.account.read", args=(self.trigramme,)), + "url_update": reverse( + "kfet.account.update", args=(self.trigramme,) + ), + "url_delete": reverse( + "kfet.account.delete", args=(self.trigramme,) + ), }, ), from_email=mail_data["FROM"], diff --git a/npins/default.nix b/npins/default.nix new file mode 100644 index 00000000..d256a275 --- /dev/null +++ b/npins/default.nix @@ -0,0 +1,81 @@ +# Generated by npins. Do not modify; will be overwritten regularly +let + data = builtins.fromJSON (builtins.readFile ./sources.json); + version = data.version; + + mkSource = + spec: + assert spec ? type; + let + path = + if spec.type == "Git" then + mkGitSource spec + else if spec.type == "GitRelease" then + mkGitSource spec + else if spec.type == "PyPi" then + mkPyPiSource spec + else if spec.type == "Channel" then + mkChannelSource spec + else + builtins.throw "Unknown source type ${spec.type}"; + in + spec // { outPath = path; }; + + mkGitSource = + { + repository, + revision, + url ? null, + hash, + branch ? null, + ... + }: + assert repository ? type; + # At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository + # In the latter case, there we will always be an url to the tarball + if url != null then + (builtins.fetchTarball { + inherit url; + sha256 = hash; # FIXME: check nix version & use SRI hashes + }) + else + assert repository.type == "Git"; + let + urlToName = + url: rev: + let + matched = builtins.match "^.*/([^/]*)(\\.git)?$" repository.url; + + short = builtins.substring 0 7 rev; + + appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else ""; + in + "${if matched == null then "source" else builtins.head matched}${appendShort}"; + name = urlToName repository.url revision; + in + builtins.fetchGit { + url = repository.url; + rev = revision; + inherit name; + allRefs = true; + # hash = hash; + }; + + mkPyPiSource = + { url, hash, ... }: + builtins.fetchurl { + inherit url; + sha256 = hash; + }; + + mkChannelSource = + { url, hash, ... }: + builtins.fetchTarball { + inherit url; + sha256 = hash; + }; +in +if version == 3 then + builtins.mapAttrs (_: mkSource) data.pins +else + throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`" diff --git a/npins/sources.json b/npins/sources.json new file mode 100644 index 00000000..9ed77931 --- /dev/null +++ b/npins/sources.json @@ -0,0 +1,33 @@ +{ + "pins": { + "kat-pkgs": { + "type": "Git", + "repository": { + "type": "Git", + "url": "https://git.dgnum.eu/lbailly/kat-pkgs.git" + }, + "branch": "master", + "revision": "6b600b716f409c6012b424de006eac3b02148b81", + "url": null, + "hash": "0204f91vxa5qglihpfkf3j5w3k7v98wry861xf2skl024faf9idf" + }, + "nix-pkgs": { + "type": "Git", + "repository": { + "type": "Git", + "url": "https://git.hubrecht.ovh/hubrecht/nix-pkgs" + }, + "branch": "main", + "revision": "ac4ff5a34789ae3398aff9501735b67b6a5a285a", + "url": null, + "hash": "16n37f74p6h30hhid98vab9w5b08xqj4qcshz2kc1jh67z5n49p6" + }, + "nixpkgs": { + "type": "Channel", + "name": "nixos-unstable", + "url": "https://releases.nixos.org/nixos/unstable/nixos-25.05beta719504.a73246e2eef4/nixexprs.tar.xz", + "hash": "1jjmg13jzbqxm5m5ql51n2kq1qggfyb0rhmjwhqhvqxhl350z58a" + } + }, + "version": 3 +} \ No newline at end of file diff --git a/requirements-devel.txt b/requirements-devel.txt index d6b5c0a4..2de02a5d 100644 --- a/requirements-devel.txt +++ b/requirements-devel.txt @@ -1,5 +1,5 @@ -r requirements.txt -django-debug-toolbar==3.2.* +django-debug-toolbar==4.4.6 ipython # Tools diff --git a/requirements-prod.txt b/requirements-prod.txt index b4a99d6b..45ac4920 100644 --- a/requirements-prod.txt +++ b/requirements-prod.txt @@ -1,15 +1,15 @@ -r requirements.txt # Postgresql bindings -psycopg2==2.9.* +psycopg2==2.9.10 # Redis -django-redis-cache==3.0.* -redis==3.5.* -channels-redis==3.4.* +django-redis-cache==3.0.1 +redis==3.5.3 +channels-redis==3.4.1 # ASGI protocol and HTTP server -daphne==3.0.* +daphne==3.0.2 # ldap bindings python-ldap diff --git a/requirements.txt b/requirements.txt index 2016b576..65d1d380 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,19 @@ -Django==3.2.* -Pillow==7.2.0 -authens==0.1b4 -channels==3.0.* -configparser==3.5.0 -django-autocomplete-light==3.9.4 -django-bootstrap-form==3.3 -django-cas-ng==4.3.* -django-cors-headers==3.13.0 -django-djconfig==0.10.0 +Django==4.2.17 +Pillow==11.0.0 +authens==0.2.0 +channels==3.0.5 +configparser==7.1.0 +django-autocomplete-light==3.11.0 +django-bootstrap-form==3.4 +django-cas-ng==5.0.1 +django-cors-headers==4.6.0 +django-djconfig==0.11.0 django-hCaptcha==0.2.0 -django-js-reverse==0.9.1 -django-widget-tweaks==1.4.1 -icalendar==4.0.7 -python-dateutil==2.8.1 +django-js-reverse==0.10.2 +django-widget-tweaks==1.5.0 +icalendar==6.1.0 +python-dateutil==2.9.0.post0 statistics==1.0.3.5 -wagtail-modeltranslation==0.11.* -wagtail==2.13.* -wagtailmenus==3.0.* +wagtail-modeltranslation==0.15.1 +wagtail==6.3.1 +wagtailmenus==4.0.1 diff --git a/shell.nix b/shell.nix index 69411b79..16185568 100644 --- a/shell.nix +++ b/shell.nix @@ -1,30 +1,81 @@ { - pkgs ? import { }, - ... + sources ? import ./npins, + pkgs ? import sources.nixpkgs { }, }: let - python = pkgs.python39; -in + nix-pkgs = import sources.nix-pkgs { inherit pkgs; }; + kat-pkgs = import sources.kat-pkgs { inherit pkgs; }; + python3 = pkgs.python3.override { + packageOverrides = final: prev: { + inherit (nix-pkgs) + authens + django-bootstrap-form + django-cas-ng + loadcredential + ; + + inherit (kat-pkgs.python3Packages) + django-djconfig + django-hCaptcha + wagtail-modeltranslation + wagtailmenus + ; + }; + }; +in pkgs.mkShell { shellHook = '' - export DJANGO_SETTINGS_MODULE=gestioasso.settings.local - - virtualenv .venv - source .venv/bin/activate - - pip install -r requirements-devel.txt | grep -v 'Requirement already satisfied:' + if [ ! -d .static ]; then + mkdir .static + fi ''; - packages = - [ python ] - ++ (with python.pkgs; [ - django-types - pip - virtualenv - python-ldap - ]); + env = { + CREDENTIALS_DIRECTORY = builtins.toString ./.credentials; + DJANGO_SETTINGS_MODULE = "gestioasso.settings.local"; + + GESTIOCOF_DEBUG = true; + GESTIOCOF_STATIC_ROOT = builtins.toString ./.static; + + GESTIOBDS_DEBUG = true; + GESTIOBDS_STATIC_ROOT = builtins.toString ./.static; + }; + + packages = [ + (python3.withPackages ( + ps: with ps; [ + django + pillow + authens + channels + configparser + django-autocomplete-light + django-bootstrap-form + django-cas-ng + django-cors-headers + django-djconfig + django-hCaptcha + django-js-reverse + django-widget-tweaks + icalendar + loadcredential + python-dateutil + statistics + wagtail-modeltranslation + wagtail + wagtailmenus + + django-debug-toolbar + ipython + black + flake8 + isort + ] + )) + pkgs.npins + ]; allowSubstitutes = false; }