From 86b6d77bf1262024a2a83a8fa5b28eaba0d833c5 Mon Sep 17 00:00:00 2001 From: Jonas Braathen Date: Tue, 7 May 2024 01:41:37 +0200 Subject: [PATCH] add skeleton for dnscms --- dnscms/.dockerignore | 39 + dnscms/.gitignore | 8 + dnscms/.tool-versions | 1 + dnscms/Dockerfile | 60 ++ dnscms/README.md | 0 dnscms/associations/__init__.py | 0 dnscms/associations/apps.py | 6 + .../associations/migrations/0001_initial.py | 34 + dnscms/associations/migrations/__init__.py | 0 dnscms/associations/models.py | 42 + dnscms/associations/tests.py | 3 + dnscms/associations/views.py | 3 + dnscms/db.sqlite3 | Bin 0 -> 991232 bytes dnscms/dnscms/__init__.py | 0 dnscms/dnscms/settings/__init__.py | 0 dnscms/dnscms/settings/base.py | 177 ++++ dnscms/dnscms/settings/dev.py | 18 + dnscms/dnscms/settings/production.py | 8 + dnscms/dnscms/static/css/dnscms.css | 0 dnscms/dnscms/static/js/dnscms.js | 0 dnscms/dnscms/templates/404.html | 11 + dnscms/dnscms/templates/500.html | 13 + dnscms/dnscms/templates/base.html | 46 + dnscms/dnscms/urls.py | 33 + dnscms/dnscms/wsgi.py | 16 + dnscms/events/__init__.py | 0 dnscms/events/apps.py | 6 + dnscms/events/migrations/0001_initial.py | 30 + dnscms/events/migrations/0002_eventindex.py | 25 + ..._rename_event_eventpage_eventoccurrence.py | 26 + dnscms/events/migrations/__init__.py | 0 dnscms/events/models.py | 170 ++++ dnscms/events/tests.py | 3 + dnscms/events/views.py | 3 + dnscms/home/__init__.py | 0 dnscms/home/migrations/0001_initial.py | 31 + .../home/migrations/0002_create_homepage.py | 61 ++ dnscms/home/migrations/0003_event.py | 28 + dnscms/home/migrations/0004_association.py | 30 + .../home/migrations/0005_association_logo.py | 20 + ...nt_page_ptr_delete_association_and_more.py | 23 + dnscms/home/migrations/__init__.py | 0 dnscms/home/models.py | 15 + dnscms/home/static/css/welcome_page.css | 184 ++++ dnscms/home/templates/home/home_page.html | 21 + dnscms/home/templates/home/welcome_page.html | 52 ++ dnscms/manage.py | 10 + dnscms/poetry.lock | 875 ++++++++++++++++++ dnscms/pyproject.toml | 27 + 49 files changed, 2158 insertions(+) create mode 100644 dnscms/.dockerignore create mode 100644 dnscms/.gitignore create mode 100644 dnscms/.tool-versions create mode 100644 dnscms/Dockerfile create mode 100644 dnscms/README.md create mode 100644 dnscms/associations/__init__.py create mode 100644 dnscms/associations/apps.py create mode 100644 dnscms/associations/migrations/0001_initial.py create mode 100644 dnscms/associations/migrations/__init__.py create mode 100644 dnscms/associations/models.py create mode 100644 dnscms/associations/tests.py create mode 100644 dnscms/associations/views.py create mode 100644 dnscms/db.sqlite3 create mode 100644 dnscms/dnscms/__init__.py create mode 100644 dnscms/dnscms/settings/__init__.py create mode 100644 dnscms/dnscms/settings/base.py create mode 100644 dnscms/dnscms/settings/dev.py create mode 100644 dnscms/dnscms/settings/production.py create mode 100644 dnscms/dnscms/static/css/dnscms.css create mode 100644 dnscms/dnscms/static/js/dnscms.js create mode 100644 dnscms/dnscms/templates/404.html create mode 100644 dnscms/dnscms/templates/500.html create mode 100644 dnscms/dnscms/templates/base.html create mode 100644 dnscms/dnscms/urls.py create mode 100644 dnscms/dnscms/wsgi.py create mode 100644 dnscms/events/__init__.py create mode 100644 dnscms/events/apps.py create mode 100644 dnscms/events/migrations/0001_initial.py create mode 100644 dnscms/events/migrations/0002_eventindex.py create mode 100644 dnscms/events/migrations/0003_rename_event_eventpage_eventoccurrence.py create mode 100644 dnscms/events/migrations/__init__.py create mode 100644 dnscms/events/models.py create mode 100644 dnscms/events/tests.py create mode 100644 dnscms/events/views.py create mode 100644 dnscms/home/__init__.py create mode 100644 dnscms/home/migrations/0001_initial.py create mode 100644 dnscms/home/migrations/0002_create_homepage.py create mode 100644 dnscms/home/migrations/0003_event.py create mode 100644 dnscms/home/migrations/0004_association.py create mode 100644 dnscms/home/migrations/0005_association_logo.py create mode 100644 dnscms/home/migrations/0006_remove_event_page_ptr_delete_association_and_more.py create mode 100644 dnscms/home/migrations/__init__.py create mode 100644 dnscms/home/models.py create mode 100644 dnscms/home/static/css/welcome_page.css create mode 100644 dnscms/home/templates/home/home_page.html create mode 100644 dnscms/home/templates/home/welcome_page.html create mode 100755 dnscms/manage.py create mode 100644 dnscms/poetry.lock create mode 100644 dnscms/pyproject.toml diff --git a/dnscms/.dockerignore b/dnscms/.dockerignore new file mode 100644 index 0000000..63ce98d --- /dev/null +++ b/dnscms/.dockerignore @@ -0,0 +1,39 @@ +# Django project +/media/ +/static/ +*.sqlite3 + +# Python and others +__pycache__ +*.pyc +.DS_Store +*.swp +/venv/ +/tmp/ +/.vagrant/ +/Vagrantfile.local +node_modules/ +/npm-debug.log +/.idea/ +.vscode +coverage +.python-version + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg diff --git a/dnscms/.gitignore b/dnscms/.gitignore new file mode 100644 index 0000000..43c8170 --- /dev/null +++ b/dnscms/.gitignore @@ -0,0 +1,8 @@ +*.pyc +.DS_Store +*.swp +.vscode/ +/venv/ +/.venv/ +/static/ +/media/ diff --git a/dnscms/.tool-versions b/dnscms/.tool-versions new file mode 100644 index 0000000..1d7a709 --- /dev/null +++ b/dnscms/.tool-versions @@ -0,0 +1 @@ +python 3.12.3 diff --git a/dnscms/Dockerfile b/dnscms/Dockerfile new file mode 100644 index 0000000..0127b83 --- /dev/null +++ b/dnscms/Dockerfile @@ -0,0 +1,60 @@ +# Use an official Python runtime based on Debian 10 "buster" as a parent image. +FROM python:3.8.1-slim-buster + +# Add user that will be used in the container. +RUN useradd wagtail + +# Port used by this container to serve HTTP. +EXPOSE 8000 + +# Set environment variables. +# 1. Force Python stdout and stderr streams to be unbuffered. +# 2. Set PORT variable that is used by Gunicorn. This should match "EXPOSE" +# command. +ENV PYTHONUNBUFFERED=1 \ + PORT=8000 + +# Install system packages required by Wagtail and Django. +RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-recommends \ + build-essential \ + libpq-dev \ + libmariadbclient-dev \ + libjpeg62-turbo-dev \ + zlib1g-dev \ + libwebp-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install the application server. +RUN pip install "gunicorn==20.0.4" + +# Install the project requirements. +COPY requirements.txt / +RUN pip install -r /requirements.txt + +# Use /app folder as a directory where the source code is stored. +WORKDIR /app + +# Set this directory to be owned by the "wagtail" user. This Wagtail project +# uses SQLite, the folder needs to be owned by the user that +# will be writing to the database file. +RUN chown wagtail:wagtail /app + +# Copy the source code of the project into the container. +COPY --chown=wagtail:wagtail . . + +# Use user "wagtail" to run the build commands below and the server itself. +USER wagtail + +# Collect static files. +RUN python manage.py collectstatic --noinput --clear + +# Runtime command that executes when "docker run" is called, it does the +# following: +# 1. Migrate the database. +# 2. Start the application server. +# WARNING: +# Migrating database at the same time as starting the server IS NOT THE BEST +# PRACTICE. The database should be migrated manually or using the release +# phase facilities of your hosting platform. This is used only so the +# Wagtail instance can be started with a simple "docker run" command. +CMD set -xe; python manage.py migrate --noinput; gunicorn dnscms.wsgi:application diff --git a/dnscms/README.md b/dnscms/README.md new file mode 100644 index 0000000..e69de29 diff --git a/dnscms/associations/__init__.py b/dnscms/associations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dnscms/associations/apps.py b/dnscms/associations/apps.py new file mode 100644 index 0000000..c9ac1ea --- /dev/null +++ b/dnscms/associations/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AssociationsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'associations' diff --git a/dnscms/associations/migrations/0001_initial.py b/dnscms/associations/migrations/0001_initial.py new file mode 100644 index 0000000..ec4a6b2 --- /dev/null +++ b/dnscms/associations/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# Generated by Django 5.0.4 on 2024-05-04 03:35 + +import django.db.models.deletion +import wagtail.blocks +import wagtail.fields +import wagtail.images.blocks +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('wagtailcore', '0093_uploadedfile'), + ('wagtailimages', '0026_delete_uploadedimage'), + ] + + operations = [ + migrations.CreateModel( + name='Association', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('body', wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(form_classname='title')), ('paragraph', wagtail.blocks.RichTextBlock()), ('image', wagtail.images.blocks.ImageChooserBlock())])), + ('association_type', models.CharField(choices=[('forening', 'Forening'), ('utvalg', 'Utvalg')], default='forening', max_length=64)), + ('url', models.URLField()), + ('logo', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image')), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + ] diff --git a/dnscms/associations/migrations/__init__.py b/dnscms/associations/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dnscms/associations/models.py b/dnscms/associations/models.py new file mode 100644 index 0000000..6e3a364 --- /dev/null +++ b/dnscms/associations/models.py @@ -0,0 +1,42 @@ +from django.db import models + + +from wagtail.models import Page +from wagtail.fields import StreamField +from wagtail import blocks +from wagtail.admin.panels import FieldPanel +from wagtail.images.blocks import ImageChooserBlock + + +class Association(Page): + class AssociationType(models.TextChoices): + FORENING = "forening", "Forening" + UTVALG = "utvalg", "Utvalg" + + body = StreamField( + [ + ("heading", blocks.CharBlock(form_classname="title")), + ("paragraph", blocks.RichTextBlock()), + ("image", ImageChooserBlock()), + ] + ) + association_type = models.CharField( + max_length=64, choices=AssociationType, default=AssociationType.FORENING + ) + logo = models.ForeignKey( + "wagtailimages.Image", + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="+", + ) + url = models.URLField() + + content_panels = Page.content_panels + [ + # FieldPanel('author'), + # FieldPanel('date'), + FieldPanel("body"), + FieldPanel("logo"), + FieldPanel("association_type"), + FieldPanel("url"), + ] diff --git a/dnscms/associations/tests.py b/dnscms/associations/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/dnscms/associations/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/dnscms/associations/views.py b/dnscms/associations/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/dnscms/associations/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/dnscms/db.sqlite3 b/dnscms/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..560bfd494a18f08f63964731e382d46ba5955b91 GIT binary patch literal 991232 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 not found + +

Sorry, this page could not be found.

+{% endblock %} diff --git a/dnscms/dnscms/templates/500.html b/dnscms/dnscms/templates/500.html new file mode 100644 index 0000000..77379e5 --- /dev/null +++ b/dnscms/dnscms/templates/500.html @@ -0,0 +1,13 @@ + + + + + Internal server error + + + +

Internal server error

+ +

Sorry, there seems to be an error. Please try again soon.

+ + diff --git a/dnscms/dnscms/templates/base.html b/dnscms/dnscms/templates/base.html new file mode 100644 index 0000000..c33dbb2 --- /dev/null +++ b/dnscms/dnscms/templates/base.html @@ -0,0 +1,46 @@ +{% load static wagtailcore_tags wagtailuserbar %} + + + + + + + {% block title %} + {% if page.seo_title %}{{ page.seo_title }}{% else %}{{ page.title }}{% endif %} + {% endblock %} + {% block title_suffix %} + {% wagtail_site as current_site %} + {% if current_site and current_site.site_name %}- {{ current_site.site_name }}{% endif %} + {% endblock %} + + {% if page.search_description %} + + {% endif %} + + + {# Force all links in the live preview panel to be opened in a new tab #} + {% if request.in_preview_panel %} + + {% endif %} + + {# Global stylesheets #} + + + {% block extra_css %} + {# Override this in templates to add extra stylesheets #} + {% endblock %} + + + + {% wagtailuserbar %} + + {% block content %}{% endblock %} + + {# Global javascript #} + + + {% block extra_js %} + {# Override this in templates to add extra javascript #} + {% endblock %} + + diff --git a/dnscms/dnscms/urls.py b/dnscms/dnscms/urls.py new file mode 100644 index 0000000..85c3cc6 --- /dev/null +++ b/dnscms/dnscms/urls.py @@ -0,0 +1,33 @@ +from django.conf import settings +from django.contrib import admin +from django.urls import include, path +from grapple import urls as grapple_urls +from wagtail import urls as wagtail_urls +from wagtail.admin import urls as wagtailadmin_urls +from wagtail.documents import urls as wagtaildocs_urls + +urlpatterns = [ + path("api/", include(grapple_urls)), + path("django-admin/", admin.site.urls), + path("admin/", include(wagtailadmin_urls)), + path("documents/", include(wagtaildocs_urls)), +] + + +if settings.DEBUG: + from django.conf.urls.static import static + from django.contrib.staticfiles.urls import staticfiles_urlpatterns + + # Serve static and media files from development server + urlpatterns += staticfiles_urlpatterns() + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + +urlpatterns = urlpatterns + [ + # For anything not caught by a more specific rule above, hand over to + # Wagtail's page serving mechanism. This should be the last pattern in + # the list: + path("", include(wagtail_urls)), + # Alternatively, if you want Wagtail pages to be served from a subpath + # of your site, rather than the site root: + # path("pages/", include(wagtail_urls)), +] diff --git a/dnscms/dnscms/wsgi.py b/dnscms/dnscms/wsgi.py new file mode 100644 index 0000000..187aaf2 --- /dev/null +++ b/dnscms/dnscms/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for dnscms project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dnscms.settings.dev") + +application = get_wsgi_application() diff --git a/dnscms/events/__init__.py b/dnscms/events/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dnscms/events/apps.py b/dnscms/events/apps.py new file mode 100644 index 0000000..20f48f2 --- /dev/null +++ b/dnscms/events/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class EventsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'events' diff --git a/dnscms/events/migrations/0001_initial.py b/dnscms/events/migrations/0001_initial.py new file mode 100644 index 0000000..6a018fe --- /dev/null +++ b/dnscms/events/migrations/0001_initial.py @@ -0,0 +1,30 @@ +# Generated by Django 5.0.4 on 2024-05-04 03:35 + +import django.db.models.deletion +import wagtail.blocks +import wagtail.fields +import wagtail.images.blocks +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('wagtailcore', '0093_uploadedfile'), + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('body', wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(form_classname='title')), ('paragraph', wagtail.blocks.RichTextBlock()), ('image', wagtail.images.blocks.ImageChooserBlock())])), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + ] diff --git a/dnscms/events/migrations/0002_eventindex.py b/dnscms/events/migrations/0002_eventindex.py new file mode 100644 index 0000000..a71777b --- /dev/null +++ b/dnscms/events/migrations/0002_eventindex.py @@ -0,0 +1,25 @@ +# Generated by Django 5.0.4 on 2024-05-06 21:38 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0001_initial'), + ('wagtailcore', '0093_uploadedfile'), + ] + + operations = [ + migrations.CreateModel( + name='EventIndex', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + ] diff --git a/dnscms/events/migrations/0003_rename_event_eventpage_eventoccurrence.py b/dnscms/events/migrations/0003_rename_event_eventpage_eventoccurrence.py new file mode 100644 index 0000000..b050ace --- /dev/null +++ b/dnscms/events/migrations/0003_rename_event_eventpage_eventoccurrence.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.4 on 2024-05-06 22:07 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0002_eventindex'), + ('wagtailcore', '0093_uploadedfile'), + ] + + operations = [ + migrations.RenameModel( + old_name='Event', + new_name='EventPage', + ), + migrations.CreateModel( + name='EventOccurrence', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='occurrences', to='events.eventpage')), + ], + ), + ] diff --git a/dnscms/events/migrations/__init__.py b/dnscms/events/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dnscms/events/models.py b/dnscms/events/models.py new file mode 100644 index 0000000..c8e274a --- /dev/null +++ b/dnscms/events/models.py @@ -0,0 +1,170 @@ +from django.db import models +from grapple.models import GraphQLStreamfield, GraphQLString +from wagtail import blocks +from wagtail.admin.panels import FieldPanel +from wagtail.fields import StreamField +from wagtail.images.blocks import ImageChooserBlock +from wagtail.models import Page + + +class EventIndex(Page): + # there can only be one event index page + max_count = 1 + + graphql_fields = [] + + +class EventPage(Page): + # no children + subpage_types = [] + + # author = models.CharField(max_length=255) + # date = models.DateField("Post date") + body = StreamField( + [ + ("heading", blocks.CharBlock(form_classname="title")), + ("paragraph", blocks.RichTextBlock()), + ("image", ImageChooserBlock()), + ] + ) + + content_panels = Page.content_panels + [ + # FieldPanel('author'), + # FieldPanel('date'), + FieldPanel("body"), + ] + + graphql_fields = [ + GraphQLString("heading"), + # GraphQLString("date"), + # GraphQLString("author"), + GraphQLStreamfield("body"), + ] + + +class EventOccurrence(models.Model): + event = models.ForeignKey(EventPage, on_delete=models.CASCADE, related_name="occurrences") + + +sample_legacy_event_json = """ +{ + "id": 64573, + "date": "2023-12-27T11:28:34", + "date_gmt": "2023-12-27T10:28:34", + "guid": { + "rendered": "https://studentersamfundet.no/?post_type=event&p=64573" + }, + "modified": "2023-12-27T11:44:11", + "modified_gmt": "2023-12-27T10:44:11", + "slug": "quiz-147-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-2-2-2-2", + "status": "publish", + "type": "event", + "link": "https://studentersamfundet.no/arrangement/quiz-147-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-2-2-2-2/", + "title": { + "rendered": "QUIZ", + "decoded": "QUIZ" + }, + "content": { + "rendered": "\n

Det Norske Studentersamfund inviterer til quiz hver tirsdag kl. 19:00.

\n\n\n\n

Vi serverer 50 spørsmål som kan spenne seg fra one hit wonders fra 80-tallet, universets uendelighet, dyrelivets merkverdigheter og mye, mye mer!

\n\n\n\n

Quiz pÃ¥ Chateau Neuf er Ã¥pent for alle. Vinnere og “lucky losers” vil bli utnevnt hver kveld. Lag som er over seks personer er tillatt, men da trekkes dere for ett poeng per deltaker per runde.

\n\n\n\n

For de som ønsker å være med på sammenlagtkonkurransen for høsten vil den regnes ut for de tolv beste prestasjonene laget leverer. Så det vil fremdeles være god sjanse for å vinne sammenlagt selv dere må droppe en quiz eller to for eksamener eller andre forpliktelser.

\n\n\n\n

Velkommen quizglade mennesker!

\n\n\n\n

Gratis inngang!

\n", + "protected": false + }, + "excerpt": { + "rendered": "

Det Norske Studentersamfund inviterer til quiz hver tirsdag kl. 19:00. Vi serverer 50 spørsmÃ¥l som kan spenne seg fra one hit wonders fra 80-tallet, universets uendelighet, dyrelivets merkverdigheter og mye, mye mer! Quiz pÃ¥ Chateau Neuf er Ã¥pent for alle. Vinnere og “lucky losers” vil bli utnevnt hver kveld. Lag som er over seks personer […]

\n", + "protected": false + }, + "author": 2150, + "featured_media": 64585, + "template": "", + "meta": [], + "event_types": [13], + "event_organizers": [390, 322], + "facebook_url": "https://fb.me/e/2RDR5pZdr", + "ticket_url": "", + "price_regular": "", + "price_member": "", + "start_time": "2024-05-07T17:00:00+00:00", + "end_time": "2024-05-07T20:00:00+00:00", + "venue": "Glassbaren", + "venue_id": "55063", + "thumbnail": { + "thumbnail": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-150x150.png", + "medium": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-300x169.png", + "medium_large": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-768x433.png", + "large": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-1280x720.png", + "1536x1536": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-1536x865.png", + "2048x2048": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1.png", + "four-column": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-393x342.png", + "six-column": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-608x342.png", + "extra-large": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-1600x901.png", + "newsletter-half": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-320x190.png", + "newsletter-third": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-213x126.png", + "featured": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-1200x480.png" + }, + "_links": { + "self": [ + { + "href": "https://studentersamfundet.no/wp-json/wp/v2/events/64573" + } + ], + "collection": [ + { + "href": "https://studentersamfundet.no/wp-json/wp/v2/events" + } + ], + "about": [ + { + "href": "https://studentersamfundet.no/wp-json/wp/v2/types/event" + } + ], + "author": [ + { + "embeddable": true, + "href": "https://studentersamfundet.no/wp-json/wp/v2/users/2150" + } + ], + "version-history": [ + { + "count": 1, + "href": "https://studentersamfundet.no/wp-json/wp/v2/events/64573/revisions" + } + ], + "predecessor-version": [ + { + "id": 64574, + "href": "https://studentersamfundet.no/wp-json/wp/v2/events/64573/revisions/64574" + } + ], + "wp:featuredmedia": [ + { + "embeddable": true, + "href": "https://studentersamfundet.no/wp-json/wp/v2/media/64585" + } + ], + "wp:attachment": [ + { + "href": "https://studentersamfundet.no/wp-json/wp/v2/media?parent=64573" + } + ], + "wp:term": [ + { + "taxonomy": "event_type", + "embeddable": true, + "href": "https://studentersamfundet.no/wp-json/wp/v2/event_types?post=64573" + }, + { + "taxonomy": "event_organizer", + "embeddable": true, + "href": "https://studentersamfundet.no/wp-json/wp/v2/event_organizers?post=64573" + } + ], + "curies": [ + { + "name": "wp", + "href": "https://api.w.org/{rel}", + "templated": true + } + ] + } +} + +""" diff --git a/dnscms/events/tests.py b/dnscms/events/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/dnscms/events/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/dnscms/events/views.py b/dnscms/events/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/dnscms/events/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/dnscms/home/__init__.py b/dnscms/home/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dnscms/home/migrations/0001_initial.py b/dnscms/home/migrations/0001_initial.py new file mode 100644 index 0000000..67f201d --- /dev/null +++ b/dnscms/home/migrations/0001_initial.py @@ -0,0 +1,31 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("wagtailcore", "0040_page_draft_title"), + ] + + operations = [ + migrations.CreateModel( + name="HomePage", + fields=[ + ( + "page_ptr", + models.OneToOneField( + on_delete=models.CASCADE, + parent_link=True, + auto_created=True, + primary_key=True, + serialize=False, + to="wagtailcore.Page", + ), + ), + ], + options={ + "abstract": False, + }, + bases=("wagtailcore.page",), + ), + ] diff --git a/dnscms/home/migrations/0002_create_homepage.py b/dnscms/home/migrations/0002_create_homepage.py new file mode 100644 index 0000000..e84576f --- /dev/null +++ b/dnscms/home/migrations/0002_create_homepage.py @@ -0,0 +1,61 @@ +from django.db import migrations + + +def create_homepage(apps, schema_editor): + # Get models + ContentType = apps.get_model("contenttypes.ContentType") + Page = apps.get_model("wagtailcore.Page") + Site = apps.get_model("wagtailcore.Site") + HomePage = apps.get_model("home.HomePage") + + # Delete the default homepage + # If migration is run multiple times, it may have already been deleted + Page.objects.filter(id=2).delete() + + # Create content type for homepage model + homepage_content_type, __ = ContentType.objects.get_or_create( + model="homepage", app_label="home" + ) + + # Create a new homepage + homepage = HomePage.objects.create( + title="Home", + draft_title="Home", + slug="home", + content_type=homepage_content_type, + path="00010001", + depth=2, + numchild=0, + url_path="/home/", + ) + + # Create a site with the new homepage set as the root + Site.objects.create(hostname="localhost", root_page=homepage, is_default_site=True) + + +def remove_homepage(apps, schema_editor): + # Get models + ContentType = apps.get_model("contenttypes.ContentType") + HomePage = apps.get_model("home.HomePage") + + # Delete the default homepage + # Page and Site objects CASCADE + HomePage.objects.filter(slug="home", depth=2).delete() + + # Delete content type for homepage model + ContentType.objects.filter(model="homepage", app_label="home").delete() + + +class Migration(migrations.Migration): + + run_before = [ + ("wagtailcore", "0053_locale_model"), + ] + + dependencies = [ + ("home", "0001_initial"), + ] + + operations = [ + migrations.RunPython(create_homepage, remove_homepage), + ] diff --git a/dnscms/home/migrations/0003_event.py b/dnscms/home/migrations/0003_event.py new file mode 100644 index 0000000..cc5c8a2 --- /dev/null +++ b/dnscms/home/migrations/0003_event.py @@ -0,0 +1,28 @@ +# Generated by Django 5.0.3 on 2024-03-31 23:38 + +import django.db.models.deletion +import wagtail.blocks +import wagtail.fields +import wagtail.images.blocks +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0002_create_homepage'), + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('body', wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(form_classname='title')), ('paragraph', wagtail.blocks.RichTextBlock()), ('image', wagtail.images.blocks.ImageChooserBlock())])), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + ] diff --git a/dnscms/home/migrations/0004_association.py b/dnscms/home/migrations/0004_association.py new file mode 100644 index 0000000..a1ec1c1 --- /dev/null +++ b/dnscms/home/migrations/0004_association.py @@ -0,0 +1,30 @@ +# Generated by Django 5.0.3 on 2024-04-02 23:32 + +import django.db.models.deletion +import wagtail.blocks +import wagtail.fields +import wagtail.images.blocks +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0003_event'), + ] + + operations = [ + migrations.CreateModel( + name='Association', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('body', wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(form_classname='title')), ('paragraph', wagtail.blocks.RichTextBlock()), ('image', wagtail.images.blocks.ImageChooserBlock())])), + ('association_type', models.CharField(choices=[('forening', 'Forening'), ('utvalg', 'Utvalg')], default='forening', max_length=64)), + ('url', models.URLField()), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + ] diff --git a/dnscms/home/migrations/0005_association_logo.py b/dnscms/home/migrations/0005_association_logo.py new file mode 100644 index 0000000..c1c11e9 --- /dev/null +++ b/dnscms/home/migrations/0005_association_logo.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.3 on 2024-04-02 23:43 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0004_association'), + ('wagtailimages', '0025_alter_image_file_alter_rendition_file'), + ] + + operations = [ + migrations.AddField( + model_name='association', + name='logo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image'), + ), + ] diff --git a/dnscms/home/migrations/0006_remove_event_page_ptr_delete_association_and_more.py b/dnscms/home/migrations/0006_remove_event_page_ptr_delete_association_and_more.py new file mode 100644 index 0000000..281755c --- /dev/null +++ b/dnscms/home/migrations/0006_remove_event_page_ptr_delete_association_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.4 on 2024-05-04 03:35 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0005_association_logo'), + ] + + operations = [ + migrations.RemoveField( + model_name='event', + name='page_ptr', + ), + migrations.DeleteModel( + name='Association', + ), + migrations.DeleteModel( + name='Event', + ), + ] diff --git a/dnscms/home/migrations/__init__.py b/dnscms/home/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dnscms/home/models.py b/dnscms/home/models.py new file mode 100644 index 0000000..7f24335 --- /dev/null +++ b/dnscms/home/models.py @@ -0,0 +1,15 @@ +from django.db import models + +from wagtail.models import Page +from wagtail.fields import StreamField +from wagtail import blocks +from wagtail.admin.panels import FieldPanel +from wagtail.images.blocks import ImageChooserBlock + + +# https://docs.wagtail.org/en/stable/topics/pages.html +# https://docs.wagtail.org/en/stable/reference/streamfield/blocks.html#wagtail.fields.StreamField + + +class HomePage(Page): + pass diff --git a/dnscms/home/static/css/welcome_page.css b/dnscms/home/static/css/welcome_page.css new file mode 100644 index 0000000..bad2933 --- /dev/null +++ b/dnscms/home/static/css/welcome_page.css @@ -0,0 +1,184 @@ +html { + box-sizing: border-box; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +body { + max-width: 960px; + min-height: 100vh; + margin: 0 auto; + padding: 0 15px; + color: #231f20; + font-family: 'Helvetica Neue', 'Segoe UI', Arial, sans-serif; + line-height: 1.25; +} + +a { + background-color: transparent; + color: #308282; + text-decoration: underline; +} + +a:hover { + color: #ea1b10; +} + +h1, +h2, +h3, +h4, +h5, +p, +ul { + padding: 0; + margin: 0; + font-weight: 400; +} + +svg:not(:root) { + overflow: hidden; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: 20px; + padding-bottom: 10px; + border-bottom: 1px solid #e6e6e6; +} + +.logo { + width: 150px; + margin-inline-end: 20px; +} + +.logo a { + display: block; +} + +.figure-logo { + max-width: 150px; + max-height: 55.1px; +} + +.release-notes { + font-size: 14px; +} + +.main { + padding: 40px 0; + margin: 0 auto; + text-align: center; +} + +.figure-space { + max-width: 265px; +} + +@keyframes pos { + 0%, 100% { + transform: rotate(-6deg); + } + 50% { + transform: rotate(6deg); + } +} + +.egg { + fill: #43b1b0; + animation: pos 3s ease infinite; + transform: translateY(50px); + transform-origin: 50% 80%; +} + +.main-text { + max-width: 400px; + margin: 5px auto; +} + +.main-text h1 { + font-size: 22px; +} + +.main-text p { + margin: 15px auto 0; +} + +.footer { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + border-top: 1px solid #e6e6e6; + padding: 10px; +} + +.option { + display: block; + padding: 10px 10px 10px 34px; + position: relative; + text-decoration: none; +} + +.option svg { + width: 24px; + height: 24px; + fill: gray; + border: 1px solid #d9d9d9; + padding: 5px; + border-radius: 100%; + top: 10px; + inset-inline-start: 0; + position: absolute; +} + +.option h2 { + font-size: 19px; + text-decoration: underline; +} + +.option p { + padding-top: 3px; + color: #231f20; + font-size: 15px; + font-weight: 300; +} + +@media (max-width: 996px) { + body { + max-width: 780px; + } +} + +@media (max-width: 767px) { + .option { + flex: 0 0 50%; + } +} + +@media (max-width: 599px) { + .main { + padding: 20px 0; + } + + .figure-space { + max-width: 200px; + } + + .footer { + display: block; + width: 300px; + margin: 0 auto; + } +} + +@media (max-width: 360px) { + .header-link { + max-width: 100px; + } +} diff --git a/dnscms/home/templates/home/home_page.html b/dnscms/home/templates/home/home_page.html new file mode 100644 index 0000000..db9e9b0 --- /dev/null +++ b/dnscms/home/templates/home/home_page.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load static %} + +{% block body_class %}template-homepage{% endblock %} + +{% block extra_css %} + +{% comment %} +Delete the line below if you're just getting started and want to remove the welcome screen! +{% endcomment %} + +{% endblock extra_css %} + +{% block content %} + +{% comment %} +Delete the line below if you're just getting started and want to remove the welcome screen! +{% endcomment %} +{% include 'home/welcome_page.html' %} + +{% endblock content %} diff --git a/dnscms/home/templates/home/welcome_page.html b/dnscms/home/templates/home/welcome_page.html new file mode 100644 index 0000000..dcacaf3 --- /dev/null +++ b/dnscms/home/templates/home/welcome_page.html @@ -0,0 +1,52 @@ +{% load i18n wagtailcore_tags %} + +
+ + +
+
+
+ +
+
+

{% trans "Welcome to your new Wagtail site!" %}

+

{% trans 'Please feel free to join our community on Slack, or get started with one of the links below.' %}

+
+
+ diff --git a/dnscms/manage.py b/dnscms/manage.py new file mode 100755 index 0000000..6d2b5bd --- /dev/null +++ b/dnscms/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dnscms.settings.dev") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/dnscms/poetry.lock b/dnscms/poetry.lock new file mode 100644 index 0000000..e7c73bc --- /dev/null +++ b/dnscms/poetry.lock @@ -0,0 +1,875 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "aniso8601" +version = "9.0.1" +description = "A library for parsing ISO 8601 strings." +optional = false +python-versions = "*" +files = [ + {file = "aniso8601-9.0.1-py2.py3-none-any.whl", hash = "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f"}, + {file = "aniso8601-9.0.1.tar.gz", hash = "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"}, +] + +[package.extras] +dev = ["black", "coverage", "isort", "pre-commit", "pyenchant", "pylint"] + +[[package]] +name = "anyascii" +version = "0.3.2" +description = "Unicode to ASCII transliteration" +optional = false +python-versions = ">=3.3" +files = [ + {file = "anyascii-0.3.2-py3-none-any.whl", hash = "sha256:3b3beef6fc43d9036d3b0529050b0c48bfad8bc960e9e562d7223cfb94fe45d4"}, + {file = "anyascii-0.3.2.tar.gz", hash = "sha256:9d5d32ef844fe225b8bc7cba7f950534fae4da27a9bf3a6bea2cb0ea46ce4730"}, +] + +[[package]] +name = "asgiref" +version = "3.8.1" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.8" +files = [ + {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, + {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, +] + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + +[[package]] +name = "django" +version = "5.0.4" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +optional = false +python-versions = ">=3.10" +files = [ + {file = "Django-5.0.4-py3-none-any.whl", hash = "sha256:916423499d75d62da7aa038d19aef23d23498d8df229775eb0a6309ee1013775"}, + {file = "Django-5.0.4.tar.gz", hash = "sha256:4bd01a8c830bb77a8a3b0e7d8b25b887e536ad17a81ba2dce5476135c73312bd"}, +] + +[package.dependencies] +asgiref = ">=3.7.0,<4" +sqlparse = ">=0.3.1" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +argon2 = ["argon2-cffi (>=19.1.0)"] +bcrypt = ["bcrypt"] + +[[package]] +name = "django-filter" +version = "24.2" +description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." +optional = false +python-versions = ">=3.8" +files = [ + {file = "django-filter-24.2.tar.gz", hash = "sha256:48e5fc1da3ccd6ca0d5f9bb550973518ce977a4edde9d2a8a154a7f4f0b9f96e"}, + {file = "django_filter-24.2-py3-none-any.whl", hash = "sha256:df2ee9857e18d38bed203c8745f62a803fa0f31688c9fe6f8e868120b1848e48"}, +] + +[package.dependencies] +Django = ">=4.2" + +[[package]] +name = "django-modelcluster" +version = "6.3" +description = "Django extension to allow working with 'clusters' of models as a single unit, independently of the database" +optional = false +python-versions = ">=3.8" +files = [ + {file = "django-modelcluster-6.3.tar.gz", hash = "sha256:0caed8a0e889f3abb92f144670878a466ef954ffa6c4c7b9c80e6426b720a49d"}, + {file = "django_modelcluster-6.3-py2.py3-none-any.whl", hash = "sha256:a8783d6565a0663f41cd6003ea361c3a5711e8a2a326160f1ec1eceb3e973d4f"}, +] + +[package.dependencies] +django = ">=3.2" +pytz = ">=2022.4" + +[package.extras] +taggit = ["django-taggit (>=3.1)"] + +[[package]] +name = "django-permissionedforms" +version = "0.1" +description = "Django extension for creating forms that vary according to user permissions" +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-permissionedforms-0.1.tar.gz", hash = "sha256:4340bb20c4477fffb13b4cc5cccf9f1b1010b64f79956c291c72d2ad2ed243f8"}, + {file = "django_permissionedforms-0.1-py2.py3-none-any.whl", hash = "sha256:d341a961a27cc77fde8cc42141c6ab55cc1f0cb886963cc2d6967b9674fa47d6"}, +] + +[package.dependencies] +Django = "*" + +[package.extras] +testing = ["django-modelcluster"] + +[[package]] +name = "django-taggit" +version = "5.0.1" +description = "django-taggit is a reusable Django application for simple tagging." +optional = false +python-versions = ">=3.8" +files = [ + {file = "django-taggit-5.0.1.tar.gz", hash = "sha256:edcd7db1e0f35c304e082a2f631ddac2e16ef5296029524eb792af7430cab4cc"}, + {file = "django_taggit-5.0.1-py3-none-any.whl", hash = "sha256:a0ca8a28b03c4b26c2630fd762cb76ec39b5e41abf727a7b66f897a625c5e647"}, +] + +[package.dependencies] +Django = ">=4.1" + +[[package]] +name = "django-treebeard" +version = "4.7.1" +description = "Efficient tree implementations for Django" +optional = false +python-versions = ">=3.8" +files = [ + {file = "django-treebeard-4.7.1.tar.gz", hash = "sha256:846e462904b437155f76e04907ba4e48480716855f88b898df4122bdcfbd6e98"}, + {file = "django_treebeard-4.7.1-py3-none-any.whl", hash = "sha256:995c7120153ab999898fe3043bbdcd8a0fc77cc106eb94de7350e9d02c885135"}, +] + +[package.dependencies] +Django = ">=3.2" + +[[package]] +name = "djangorestframework" +version = "3.15.1" +description = "Web APIs for Django, made easy." +optional = false +python-versions = ">=3.6" +files = [ + {file = "djangorestframework-3.15.1-py3-none-any.whl", hash = "sha256:3ccc0475bce968608cf30d07fb17d8e52d1d7fc8bfe779c905463200750cbca6"}, + {file = "djangorestframework-3.15.1.tar.gz", hash = "sha256:f88fad74183dfc7144b2756d0d2ac716ea5b4c7c9840995ac3bfd8ec034333c1"}, +] + +[package.dependencies] +django = ">=3.0" + +[[package]] +name = "draftjs-exporter" +version = "5.0.0" +description = "Library to convert rich text from Draft.js raw ContentState to HTML" +optional = false +python-versions = "*" +files = [ + {file = "draftjs_exporter-5.0.0-py3-none-any.whl", hash = "sha256:8cb9d2d51284233decfe274802f1c53e257158c62b9f53ed2399de3fa80ac561"}, + {file = "draftjs_exporter-5.0.0.tar.gz", hash = "sha256:2efee45d4bb4c0aaacc3e5ea2983a29a29381e02037f3f92a6b12706d7b87e1e"}, +] + +[package.extras] +html5lib = ["beautifulsoup4 (>=4.4.1,<5)", "html5lib (>=0.999,<2)"] +lxml = ["lxml (>=4.2.0,<5)"] + +[[package]] +name = "et-xmlfile" +version = "1.1.0" +description = "An implementation of lxml.xmlfile for the standard library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, + {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, +] + +[[package]] +name = "filetype" +version = "1.2.0" +description = "Infer file type and MIME type of any file/buffer. No external dependencies." +optional = false +python-versions = "*" +files = [ + {file = "filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25"}, + {file = "filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb"}, +] + +[[package]] +name = "graphene" +version = "3.3" +description = "GraphQL Framework for Python" +optional = false +python-versions = "*" +files = [ + {file = "graphene-3.3-py2.py3-none-any.whl", hash = "sha256:bb3810be33b54cb3e6969506671eb72319e8d7ba0d5ca9c8066472f75bf35a38"}, + {file = "graphene-3.3.tar.gz", hash = "sha256:529bf40c2a698954217d3713c6041d69d3f719ad0080857d7ee31327112446b0"}, +] + +[package.dependencies] +aniso8601 = ">=8,<10" +graphql-core = ">=3.1,<3.3" +graphql-relay = ">=3.1,<3.3" + +[package.extras] +dev = ["black (==22.3.0)", "coveralls (>=3.3,<4)", "flake8 (>=4,<5)", "iso8601 (>=1,<2)", "mock (>=4,<5)", "pytest (>=6,<7)", "pytest-asyncio (>=0.16,<2)", "pytest-benchmark (>=3.4,<4)", "pytest-cov (>=3,<4)", "pytest-mock (>=3,<4)", "pytz (==2022.1)", "snapshottest (>=0.6,<1)"] +test = ["coveralls (>=3.3,<4)", "iso8601 (>=1,<2)", "mock (>=4,<5)", "pytest (>=6,<7)", "pytest-asyncio (>=0.16,<2)", "pytest-benchmark (>=3.4,<4)", "pytest-cov (>=3,<4)", "pytest-mock (>=3,<4)", "pytz (==2022.1)", "snapshottest (>=0.6,<1)"] + +[[package]] +name = "graphene-django" +version = "3.2.1" +description = "Graphene Django integration" +optional = false +python-versions = "*" +files = [ + {file = "graphene-django-3.2.1.tar.gz", hash = "sha256:52145037872d2575974c4bb2be224756ffeafe5a4e20f9c4367519622965812b"}, + {file = "graphene_django-3.2.1-py2.py3-none-any.whl", hash = "sha256:3fbdd8d4990ecec326c59d68edfcaf9a7bc9c4dbdcbf88b11ac46dfc10240e49"}, +] + +[package.dependencies] +Django = ">=3.2" +graphene = ">=3.0,<4" +graphql-core = ">=3.1.0,<4" +graphql-relay = ">=3.1.1,<4" +promise = ">=2.1" +text-unidecode = "*" + +[package.extras] +dev = ["coveralls", "django-filter (>=22.1)", "djangorestframework (>=3.6.3)", "mock", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-django (>=4.5.2)", "pytest-random-order", "pytz", "ruff (==0.1.2)"] +rest-framework = ["djangorestframework (>=3.6.3)"] +test = ["coveralls", "django-filter (>=22.1)", "djangorestframework (>=3.6.3)", "mock", "pytest (>=7.3.1)", "pytest-cov", "pytest-django (>=4.5.2)", "pytest-random-order", "pytz"] + +[[package]] +name = "graphql-core" +version = "3.2.3" +description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL." +optional = false +python-versions = ">=3.6,<4" +files = [ + {file = "graphql-core-3.2.3.tar.gz", hash = "sha256:06d2aad0ac723e35b1cb47885d3e5c45e956a53bc1b209a9fc5369007fe46676"}, + {file = "graphql_core-3.2.3-py3-none-any.whl", hash = "sha256:5766780452bd5ec8ba133f8bf287dc92713e3868ddd83aee4faab9fc3e303dc3"}, +] + +[[package]] +name = "graphql-relay" +version = "3.2.0" +description = "Relay library for graphql-core" +optional = false +python-versions = ">=3.6,<4" +files = [ + {file = "graphql-relay-3.2.0.tar.gz", hash = "sha256:1ff1c51298356e481a0be009ccdff249832ce53f30559c1338f22a0e0d17250c"}, + {file = "graphql_relay-3.2.0-py3-none-any.whl", hash = "sha256:c9b22bd28b170ba1fe674c74384a8ff30a76c8e26f88ac3aa1584dd3179953e5"}, +] + +[package.dependencies] +graphql-core = ">=3.2,<3.3" + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "l18n" +version = "2021.3" +description = "Internationalization for pytz timezones and territories" +optional = false +python-versions = "*" +files = [ + {file = "l18n-2021.3-py3-none-any.whl", hash = "sha256:78495d1df95b6f7dcc694d1ba8994df709c463a1cbac1bf016e1b9a5ce7280b9"}, + {file = "l18n-2021.3.tar.gz", hash = "sha256:1956e890d673d17135cc20913253c154f6bc1c00266c22b7d503cc1a5a42d848"}, +] + +[package.dependencies] +pytz = ">=2020.1" +six = "*" + +[[package]] +name = "laces" +version = "0.1.1" +description = "Django components that know how to render themselves." +optional = false +python-versions = ">=3.8" +files = [ + {file = "laces-0.1.1-py3-none-any.whl", hash = "sha256:ae2c575b9aaa46154e5518c61c9f86f5a9478f753a51e9c5547c7d275d361242"}, + {file = "laces-0.1.1.tar.gz", hash = "sha256:e45159c46f6adca33010d34e9af869e57201b70675c6dc088e919b16c89456a4"}, +] + +[package.dependencies] +Django = ">=3.2" + +[package.extras] +dev = ["black (==24.1.1)", "blacken-docs (==1.16.0)", "coverage (==7.3.4)", "django-stubs[compatible-mypy] (==4.2.7)", "flake8 (==7.0.0)", "flake8-bugbear", "flake8-comprehensions", "isort (==5.13.2)", "mypy (==1.7.1)", "pre-commit (==3.4.0)", "tox (==4.12.1)", "tox-gh-actions (==3.2.0)", "types-requests (==2.31.0.20240125)", "virtualenv-pyenv (==0.4.0)"] +testing = ["coverage (==7.3.4)", "dj-database-url (==2.1.0)"] + +[[package]] +name = "openpyxl" +version = "3.1.2" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +optional = false +python-versions = ">=3.6" +files = [ + {file = "openpyxl-3.1.2-py2.py3-none-any.whl", hash = "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5"}, + {file = "openpyxl-3.1.2.tar.gz", hash = "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184"}, +] + +[package.dependencies] +et-xmlfile = "*" + +[[package]] +name = "pillow" +version = "10.3.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, + {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, + {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, + {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, + {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, + {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, + {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, + {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, + {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, + {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, + {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, + {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, + {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, + {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, + {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, + {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, + {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + +[[package]] +name = "pillow-heif" +version = "0.16.0" +description = "Python interface for libheif library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pillow_heif-0.16.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:c7db96ac172e2654676986e8c35fa32bffdd5b429a8c86b9d628c0333c570d82"}, + {file = "pillow_heif-0.16.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:a146be0c8e7bef204eeaa14799b2fca8a4a52ad972850975e23ef10cee4e7de7"}, + {file = "pillow_heif-0.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33e0b1549bcdfec363b3ba6fb55b3de882e1409b5b00f5a68a1a027f051e8ef2"}, + {file = "pillow_heif-0.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fea4410ce02e295079db5b2617579ba016671d334ac1888a1d4b34aedb56b866"}, + {file = "pillow_heif-0.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:331579ce4f5fa079595c529b06810886ff76f8ade3eb411a1c9c90853a708022"}, + {file = "pillow_heif-0.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:792e5d88b7d016fe48ae2fd77a852ec8dcf9a7fad1f7f191d35bc173896fe378"}, + {file = "pillow_heif-0.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e0492e4fd6d3334b9eed3651058216ef62f04afa099cfc6b05815c1bf0da2c38"}, + {file = "pillow_heif-0.16.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:beb6576cbe5a9404a8f2ad9ec68f6b0c406e5e9f5d5573722dc3244898dc9866"}, + {file = "pillow_heif-0.16.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:241cf6c510215c6df0ee948dfed06a20c099475250c5c6cac5e7a1ef9e0ec4c3"}, + {file = "pillow_heif-0.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28c980bf8d5239ee87986c9217a5954b07993d71d391949a9feafad0a9c5e9a7"}, + {file = "pillow_heif-0.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8856cf5f0d53f83d814ae5c8d34433e5e5ad9f3e328480257cd6e9fbdb4a458"}, + {file = "pillow_heif-0.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fba5c46f84031f1186bdea2a0c95f82958f8c29321200e73d7ac5e79ee460c83"}, + {file = "pillow_heif-0.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5c7f7a94fc2d08ddcf55a6834c4c55b7dea9605656c565ce11c82e3f6e0454a8"}, + {file = "pillow_heif-0.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a2681d4b62418813289987a9420059d724cd93542d0b05e0928fe4578517714"}, + {file = "pillow_heif-0.16.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:7e424d6a34b9466d054706393e76b5abdd84fabdc0c72b19ca10435a76140de7"}, + {file = "pillow_heif-0.16.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:be41b7fadd4a9355d24936f6fad83bb8130fe55ba228ec298ad316392bb6f38b"}, + {file = "pillow_heif-0.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:078bc74fd767625e465b2c107228f9c398b9a128bdf81b3f18812d7c07be660f"}, + {file = "pillow_heif-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f4293ecbb81d255d8d887dce4708a58e87c86e53c6f1b1affc4c3105e1bcb8c"}, + {file = "pillow_heif-0.16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f63a1d8f95811569df5df9b6b11674038929c2f696221f2a393aee5ac1e535b4"}, + {file = "pillow_heif-0.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:89ec30420ddc843c43916febbe31697552ed123396a1696715eea75169866c07"}, + {file = "pillow_heif-0.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:d4595ec975db845d84ab90cbf0678f15b0068b8b83c01d1db7ea524e31bab4b4"}, + {file = "pillow_heif-0.16.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:1421d96aebdc9f5773213c8221ce547efb56e37a62da6698312edd4f281efb42"}, + {file = "pillow_heif-0.16.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:88ff22d2b162e7edd9cb9dd98de81455be04c40a99d1d3d3ebe1602b1a21c453"}, + {file = "pillow_heif-0.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb3efbe8efd26203589794988b11ea9bf3dea2d3bcf218e658f779d526dfcf80"}, + {file = "pillow_heif-0.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f062c1be6f04804ffdf0bc452142eff38d7544c8655c04291d16e3b996e4dc4"}, + {file = "pillow_heif-0.16.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:7fabd6534a38078a66ce8b7a5ae8ad37afd9863c930abd3031fb553f1ab4f01a"}, + {file = "pillow_heif-0.16.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d9e465d92cf01093e3e4c33776af97368add23ac1c8d0007f34b8d3e3390d6ad"}, + {file = "pillow_heif-0.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:502cebc90c11a6bffa2ea899088999c25fc99c8f322e047a266e541e3046b27c"}, + {file = "pillow_heif-0.16.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:c2ad68e3e4be40adfc5290bf6daa1569dd7d18501e17779d217ce5cd8c1e338d"}, + {file = "pillow_heif-0.16.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8e168d45b2ce63c1fe2334fd02927699b0097de72605f7571948010fd79e58f0"}, + {file = "pillow_heif-0.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bf10a1686c2d51f4db8ebb78825f96f28d18d1878599e1c64e88cfbdb70a3d2"}, + {file = "pillow_heif-0.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f15dc73ced02a0ccfac93159d12deeaecfbe4335883a1a3309df0f01c26e6e6"}, + {file = "pillow_heif-0.16.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2673048f3cf1498327add70f16e1129be2a09cf4a31cbc02363f5760eb5ba955"}, + {file = "pillow_heif-0.16.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9273af7224e0fb16c18637184a8ea9a8790105658daab04ad541982b8623e5c1"}, + {file = "pillow_heif-0.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:f613dfd05fd62a8b7b57649bfa5db1501be41e18b5e15dd4a2fc12d3e3ddfdaa"}, + {file = "pillow_heif-0.16.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:3501f22985cbb427c76febf07a7e309cb828e485c0cf250a625733fc06fc1815"}, + {file = "pillow_heif-0.16.0-pp310-pypy310_pp73-macosx_12_0_arm64.whl", hash = "sha256:2b7450303f08ec81d1a63a75052863bb687fc3be1fdd8a34d2c0fef627aacae5"}, + {file = "pillow_heif-0.16.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7794c1a8304eeb841d72cb73aa64cc60c9e5dccb2c7612f8caf528505f78581f"}, + {file = "pillow_heif-0.16.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5edd98192f74e4c7cffdd62953b2987e2b1e0d6a55d5c940306bed71f40206a"}, + {file = "pillow_heif-0.16.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:38fa2854ec7dbe6c875d64cc5b3cf5cc55f1c8a0248dc1c7c34e9d2505521b82"}, + {file = "pillow_heif-0.16.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b50160331754b603524e6ed33c386f478fd66fb345fa6433a507a01c8de642c6"}, + {file = "pillow_heif-0.16.0-pp38-pypy38_pp73-macosx_12_0_arm64.whl", hash = "sha256:9fd829c257a763e3a2e8418a773c2808c90799ee3e6b405b5399cb4fdfbe336e"}, + {file = "pillow_heif-0.16.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbd9cc527bbd53c3e7588e16aad170e11cfd180b7e9bd84f18fb020ddec11408"}, + {file = "pillow_heif-0.16.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a27abb523a07b17c118c09f1a00f92cde2295f8e997600024d4b57df3c5ba818"}, + {file = "pillow_heif-0.16.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0075adeb324adb07ddbfbe8a5c79ed12e5d04e60e9a642ff9427e71b5b0adccd"}, + {file = "pillow_heif-0.16.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:40014105688478d6ca146fc04bff6c13f445d01bdea79417b34ee50c1e559190"}, + {file = "pillow_heif-0.16.0-pp39-pypy39_pp73-macosx_12_0_arm64.whl", hash = "sha256:7ef47297d526147923f4ecc7ff681a5d5f4e6e3300017681f59968652a0d8afb"}, + {file = "pillow_heif-0.16.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9923dfcc97ae9484d3514f2f6ec368e2ac97cd66f7b95359cc1b0ec0c1cd6157"}, + {file = "pillow_heif-0.16.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17963a73186961fe7792aef01c46e980635f3fcc1836393de39ec9c6776ca51e"}, + {file = "pillow_heif-0.16.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4b6caa5b13b4dfc180507527254014530f6bedbeabc1de2238918bf5b2700c7e"}, + {file = "pillow_heif-0.16.0.tar.gz", hash = "sha256:4d95004bb77aa640f80617716aa21bc092ec06307f6f2ad423deeeda07b4d29c"}, +] + +[package.dependencies] +pillow = ">=9.5.0" + +[package.extras] +dev = ["coverage", "defusedxml", "numpy", "opencv-python (==4.9.0.80)", "packaging", "pre-commit", "pylint", "pympler", "pytest"] +docs = ["sphinx (>=4.4)", "sphinx-issues (>=3.0.1)", "sphinx-rtd-theme (>=1.0)"] +tests = ["defusedxml", "numpy", "packaging", "pympler", "pytest"] +tests-min = ["defusedxml", "packaging", "pytest"] + +[[package]] +name = "promise" +version = "2.3" +description = "Promises/A+ implementation for Python" +optional = false +python-versions = "*" +files = [ + {file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"}, +] + +[package.dependencies] +six = "*" + +[package.extras] +test = ["coveralls", "futures", "mock", "pytest (>=2.7.3)", "pytest-benchmark", "pytest-cov"] + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "ruff" +version = "0.3.7" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0e8377cccb2f07abd25e84fc5b2cbe48eeb0fea9f1719cad7caedb061d70e5ce"}, + {file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:15a4d1cc1e64e556fa0d67bfd388fed416b7f3b26d5d1c3e7d192c897e39ba4b"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d28bdf3d7dc71dd46929fafeec98ba89b7c3550c3f0978e36389b5631b793663"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:379b67d4f49774ba679593b232dcd90d9e10f04d96e3c8ce4a28037ae473f7bb"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c060aea8ad5ef21cdfbbe05475ab5104ce7827b639a78dd55383a6e9895b7c51"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ebf8f615dde968272d70502c083ebf963b6781aacd3079081e03b32adfe4d58a"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48098bd8f5c38897b03604f5428901b65e3c97d40b3952e38637b5404b739a2"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da8a4fda219bf9024692b1bc68c9cff4b80507879ada8769dc7e985755d662ea"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c44e0149f1d8b48c4d5c33d88c677a4aa22fd09b1683d6a7ff55b816b5d074f"}, + {file = "ruff-0.3.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3050ec0af72b709a62ecc2aca941b9cd479a7bf2b36cc4562f0033d688e44fa1"}, + {file = "ruff-0.3.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a29cc38e4c1ab00da18a3f6777f8b50099d73326981bb7d182e54a9a21bb4ff7"}, + {file = "ruff-0.3.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b15cc59c19edca917f51b1956637db47e200b0fc5e6e1878233d3a938384b0b"}, + {file = "ruff-0.3.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e491045781b1e38b72c91247cf4634f040f8d0cb3e6d3d64d38dcf43616650b4"}, + {file = "ruff-0.3.7-py3-none-win32.whl", hash = "sha256:bc931de87593d64fad3a22e201e55ad76271f1d5bfc44e1a1887edd0903c7d9f"}, + {file = "ruff-0.3.7-py3-none-win_amd64.whl", hash = "sha256:5ef0e501e1e39f35e03c2acb1d1238c595b8bb36cf7a170e7c1df1b73da00e74"}, + {file = "ruff-0.3.7-py3-none-win_arm64.whl", hash = "sha256:789e144f6dc7019d1f92a812891c645274ed08af6037d11fc65fcbc183b7d59f"}, + {file = "ruff-0.3.7.tar.gz", hash = "sha256:d5c1aebee5162c2226784800ae031f660c350e7a3402c4d1f8ea4e97e232e3ba"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "sqlparse" +version = "0.5.0" +description = "A non-validating SQL parser." +optional = false +python-versions = ">=3.8" +files = [ + {file = "sqlparse-0.5.0-py3-none-any.whl", hash = "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"}, + {file = "sqlparse-0.5.0.tar.gz", hash = "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93"}, +] + +[package.extras] +dev = ["build", "hatch"] +doc = ["sphinx"] + +[[package]] +name = "telepath" +version = "0.3.1" +description = "A library for exchanging data between Python and JavaScript" +optional = false +python-versions = ">=3.8" +files = [ + {file = "telepath-0.3.1-py38-none-any.whl", hash = "sha256:c280aa8e77ad71ce80e96500a4e4d4a32f35b7e0b52e896bb5fde9a5bcf0699a"}, + {file = "telepath-0.3.1.tar.gz", hash = "sha256:925c0609e0a8a6488ec4a55b19d485882cf72223b2b19fe2359a50fddd813c9c"}, +] + +[package.extras] +docs = ["mkdocs (>=1.1,<1.2)", "mkdocs-material (>=6.2,<6.3)"] + +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "urllib3" +version = "2.2.1" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "wagtail" +version = "6.1" +description = "A Django content management system." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wagtail-6.1-py3-none-any.whl", hash = "sha256:6c5ccabc5ac1701e4107241077a880f3fabd34c4ac20bdc412e8961e7b17b4a8"}, + {file = "wagtail-6.1.tar.gz", hash = "sha256:ad33ed1ccad1f9f1b4faba216c6cc92ba1a2dfefdbfd97c23ffbf7db99dd93c5"}, +] + +[package.dependencies] +anyascii = ">=0.1.5" +beautifulsoup4 = ">=4.8,<4.13" +Django = ">=4.2,<6.0" +django-filter = ">=23.3,<25" +django-modelcluster = ">=6.2.1,<7.0" +django-permissionedforms = ">=0.1,<1.0" +django-taggit = ">=4.0,<5.1" +django-treebeard = ">=4.5.1,<5.0" +djangorestframework = ">=3.15.1,<4.0" +draftjs-exporter = ">=2.1.5,<6.0" +l18n = ">=2018.5" +laces = ">=0.1,<0.2" +openpyxl = ">=3.0.10,<4.0" +Pillow = ">=9.1.0,<11.0.0" +requests = ">=2.11.1,<3.0" +telepath = ">=0.3.1,<1" +Willow = {version = ">=1.8.0,<2", extras = ["heif"]} + +[package.extras] +docs = ["Sphinx (>=1.5.2)", "myst-parser (==2.0.0)", "pyenchant (>=3.1.1,<4)", "sphinx-autobuild (>=0.6.0)", "sphinx-copybutton (>=0.5,<1.0)", "sphinx-wagtail-theme (==6.3.0)", "sphinxcontrib-spelling (>=7,<8)"] +testing = ["Jinja2 (>=3.0,<3.2)", "azure-mgmt-cdn (>=12.0,<13.0)", "azure-mgmt-frontdoor (>=1.0,<1.1)", "boto3 (>=1.28,<2)", "coverage (>=3.7.0)", "curlylint (==0.13.1)", "django-pattern-library (>=0.7)", "djhtml (==3.0.6)", "doc8 (==0.8.1)", "factory-boy (>=3.2)", "freezegun (>=0.3.8)", "polib (>=1.1,<2.0)", "python-dateutil (>=2.7)", "pytz (>=2014.7)", "ruff (==0.1.5)", "semgrep (==1.40.0)", "tblib (>=2.0,<3.0)"] + +[[package]] +name = "wagtail-grapple" +version = "0.25.1" +description = "A Wagtail package that speeds up and simplifies implementing a GraphQL endpoint!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "wagtail_grapple-0.25.1-py3-none-any.whl", hash = "sha256:81e7f568c6dbd8bb0f607c736c677843bd4f6601ee852c8dde4dce2c9279ab29"}, + {file = "wagtail_grapple-0.25.1.tar.gz", hash = "sha256:cd2956d8bbd4e2b60a482829b00dbfbd782c6ca28ec5b0e50cd442b66a5e6898"}, +] + +[package.dependencies] +graphene-django = ">=3,<4" +Wagtail = ">=5.2" +wagtail-headless-preview = "*" + +[package.extras] +docs = ["Sphinx (>=7.0,<8.0)", "sphinx-wagtail-theme (>=6.0,<7.0)", "sphinx_copybutton (>=0.5)", "sphinxcontrib-spelling (>=8.0,<9.0)"] +testing = ["coverage[toml] (>=7.2.7,<8.0)"] + +[[package]] +name = "wagtail-headless-preview" +version = "0.8.0" +description = "Enhance Wagtail previews in headless setups." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wagtail_headless_preview-0.8.0-py3-none-any.whl", hash = "sha256:91b305c36573490856e212f9e5645ada81f72ad37f1bb00e6feddc5537252358"}, + {file = "wagtail_headless_preview-0.8.0.tar.gz", hash = "sha256:581d8419cd1ef1f7de88235445e9695e5591d46259283d56bfe814e8620fa1d5"}, +] + +[package.dependencies] +Wagtail = ">=4.1" + +[package.extras] +testing = ["coverage[toml] (>=7.0,<8.0)", "django-cors-headers", "tox (>=4)"] + +[[package]] +name = "willow" +version = "1.8.0" +description = "A Python image library that sits on top of Pillow, Wand and OpenCV" +optional = false +python-versions = ">=3.8" +files = [ + {file = "willow-1.8.0-py3-none-any.whl", hash = "sha256:48ccf5ce48ccd29c37a32497cd7af50983f8570543c4de2988b15d583efc66be"}, + {file = "willow-1.8.0.tar.gz", hash = "sha256:ef3df6cde80d4914e719188147bef1d71c240edb118340e0c5957ecc8fe08315"}, +] + +[package.dependencies] +defusedxml = ">=0.7,<1.0" +filetype = ">=1.0.10,<1.1.0 || >1.1.0" +pillow-heif = {version = ">=0.13.0,<1.0.0", optional = true, markers = "extra == \"heif\" and python_version >= \"3.12\""} + +[package.extras] +docs = ["Sphinx (>=7.0)", "sphinx-wagtail-theme (>=6.1.1,<7.0)", "sphinx_copybutton (>=0.5)", "sphinxcontrib-spelling (>=8.0,<9.0)"] +heif = ["pillow-heif (>=0.10.0,<1.0.0)", "pillow-heif (>=0.13.0,<1.0.0)"] +pillow = ["Pillow (>=9.1.0,<11.0.0)"] +testing = ["coverage[toml] (>=7.2.7,<8.0)", "pre-commit (>=3.4.0)", "willow[heif,pillow,wand]"] +wand = ["Wand (>=0.6,<1.0)"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.12" +content-hash = "f9559b4b0ff079a52cc8f8141ce16b6e57d6422cfa73ece94370337b08a5faf6" diff --git a/dnscms/pyproject.toml b/dnscms/pyproject.toml new file mode 100644 index 0000000..d90c2be --- /dev/null +++ b/dnscms/pyproject.toml @@ -0,0 +1,27 @@ +[tool.poetry] +name = "dnscms" +version = "0.1.0" +description = "" +authors = ["Your Name "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.12" +wagtail = "^6.0.1" +django = "^5.0.4" +wagtail-grapple = "^0.25.1" + +[tool.poetry.group.dev.dependencies] +ruff = "^0.3.4" + +[tool.ruff] +line-length = 99 + +[tool.ruff.lint] +select = ["F", "E", "W", "Q", "UP", "DJ"] +ignore = [] +exclude = ["**/migrations/*.py"] + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api"