diff --git a/.containerignore b/.containerignore deleted file mode 100644 index 4f748cf..0000000 --- a/.containerignore +++ /dev/null @@ -1,4 +0,0 @@ -/.idea/ -/containers/ -.gitignore -compose.* \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..dc5a875 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +**/*.log +**/*.md +**/*.php~ +**/*.dist.php +**/*.dist +**/*.cache +**/._* +**/.dockerignore +**/.DS_Store +**/.git/ +**/.gitattributes +**/.gitignore +**/.gitmodules +**/compose.*.yaml +**/compose.*.yml +**/compose.yaml +**/compose.yml +**/docker-compose.*.yaml +**/docker-compose.*.yml +**/docker-compose.yaml +**/docker-compose.yml +**/Dockerfile +**/Thumbs.db +.github/ +docs/ +public/bundles/ +tests/ +var/ +vendor/ +.editorconfig +.env.*.local +.env.local +.env.local.php +.env.test diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0315479 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,57 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + +[*] +# Change these settings to your own preference +indent_style = space +indent_size = 4 + +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{js,html,ts,tsx}] +indent_size = 2 + +[*.json] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + +[*.sh] +indent_style = tab + +[*.xml.dist] +indent_style = space +indent_size = 4 + +[*.{yaml,yml}] +trim_trailing_whitespace = false + +[.github/workflows/*.yml] +indent_size = 2 + +[.gitmodules] +indent_style = tab + +[.php_cs.dist] +indent_style = space +indent_size = 4 + +[composer.json] +indent_size = 4 + +[{compose,docker-compose}.*.{yaml,yml}] +indent_size = 2 + +[*.*Dockerfile] +indent_style = tab + +[*.*Caddyfile] +indent_style = tab diff --git a/.env b/.env new file mode 100644 index 0000000..e6cabe4 --- /dev/null +++ b/.env @@ -0,0 +1,20 @@ +# In all environments, the following files are loaded if they exist, +# the latter taking precedence over the former: +# +# * .env contains default values for the environment variables needed by the app +# * .env.local uncommitted file with local overrides +# * .env.$APP_ENV committed environment-specific defaults +# * .env.$APP_ENV.local uncommitted environment-specific overrides +# +# Real environment variables win over .env files. +# +# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. +# https://symfony.com/doc/current/configuration/secrets.html +# +# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). +# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_SECRET= +###< symfony/framework-bundle ### diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000..f359c83 --- /dev/null +++ b/.env.dev @@ -0,0 +1,4 @@ + +###> symfony/framework-bundle ### +APP_SECRET=e26b9552d9e7f969b160373effaa7690 +###< symfony/framework-bundle ### diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..642c91f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +* text=auto eol=lf + +*.conf text eol=lf +*.html text eol=lf +*.ini text eol=lf +*.js text eol=lf +*.json text eol=lf +*.md text eol=lf +*.php text eol=lf +*.sh text eol=lf +*.yaml text eol=lf +*.yml text eol=lf +bin/console text eol=lf +composer.lock text eol=lf merge=ours + +*.ico binary +*.png binary diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8b0f691 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,76 @@ +name: CI + +on: + push: + branches: + - main + pull_request: ~ + workflow_dispatch: ~ + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + tests: + name: Tests + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Build Docker images + uses: docker/bake-action@v4 + with: + pull: true + load: true + files: | + compose.yaml + compose.override.yaml + set: | + *.cache-from=type=gha,scope=${{github.ref}} + *.cache-from=type=gha,scope=refs/heads/main + *.cache-to=type=gha,scope=${{github.ref}},mode=max + - + name: Start services + run: docker compose up --wait --no-build + - + name: Check HTTP reachability + run: curl -v --fail-with-body http://localhost + - + name: Check HTTPS reachability + if: false # Remove this line when the homepage will be configured, or change the path to check + run: curl -vk --fail-with-body https://localhost + - + name: Check Mercure reachability + run: curl -vkI --fail-with-body https://localhost/.well-known/mercure?topic=test + - + name: Create test database + if: false # Remove this line if Doctrine ORM is installed + run: docker compose exec -T php bin/console -e test doctrine:database:create + - + name: Run migrations + if: false # Remove this line if Doctrine Migrations is installed + run: docker compose exec -T php bin/console -e test doctrine:migrations:migrate --no-interaction + - + name: Run PHPUnit + if: false # Remove this line if PHPUnit is installed + run: docker compose exec -T php bin/phpunit + - + name: Doctrine Schema Validator + if: false # Remove this line if Doctrine ORM is installed + run: docker compose exec -T php bin/console -e test doctrine:schema:validate + lint: + name: Docker Lint + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Lint Dockerfile + uses: hadolint/hadolint-action@v3.1.0 diff --git a/.gitignore b/.gitignore index 8df0ad4..efc07b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,174 +1,60 @@ -compose.override.yaml -/tvdt/staticfiles/ - -.idea/ ### Generated by gibo (https://github.com/simonwhitaker/gibo) -### https://raw.github.com/github/gitignore/76739a38b56907118c5a880d63250c99d5690a5a/Python.gitignore +### https://raw.github.com/github/gitignore/6eeebe6f49678aacd8311ce079842c971b3ebe96/Symfony.gitignore -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class +# Cache and logs (Symfony2) +/app/cache/* +/app/logs/* +!app/cache/.gitkeep +!app/logs/.gitkeep -# C extensions -*.so +# Email spool folder +/app/spool/* -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST +# Cache, session files and logs (Symfony3) +/var/cache/* +/var/logs/* +/var/sessions/* +!var/cache/.gitkeep +!var/logs/.gitkeep +!var/sessions/.gitkeep -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec +# Logs (Symfony4) +/var/log/* +!var/log/.gitkeep -# Installer logs -pip-log.txt -pip-delete-this-directory.txt +# Parameters +/app/config/parameters.yml +/app/config/parameters.ini -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ +# Managed by Composer +/app/bootstrap.php.cache +/var/bootstrap.php.cache +/bin/* +!bin/console +!bin/symfony_requirements +/vendor/ -# Translations -*.mo -*.pot +# Assets and user uploads +/web/bundles/ +/web/uploads/ -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal +# PHPUnit +/app/phpunit.xml +/phpunit.xml -# Flask stuff: -instance/ -.webassets-cache +# Build data +/build/ -# Scrapy stuff: -.scrapy +# Composer PHAR +/composer.phar -# Sphinx documentation -docs/_build/ +# Backup entities generated with doctrine:generate:entities command +**/Entity/*~ -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/latest/usage/project/#working-with-version-control -.pdm.toml -.pdm-python -.pdm-build/ - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +# Embedded web-server pid file +/.web-server-pid ### Generated by gibo (https://github.com/simonwhitaker/gibo) -### https://raw.github.com/github/gitignore/76739a38b56907118c5a880d63250c99d5690a5a/Global/macOS.gitignore +### https://raw.github.com/github/gitignore/6eeebe6f49678aacd8311ce079842c971b3ebe96/Global/macOS.gitignore # General .DS_Store @@ -197,3 +83,13 @@ Icon Network Trash Folder Temporary Items .apdisk + +###> symfony/framework-bundle ### +/.env.local +/.env.local.php +/.env.*.local +/config/secrets/prod/prod.decrypt.private.php +/public/bundles/ +/var/ +/vendor/ +###< symfony/framework-bundle ### diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8332832 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,94 @@ +#syntax=docker/dockerfile:1 + +# Versions +FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream + +# The different stages of this Dockerfile are meant to be built into separate images +# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage +# https://docs.docker.com/compose/compose-file/#target + + +# Base FrankenPHP image +FROM frankenphp_upstream AS frankenphp_base + +WORKDIR /app + +VOLUME /app/var/ + +# persistent / runtime deps +# hadolint ignore=DL3008 +RUN apt-get update && apt-get install -y --no-install-recommends \ + acl \ + file \ + gettext \ + git \ + && rm -rf /var/lib/apt/lists/* + +RUN set -eux; \ + install-php-extensions \ + @composer \ + apcu \ + intl \ + opcache \ + zip \ + ; + +# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser +ENV COMPOSER_ALLOW_SUPERUSER=1 + +ENV PHP_INI_SCAN_DIR=":$PHP_INI_DIR/app.conf.d" + +###> recipes ### +###< recipes ### + +COPY --link frankenphp/conf.d/10-app.ini $PHP_INI_DIR/app.conf.d/ +COPY --link --chmod=755 frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +COPY --link frankenphp/Caddyfile /etc/caddy/Caddyfile + +ENTRYPOINT ["docker-entrypoint"] + +HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 +CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile" ] + +# Dev FrankenPHP image +FROM frankenphp_base AS frankenphp_dev + +ENV APP_ENV=dev XDEBUG_MODE=off + +RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" + +RUN set -eux; \ + install-php-extensions \ + xdebug \ + ; + +COPY --link frankenphp/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/ + +CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--watch" ] + +# Prod FrankenPHP image +FROM frankenphp_base AS frankenphp_prod + +ENV APP_ENV=prod +ENV FRANKENPHP_CONFIG="import worker.Caddyfile" + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +COPY --link frankenphp/conf.d/20-app.prod.ini $PHP_INI_DIR/app.conf.d/ +COPY --link frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile + +# prevent the reinstallation of vendors at every changes in the source code +COPY --link composer.* symfony.* ./ +RUN set -eux; \ + composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress + +# copy sources +COPY --link . ./ +RUN rm -Rf frankenphp/ + +RUN set -eux; \ + mkdir -p var/cache var/log; \ + composer dump-autoload --classmap-authoritative --no-dev; \ + composer dump-env prod; \ + composer run-script --no-dev post-install-cmd; \ + chmod +x bin/console; sync; diff --git a/Makefile b/Makefile deleted file mode 100644 index 178e130..0000000 --- a/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -DOCKER_EXEC=docker compose exec app -.DEFAULT_GOAL := help - -.PHONY: help -help: - @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-10s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) - -.PHONY: init -init: install up migrate fixtures ## setup the application from scratch - -.PHONY: up -up: ## Starts the app - @docker compose up -d --force-recreate - -.PHONY: down -down: ## Stops the app - @docker compose down --remove-orphans - -.PHONY: build -build: ## (Re)build the containers - @echo ✨ Building container - @docker compose build - -.PHONY: shell -shell: ## Opens a shell in the app container - @${DOCKER_EXEC} bash - -.PHONY: migrate -migrate: ## Migrate the database to the latest version - @echo ✨ Appling migrations - @${DOCKER_EXEC} python manage.py migrate - -.PHONY: compilemessages -messages: ## Compile translations - @echo ✨ Finding translations - @${DOCKER_EXEC} python manage.py makemessages -l nl - @echo ✨ Compiling translations - @${DOCKER_EXEC} python manage.py compilemessages --ignore .venv - -.PHONY: install -install: ## Install dependencies in container - @echo ✨ Installing dependencies - @docker compose run --rm --entrypoint="" app poetry install --without prod --sync - -.PHONY: fixtures -fixtures: - @echo ✨ Loading fixtures - @${DOCKER_EXEC} python manage.py loaddata krtek - -.PHONY: _clean -_clean: - @echo ✨ Stopping containers - @docker compose down -v - @echo ✨ Removing compiled files - @rm -f tvdt/*/locale/*/LC_MESSAGES/django.mo tvdt/locale/*/LC_MESSAGES/django.mo - -.PHONY: clean -clean: _clean init - diff --git a/bin/console b/bin/console new file mode 100755 index 0000000..d8d530e --- /dev/null +++ b/bin/console @@ -0,0 +1,21 @@ +#!/usr/bin/env php + symfony/mercure-bundle ### +###< symfony/mercure-bundle ### diff --git a/compose.prod.yaml b/compose.prod.yaml index 20fdfb7..f0db05d 100644 --- a/compose.prod.yaml +++ b/compose.prod.yaml @@ -1,5 +1,10 @@ +# Production environment override services: - app: - image: tvdt/app:prod + php: build: - dockerfile: containers/python/Containerfile.prod \ No newline at end of file + context: . + target: frankenphp_prod + environment: + APP_SECRET: ${APP_SECRET} + MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET} + MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET} diff --git a/compose.yaml b/compose.yaml index 346726a..96db15e 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,25 +1,43 @@ services: - app: - build: - dockerfile: containers/python/Containerfile.dev - ports: - - "8000:8000" - + php: + image: ${IMAGES_PREFIX:-}app-php + restart: unless-stopped environment: - DATABASE_URL: postgres://tvdt:tvdt@db:5432/tvdt - DEBUG: true - depends_on: - - db - db: - image: postgres:17.2 - environment: - POSTGRES_PASSWORD: tvdt - POSTGRES_USER: tvdt - POSTGRES_DB: tvdt + SERVER_NAME: ${SERVER_NAME:-localhost}, php:80 + MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} + MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} + # Run "composer require symfony/orm-pack" to install and configure Doctrine ORM + DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8} + # Run "composer require symfony/mercure-bundle" to install and configure the Mercure integration + MERCURE_URL: ${CADDY_MERCURE_URL:-http://php/.well-known/mercure} + MERCURE_PUBLIC_URL: ${CADDY_MERCURE_PUBLIC_URL:-https://${SERVER_NAME:-localhost}/.well-known/mercure} + MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} + # The two next lines can be removed after initial installation + SYMFONY_VERSION: ${SYMFONY_VERSION:-} + STABILITY: ${STABILITY:-stable} volumes: - - data:/var/lib/postgresql/data + - caddy_data:/data + - caddy_config:/config ports: - - "5432:5432" + # HTTP + - target: 80 + published: ${HTTP_PORT:-80} + protocol: tcp + # HTTPS + - target: 443 + published: ${HTTPS_PORT:-443} + protocol: tcp + # HTTP/3 + - target: 443 + published: ${HTTP3_PORT:-443} + protocol: udp + +# Mercure is installed as a Caddy module, prevent the Flex recipe from installing another service +###> symfony/mercure-bundle ### +###< symfony/mercure-bundle ### volumes: - data: \ No newline at end of file + caddy_data: + caddy_config: +###> symfony/mercure-bundle ### +###< symfony/mercure-bundle ### diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..e4248c1 --- /dev/null +++ b/composer.json @@ -0,0 +1,71 @@ +{ + "name": "symfony/skeleton", + "type": "project", + "license": "MIT", + "description": "A minimal Symfony project recommended to create bare bones applications", + "minimum-stability": "stable", + "prefer-stable": true, + "require": { + "php": ">=8.3.15", + "ext-ctype": "*", + "ext-iconv": "*", + "runtime/frankenphp-symfony": "^0.2.0", + "symfony/console": "7.2.*", + "symfony/dotenv": "7.2.*", + "symfony/flex": "^2", + "symfony/framework-bundle": "7.2.*", + "symfony/runtime": "7.2.*", + "symfony/yaml": "7.2.*" + }, + "config": { + "allow-plugins": { + "php-http/discovery": true, + "symfony/flex": true, + "symfony/runtime": true + }, + "bump-after-update": true, + "sort-packages": true + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "App\\Tests\\": "tests/" + } + }, + "replace": { + "symfony/polyfill-ctype": "*", + "symfony/polyfill-iconv": "*", + "symfony/polyfill-php72": "*", + "symfony/polyfill-php73": "*", + "symfony/polyfill-php74": "*", + "symfony/polyfill-php80": "*", + "symfony/polyfill-php81": "*", + "symfony/polyfill-php82": "*" + }, + "scripts": { + "auto-scripts": { + "cache:clear": "symfony-cmd", + "assets:install %PUBLIC_DIR%": "symfony-cmd" + }, + "post-install-cmd": [ + "@auto-scripts" + ], + "post-update-cmd": [ + "@auto-scripts" + ] + }, + "conflict": { + "symfony/symfony": "*" + }, + "extra": { + "symfony": { + "allow-contrib": false, + "require": "7.2.*", + "docker": true + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..86e1015 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2487 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "656bea625358cec88fac936ce826f160", + "packages": [ + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "runtime/frankenphp-symfony", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-runtime/frankenphp-symfony.git", + "reference": "56822c3631d9522a3136a4c33082d006bdfe4bad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-runtime/frankenphp-symfony/zipball/56822c3631d9522a3136a4c33082d006bdfe4bad", + "reference": "56822c3631d9522a3136a4c33082d006bdfe4bad", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/runtime": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Runtime\\FrankenPhpSymfony\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "kevin@dunglas.dev" + } + ], + "description": "FrankenPHP runtime for Symfony", + "support": { + "issues": "https://github.com/php-runtime/frankenphp-symfony/issues", + "source": "https://github.com/php-runtime/frankenphp-symfony/tree/0.2.0" + }, + "funding": [ + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-12-12T12:06:11+00:00" + }, + { + "name": "symfony/cache", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "e7e983596b744c4539f31e79b0350a6cf5878a20" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/e7e983596b744c4539f31e79b0350a6cf5878a20", + "reference": "e7e983596b744c4539f31e79b0350a6cf5878a20", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.4|^7.0" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/dependency-injection": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/var-dumper": "<6.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "classmap": [ + "Traits/ValueWrapper.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:08:50+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", + "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^3.0" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/config", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/bcd3c4adf0144dee5011bb35454728c38adec055", + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^7.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-04T11:36:24+00:00" + }, + { + "name": "symfony/console", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-11T03:49:26+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "a475747af1a1c98272a5471abc35f3da81197c5d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a475747af1a1c98272a5471abc35f3da81197c5d", + "reference": "a475747af1a1c98272a5471abc35f3da81197c5d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^3.5", + "symfony/var-exporter": "^6.4|^7.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.4", + "symfony/finder": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-25T15:45:00+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/dotenv", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dotenv.git", + "reference": "28347a897771d0c28e99b75166dd2689099f3045" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/28347a897771d0c28e99b75166dd2689099f3045", + "reference": "28347a897771d0c28e99b75166dd2689099f3045", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "conflict": { + "symfony/console": "<6.4", + "symfony/process": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Dotenv\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Registers environment variables from a .env file", + "homepage": "https://symfony.com", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "source": "https://github.com/symfony/dotenv/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-27T11:18:42+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "6150b89186573046167796fa5f3f76601d5145f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/6150b89186573046167796fa5f3f76601d5145f8", + "reference": "6150b89186573046167796fa5f3f76601d5145f8", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^6.4|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:50:44+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-25T15:15:23+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-23T06:56:12+00:00" + }, + { + "name": "symfony/flex", + "version": "v2.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/flex.git", + "reference": "92f4fba342161ff36072bd3b8e0b3c6c23160402" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/flex/zipball/92f4fba342161ff36072bd3b8e0b3c6c23160402", + "reference": "92f4fba342161ff36072bd3b8e0b3c6c23160402", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.1", + "php": ">=8.0" + }, + "conflict": { + "composer/semver": "<1.7.2" + }, + "require-dev": { + "composer/composer": "^2.1", + "symfony/dotenv": "^5.4|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/phpunit-bridge": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Symfony\\Flex\\Flex" + }, + "autoload": { + "psr-4": { + "Symfony\\Flex\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien.potencier@gmail.com" + } + ], + "description": "Composer plugin for Symfony", + "support": { + "issues": "https://github.com/symfony/flex/issues", + "source": "https://github.com/symfony/flex/tree/v2.4.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-07T08:51:54+00:00" + }, + { + "name": "symfony/framework-bundle", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "1c630f4697c9bd87b342e8090cc9022071af4d77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/1c630f4697c9bd87b342e8090cc9022071af4d77", + "reference": "1c630f4697c9bd87b342e8090cc9022071af4d77", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.2", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^7.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/filesystem": "^7.1", + "symfony/finder": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^7.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "^6.4|^7.0" + }, + "conflict": { + "doctrine/persistence": "<1.3", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/asset": "<6.4", + "symfony/asset-mapper": "<6.4", + "symfony/clock": "<6.4", + "symfony/console": "<6.4", + "symfony/dom-crawler": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/lock": "<6.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/runtime": "<6.4.13|>=7.0,<7.1.6", + "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4", + "symfony/security-core": "<6.4", + "symfony/security-csrf": "<7.2", + "symfony/serializer": "<7.1", + "symfony/stopwatch": "<6.4", + "symfony/translation": "<6.4", + "symfony/twig-bridge": "<6.4", + "symfony/twig-bundle": "<6.4", + "symfony/validator": "<6.4", + "symfony/web-profiler-bundle": "<6.4", + "symfony/webhook": "<7.2", + "symfony/workflow": "<6.4" + }, + "require-dev": { + "doctrine/persistence": "^1.3|^2|^3", + "dragonmantank/cron-expression": "^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "seld/jsonlint": "^1.10", + "symfony/asset": "^6.4|^7.0", + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/dotenv": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/mailer": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/notifier": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/scheduler": "^6.4.4|^7.0.4", + "symfony/security-bundle": "^6.4|^7.0", + "symfony/semaphore": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/string": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/webhook": "^7.2", + "symfony/workflow": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\FrameworkBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/framework-bundle/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T13:24:01+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e88a66c3997859532bc2ddd6dd8f35aba2711744", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + }, + "require-dev": { + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-13T18:58:46+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d8ae58eecae44c8e66833e76cc50a4ad3c002d97", + "reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^7.1", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-11T12:09:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/routing", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-25T11:08:51+00:00" + }, + { + "name": "symfony/runtime", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/runtime.git", + "reference": "2c350568f3eaccb25fbbbf962bd67cde273121a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/runtime/zipball/2c350568f3eaccb25fbbbf962bd67cde273121a7", + "reference": "2c350568f3eaccb25fbbbf962bd67cde273121a7", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": ">=8.2" + }, + "conflict": { + "symfony/dotenv": "<6.4" + }, + "require-dev": { + "composer/composer": "^2.6", + "symfony/console": "^6.4|^7.0", + "symfony/dotenv": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Symfony\\Component\\Runtime\\Internal\\ComposerPlugin" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Runtime\\": "", + "Symfony\\Runtime\\Symfony\\Component\\": "Internal/" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Enables decoupling PHP applications from global state", + "homepage": "https://symfony.com", + "keywords": [ + "runtime" + ], + "support": { + "source": "https://github.com/symfony/runtime/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-06T11:43:25+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/string", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-13T13:31:26+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-08T15:48:14+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-18T07:58:17+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-23T06:56:12+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=8.3.15", + "ext-ctype": "*", + "ext-iconv": "*" + }, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +} diff --git a/config/bundles.php b/config/bundles.php new file mode 100644 index 0000000..49d3fb6 --- /dev/null +++ b/config/bundles.php @@ -0,0 +1,5 @@ + ['all' => true], +]; diff --git a/config/packages/cache.yaml b/config/packages/cache.yaml new file mode 100644 index 0000000..6899b72 --- /dev/null +++ b/config/packages/cache.yaml @@ -0,0 +1,19 @@ +framework: + cache: + # Unique name of your app: used to compute stable namespaces for cache keys. + #prefix_seed: your_vendor_name/app_name + + # The "app" cache stores to the filesystem by default. + # The data in this cache should persist between deploys. + # Other options include: + + # Redis + #app: cache.adapter.redis + #default_redis_provider: redis://localhost + + # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) + #app: cache.adapter.apcu + + # Namespaced pools use the above "app" backend by default + #pools: + #my.dedicated.cache: null diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml new file mode 100644 index 0000000..7e1ee1f --- /dev/null +++ b/config/packages/framework.yaml @@ -0,0 +1,15 @@ +# see https://symfony.com/doc/current/reference/configuration/framework.html +framework: + secret: '%env(APP_SECRET)%' + + # Note that the session will be started ONLY if you read or write from it. + session: true + + #esi: true + #fragments: true + +when@test: + framework: + test: true + session: + storage_factory_id: session.storage.factory.mock_file diff --git a/config/packages/routing.yaml b/config/packages/routing.yaml new file mode 100644 index 0000000..8166181 --- /dev/null +++ b/config/packages/routing.yaml @@ -0,0 +1,10 @@ +framework: + router: + # Configure how to generate URLs in non-HTTP contexts, such as CLI commands. + # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands + #default_uri: http://localhost + +when@prod: + framework: + router: + strict_requirements: null diff --git a/config/preload.php b/config/preload.php new file mode 100644 index 0000000..5ebcdb2 --- /dev/null +++ b/config/preload.php @@ -0,0 +1,5 @@ +uri query { + replace authorization REDACTED + } + } + } + + root /app/public + encode zstd br gzip + + mercure { + # Transport to use (default to Bolt) + transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db} + # Publisher JWT key + publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG} + # Subscriber JWT key + subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG} + # Allow anonymous subscribers (double-check that it's what you want) + anonymous + # Enable the subscription API (double-check that it's what you want) + subscriptions + # Extra directives + {$MERCURE_EXTRA_DIRECTIVES} + } + + vulcain + + {$CADDY_SERVER_EXTRA_DIRECTIVES} + + # Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics + header ?Permissions-Policy "browsing-topics=()" + + @phpRoute { + not path /.well-known/mercure* + not file {path} + } + rewrite @phpRoute index.php + + @frontController path index.php + php @frontController + + file_server +} diff --git a/frankenphp/conf.d/10-app.ini b/frankenphp/conf.d/10-app.ini new file mode 100644 index 0000000..79a17dd --- /dev/null +++ b/frankenphp/conf.d/10-app.ini @@ -0,0 +1,13 @@ +expose_php = 0 +date.timezone = UTC +apc.enable_cli = 1 +session.use_strict_mode = 1 +zend.detect_unicode = 0 + +; https://symfony.com/doc/current/performance.html +realpath_cache_size = 4096K +realpath_cache_ttl = 600 +opcache.interned_strings_buffer = 16 +opcache.max_accelerated_files = 20000 +opcache.memory_consumption = 256 +opcache.enable_file_override = 1 diff --git a/frankenphp/conf.d/20-app.dev.ini b/frankenphp/conf.d/20-app.dev.ini new file mode 100644 index 0000000..e50f43d --- /dev/null +++ b/frankenphp/conf.d/20-app.dev.ini @@ -0,0 +1,5 @@ +; See https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host +; See https://github.com/docker/for-linux/issues/264 +; The `client_host` below may optionally be replaced with `discover_client_host=yes` +; Add `start_with_request=yes` to start debug session on each request +xdebug.client_host = host.docker.internal diff --git a/frankenphp/conf.d/20-app.prod.ini b/frankenphp/conf.d/20-app.prod.ini new file mode 100644 index 0000000..3bcaa71 --- /dev/null +++ b/frankenphp/conf.d/20-app.prod.ini @@ -0,0 +1,2 @@ +opcache.preload_user = root +opcache.preload = /app/config/preload.php diff --git a/frankenphp/docker-entrypoint.sh b/frankenphp/docker-entrypoint.sh new file mode 100755 index 0000000..c62faad --- /dev/null +++ b/frankenphp/docker-entrypoint.sh @@ -0,0 +1,62 @@ +#!/bin/sh +set -e + +if [ "$1" = 'frankenphp' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then + # Install the project the first time PHP is started + # After the installation, the following block can be deleted + if [ ! -f composer.json ]; then + rm -Rf tmp/ + composer create-project "symfony/skeleton $SYMFONY_VERSION" tmp --stability="$STABILITY" --prefer-dist --no-progress --no-interaction --no-install + + cd tmp + cp -Rp . .. + cd - + rm -Rf tmp/ + + composer require "php:>=$PHP_VERSION" runtime/frankenphp-symfony + composer config --json extra.symfony.docker 'true' + + if grep -q ^DATABASE_URL= .env; then + echo 'To finish the installation please press Ctrl+C to stop Docker Compose and run: docker compose up --build -d --wait' + sleep infinity + fi + fi + + if [ -z "$(ls -A 'vendor/' 2>/dev/null)" ]; then + composer install --prefer-dist --no-progress --no-interaction + fi + + if grep -q ^DATABASE_URL= .env; then + echo 'Waiting for database to be ready...' + ATTEMPTS_LEFT_TO_REACH_DATABASE=60 + until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do + if [ $? -eq 255 ]; then + # If the Doctrine command exits with 255, an unrecoverable error occurred + ATTEMPTS_LEFT_TO_REACH_DATABASE=0 + break + fi + sleep 1 + ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1)) + echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left." + done + + if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then + echo 'The database is not up or not reachable:' + echo "$DATABASE_ERROR" + exit 1 + else + echo 'The database is now ready and reachable' + fi + + if [ "$( find ./migrations -iname '*.php' -print -quit )" ]; then + php bin/console doctrine:migrations:migrate --no-interaction --all-or-nothing + fi + fi + + setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var + setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var + + echo 'PHP app ready!' +fi + +exec docker-php-entrypoint "$@" diff --git a/frankenphp/worker.Caddyfile b/frankenphp/worker.Caddyfile new file mode 100644 index 0000000..d384ae4 --- /dev/null +++ b/frankenphp/worker.Caddyfile @@ -0,0 +1,4 @@ +worker { + file ./public/index.php + env APP_RUNTIME Runtime\FrankenPhpSymfony\Runtime +} diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..9982c21 --- /dev/null +++ b/public/index.php @@ -0,0 +1,9 @@ + Quiz: - try: - return Quiz.objects.get(id=value) - except Quiz.DoesNotExist: - raise ValueError - - def to_url(self, value: Quiz | int) -> str: - return str(value.id) if isinstance(value, Quiz) else value diff --git a/tvdt/backoffice/migrations/__init__.py b/tvdt/backoffice/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tvdt/backoffice/templates/backoffice/base.html b/tvdt/backoffice/templates/backoffice/base.html deleted file mode 100644 index 7765e22..0000000 --- a/tvdt/backoffice/templates/backoffice/base.html +++ /dev/null @@ -1,36 +0,0 @@ -{% load i18n %} -{% load static %} - - - - - - - - - {% block title %} - {% translate "Tijd voor de test" %} - {% endblock title %} - - - - {% block nav %} - {% include "backoffice/nav.html" %} - {% endblock nav %} -
-
- {% include "messages.html" %} - {% block body %} - {% endblock body %} -
-
- - {% block script %} - {% endblock script %} - diff --git a/tvdt/backoffice/templates/backoffice/index.html b/tvdt/backoffice/templates/backoffice/index.html deleted file mode 100644 index d61e80b..0000000 --- a/tvdt/backoffice/templates/backoffice/index.html +++ /dev/null @@ -1,45 +0,0 @@ -{% extends "backoffice/base.html" %} -{% load i18n %} -{% block body %} -

{% translate "Your Seasons" %}

- - - - - - - - - - - - {% for season in seasons %} - - - - - - - - {% empty %} - EMPTY - {% endfor %} - -
{% translate "Name" %}{% translate "Active Quiz" %}{% translate "Season Code" %}{% translate "Preregister?" %}{% translate "Manage" %}
{{ season.name }} - {% if season.active_quiz %} - {{ season.active_quiz.name }} - {% else %} - {% translate "No active quiz" %} - {% endif %} - - {{ season.season_code }} - - - - {% translate "Manage" %} -
-{% endblock body %} diff --git a/tvdt/backoffice/templates/backoffice/nav.html b/tvdt/backoffice/templates/backoffice/nav.html deleted file mode 100644 index 6f03737..0000000 --- a/tvdt/backoffice/templates/backoffice/nav.html +++ /dev/null @@ -1,51 +0,0 @@ -{% load i18n %} - diff --git a/tvdt/backoffice/templates/backoffice/quiz.html b/tvdt/backoffice/templates/backoffice/quiz.html deleted file mode 100644 index e880f0e..0000000 --- a/tvdt/backoffice/templates/backoffice/quiz.html +++ /dev/null @@ -1,92 +0,0 @@ -{% extends "backoffice/base.html" %} -{% load i18n %} -{% block body %} -

-

{% translate "Quiz" %}: {{ quiz.season.name }} - {{ quiz.name }}

-

-
-

-

{% translate "Questions" %}

-

-
- {% for question in quiz.questions.all %} -
-

- -

-
-
- {% for answer in question.answers.all %} -
  • {{ answer.text }}
  • - {% empty %} - {% translate "There are no answers for this question" %} - {% endfor %} -
    -
    -
    - {% empty %} - EMPTY - {% endfor %} -
    -
    -
    -

    -

    {% translate "Score" %}

    -

    - -

    {% translate "Number of dropouts:" %} {{ quiz.dropouts }}

    - - - - - - - - - - - - {% with result=quiz.get_score %} - {% for candidate in result %} - - - - - - - - {% empty %} - {% endfor %} - -
    {% translate "Candidate" %}{% translate "Correct Answers" %}{% translate "Corrections" %}{% translate "Score" %}{% translate "Time" %}
    {{ candidate.name }}{{ candidate.correct }}{{ candidate.corrections }}{{ candidate.score }}{{ candidate.time }}
    - {% endwith %} -
    -{% endblock body %} -{% block script %} - -{% endblock script %} diff --git a/tvdt/backoffice/templates/backoffice/season.html b/tvdt/backoffice/templates/backoffice/season.html deleted file mode 100644 index 9b824a9..0000000 --- a/tvdt/backoffice/templates/backoffice/season.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "backoffice/base.html" %} -{% load i18n %} -{% block body %} -

    -

    {% translate "Season" %}: {{ season.name }}

    -

    -
    -
    -

    {% translate "Quizzes" %}

    -
    - {% for quiz in season.quizzes.all %} - {{ quiz.name }} - {% empty %} - {% endfor %} -
    -
    -
    -

    {% translate "Candidates" %}

    - -
    -
    -{% endblock body %} diff --git a/tvdt/backoffice/tests.py b/tvdt/backoffice/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/tvdt/backoffice/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/tvdt/backoffice/urls.py b/tvdt/backoffice/urls.py deleted file mode 100644 index 1190c97..0000000 --- a/tvdt/backoffice/urls.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.contrib.auth.decorators import login_required -from django.urls import path, register_converter - -from tvdt.converters import SeasonCodeConverter - -from .converters import QuizConverter -from .views import BackofficeIndexView, QuizView, SeasonView - -register_converter(SeasonCodeConverter, "season") -register_converter(QuizConverter, "quiz") - -app_name = "backoffice" -urlpatterns = [ - path("", login_required(BackofficeIndexView.as_view()), name="index"), - path( - "/", - login_required(SeasonView.as_view()), - name="season", - ), - path("/", login_required(QuizView.as_view()), name="quiz"), -] diff --git a/tvdt/backoffice/views/__init__.py b/tvdt/backoffice/views/__init__.py deleted file mode 100644 index 6bcb9a9..0000000 --- a/tvdt/backoffice/views/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .home import BackofficeIndexView -from .quiz import QuizView -from .season import SeasonView diff --git a/tvdt/backoffice/views/home.py b/tvdt/backoffice/views/home.py deleted file mode 100644 index 23f8f51..0000000 --- a/tvdt/backoffice/views/home.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.http import HttpRequest -from django.views.generic import TemplateView - - -class BackofficeIndexView(TemplateView): - template_name = "backoffice/index.html" - - def get(self, request: HttpRequest, *args, **kwargs): - seasons = request.user.seasons.all() - return self.render_to_response({"seasons": seasons}) diff --git a/tvdt/backoffice/views/quiz.py b/tvdt/backoffice/views/quiz.py deleted file mode 100644 index 7144121..0000000 --- a/tvdt/backoffice/views/quiz.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.http import HttpRequest -from django.views import View -from django.views.generic.base import TemplateResponseMixin - -from quiz.models import Quiz - - -class QuizView(View, TemplateResponseMixin): - template_name = "backoffice/quiz.html" - - def get(self, request: HttpRequest, quiz: Quiz, *args, **kwargs): - - return self.render_to_response({"quiz": quiz}) diff --git a/tvdt/backoffice/views/season.py b/tvdt/backoffice/views/season.py deleted file mode 100644 index de3c0e9..0000000 --- a/tvdt/backoffice/views/season.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.http import HttpRequest -from django.views import View -from django.views.generic.base import TemplateResponseMixin - -from quiz.models import Season - - -class SeasonView(View, TemplateResponseMixin): - template_name = "backoffice/season.html" - - def get(self, request: HttpRequest, season: Season, *args, **kwargs): - return self.render_to_response({"season": season}) diff --git a/tvdt/locale/nl/LC_MESSAGES/django.po b/tvdt/locale/nl/LC_MESSAGES/django.po deleted file mode 100644 index b06f02e..0000000 --- a/tvdt/locale/nl/LC_MESSAGES/django.po +++ /dev/null @@ -1,122 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-11 23:22+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: backoffice/templates/backoffice/base.html:18 -msgid "Tijd voor de test" -msgstr "Tijd voor de test" - -#: backoffice/templates/backoffice/index.html:4 -msgid "Your Seasons" -msgstr "Jouw seizoenen" - -#: backoffice/templates/backoffice/index.html:8 -msgid "Name" -msgstr "Naam" - -#: backoffice/templates/backoffice/index.html:9 -msgid "Active Quiz" -msgstr "Actieve test" - -#: backoffice/templates/backoffice/index.html:10 -msgid "Season Code" -msgstr "Seizoenscode" - -#: backoffice/templates/backoffice/index.html:11 -msgid "Preregister?" -msgstr "Voorregistreren?" - -#: backoffice/templates/backoffice/index.html:12 -#: backoffice/templates/backoffice/index.html:37 -msgid "Manage" -msgstr "Beheer" - -#: backoffice/templates/backoffice/index.html:23 -msgid "No active quiz" -msgstr "Geen actieve test" - -#: backoffice/templates/backoffice/quiz.html:5 -msgid "Quiz" -msgstr "Test" - -#: backoffice/templates/backoffice/quiz.html:9 -msgid "Questions" -msgstr "Vragen" - -#: backoffice/templates/backoffice/quiz.html:36 -msgid "There are no answers for this question" -msgstr "Er zijn geen antwoorden voor deze vraag" - -#: backoffice/templates/backoffice/quiz.html:48 -#: backoffice/templates/backoffice/quiz.html:66 -msgid "Score" -msgstr "Score" - -#: backoffice/templates/backoffice/quiz.html:52 -msgid "Start Elimination" -msgstr "Start eliminatie" - -#: backoffice/templates/backoffice/quiz.html:55 -msgid "Prepare Custom Elimination" -msgstr "Aangepaste eliminatie voorbereiden" - -#: backoffice/templates/backoffice/quiz.html:56 -msgid "Load Prepared Elimination" -msgstr "Aangepaste eliminatie inladen" - -#: backoffice/templates/backoffice/quiz.html:59 -msgid "Number of dropouts:" -msgstr "Aantal afvallers:" - -#: backoffice/templates/backoffice/quiz.html:63 -msgid "Candidate" -msgstr "Kandidaat" - -#: backoffice/templates/backoffice/quiz.html:64 -msgid "Correct Answers" -msgstr "Goede antwoorden" - -#: backoffice/templates/backoffice/quiz.html:65 -msgid "Corrections" -msgstr "Jokers" - -#: backoffice/templates/backoffice/quiz.html:67 -msgid "Time" -msgstr "Tijd" - -#: backoffice/templates/backoffice/season.html:5 -msgid "Season" -msgstr "Seizoen" - -#: backoffice/templates/backoffice/season.html:9 - -msgid "Quizzes" -msgstr "Tests" - -#: backoffice/templates/backoffice/season.html:21 -msgid "Candidates" -msgstr "Kandidaten" - -#: tvdt/settings.py:173 -msgid "Dutch" -msgstr "Nederlands" - -#: tvdt/settings.py:173 -msgid "English" -msgstr "Engels" diff --git a/tvdt/manage.py b/tvdt/manage.py deleted file mode 100755 index 1991df3..0000000 --- a/tvdt/manage.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" -import os -import sys - - -def main() -> None: - """Run administrative tasks.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tvdt.settings") - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == "__main__": - main() diff --git a/tvdt/poetry.lock b/tvdt/poetry.lock deleted file mode 100644 index dbce903..0000000 --- a/tvdt/poetry.lock +++ /dev/null @@ -1,1163 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. - -[[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 = "black" -version = "24.10.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.9" -files = [ - {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, - {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, - {file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"}, - {file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"}, - {file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"}, - {file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"}, - {file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"}, - {file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"}, - {file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"}, - {file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"}, - {file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"}, - {file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"}, - {file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"}, - {file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"}, - {file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"}, - {file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"}, - {file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"}, - {file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"}, - {file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"}, - {file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"}, - {file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"}, - {file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.10)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -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.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "crispy-bootstrap5" -version = "2024.10" -description = "Bootstrap5 template pack for django-crispy-forms" -optional = false -python-versions = ">=3.8" -files = [ - {file = "crispy_bootstrap5-2024.10-py3-none-any.whl", hash = "sha256:59e91dac5e45a8c954af3fbcaa6804cd5aef4402f027af2f99a352b096c4016f"}, - {file = "crispy_bootstrap5-2024.10.tar.gz", hash = "sha256:55b442fe675dd95ad280123c7fe464f454186e90b8e5642e751f436c87627c44"}, -] - -[package.dependencies] -django = ">=4.2" -django-crispy-forms = ">=2.3" - -[package.extras] -test = ["pytest", "pytest-django"] - -[[package]] -name = "cryptography" -version = "44.0.0" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -optional = false -python-versions = "!=3.9.0,!=3.9.1,>=3.7" -files = [ - {file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, - {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, - {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f"}, - {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb"}, - {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b"}, - {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543"}, - {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:60eb32934076fa07e4316b7b2742fa52cbb190b42c2df2863dbc4230a0a9b385"}, - {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e"}, - {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e"}, - {file = "cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053"}, - {file = "cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd"}, - {file = "cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591"}, - {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7"}, - {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc"}, - {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289"}, - {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7"}, - {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c"}, - {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9abcc2e083cbe8dde89124a47e5e53ec38751f0d7dfd36801008f316a127d7ba"}, - {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64"}, - {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285"}, - {file = "cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417"}, - {file = "cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede"}, - {file = "cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731"}, - {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4"}, - {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756"}, - {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c"}, - {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa"}, - {file = "cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c"}, - {file = "cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02"}, -] - -[package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] -docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] -nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] -pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] -sdist = ["build (>=1.0.0)"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi (>=2024)", "cryptography-vectors (==44.0.0)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] -test-randomorder = ["pytest-randomly"] - -[[package]] -name = "cssbeautifier" -version = "1.15.1" -description = "CSS unobfuscator and beautifier." -optional = false -python-versions = "*" -files = [ - {file = "cssbeautifier-1.15.1.tar.gz", hash = "sha256:9f7064362aedd559c55eeecf6b6bed65e05f33488dcbe39044f0403c26e1c006"}, -] - -[package.dependencies] -editorconfig = ">=0.12.2" -jsbeautifier = "*" -six = ">=1.13.0" - -[[package]] -name = "dj-database-url" -version = "2.3.0" -description = "Use Database URLs in your Django Application." -optional = false -python-versions = "*" -files = [ - {file = "dj_database_url-2.3.0-py3-none-any.whl", hash = "sha256:bb0d414ba0ac5cd62773ec7f86f8cc378a9dbb00a80884c2fc08cc570452521e"}, - {file = "dj_database_url-2.3.0.tar.gz", hash = "sha256:ae52e8e634186b57e5a45e445da5dc407a819c2ceed8a53d1fac004cc5288787"}, -] - -[package.dependencies] -Django = ">=4.2" -typing_extensions = ">=3.10.0.0" - -[[package]] -name = "dj-email-url" -version = "1.0.6" -description = "Use an URL to configure email backend settings in your Django Application." -optional = false -python-versions = "*" -files = [ - {file = "dj-email-url-1.0.6.tar.gz", hash = "sha256:55ffe3329e48f54f8a75aa36ece08f365e09d61f8a209773ef09a1d4760e699a"}, - {file = "dj_email_url-1.0.6-py2.py3-none-any.whl", hash = "sha256:cbd08327fbb08b104eac160fb4703f375532e4c0243eb230f5b960daee7a96db"}, -] - -[[package]] -name = "django" -version = "5.1.3" -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.1.3-py3-none-any.whl", hash = "sha256:8b38a9a12da3ae00cb0ba72da985ec4b14de6345046b1e174b1fd7254398f818"}, - {file = "Django-5.1.3.tar.gz", hash = "sha256:c0fa0e619c39325a169208caef234f90baa925227032ad3f44842ba14d75234a"}, -] - -[package.dependencies] -asgiref = ">=3.8.1,<4" -sqlparse = ">=0.3.1" -tzdata = {version = "*", markers = "sys_platform == \"win32\""} - -[package.extras] -argon2 = ["argon2-cffi (>=19.1.0)"] -bcrypt = ["bcrypt"] - -[[package]] -name = "django-allauth" -version = "65.2.0" -description = "Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication." -optional = false -python-versions = ">=3.8" -files = [ - {file = "django_allauth-65.2.0.tar.gz", hash = "sha256:0a3d7baf7beefd6fe8027316302c26ece7433cf4331a3b245d15fc9a7be68b6f"}, -] - -[package.dependencies] -asgiref = ">=3.8.1" -Django = ">=4.2.16" -pyjwt = {version = ">=1.7", extras = ["crypto"], optional = true, markers = "extra == \"socialaccount\""} -requests = {version = ">=2.0.0", optional = true, markers = "extra == \"socialaccount\""} -requests-oauthlib = {version = ">=0.3.0", optional = true, markers = "extra == \"socialaccount\""} - -[package.extras] -mfa = ["fido2 (>=1.1.2)", "qrcode (>=7.0.0)"] -openid = ["python3-openid (>=3.0.8)"] -saml = ["python3-saml (>=1.15.0,<2.0.0)"] -socialaccount = ["pyjwt[crypto] (>=1.7)", "requests (>=2.0.0)", "requests-oauthlib (>=0.3.0)"] -steam = ["python3-openid (>=3.0.8)"] - -[[package]] -name = "django-cache-url" -version = "3.4.5" -description = "Use Cache URLs in your Django application." -optional = false -python-versions = "*" -files = [ - {file = "django-cache-url-3.4.5.tar.gz", hash = "sha256:eb9fb194717524348c95cad9905b70b647452741c1d9e481fac6d2125f0ad917"}, - {file = "django_cache_url-3.4.5-py2.py3-none-any.whl", hash = "sha256:5f350759978483ab85dc0e3e17b3d53eed3394a28148f6bf0f53d11d0feb5b3c"}, -] - -[[package]] -name = "django-crispy-forms" -version = "2.3" -description = "Best way to have Django DRY forms" -optional = false -python-versions = ">=3.8" -files = [ - {file = "django_crispy_forms-2.3-py3-none-any.whl", hash = "sha256:efc4c31e5202bbec6af70d383a35e12fc80ea769d464fb0e7fe21768bb138a20"}, - {file = "django_crispy_forms-2.3.tar.gz", hash = "sha256:2db17ae08527201be1273f0df789e5f92819e23dd28fec69cffba7f3762e1a38"}, -] - -[package.dependencies] -django = ">=4.2" - -[[package]] -name = "django-stubs" -version = "5.1.1" -description = "Mypy stubs for Django" -optional = false -python-versions = ">=3.8" -files = [ - {file = "django_stubs-5.1.1-py3-none-any.whl", hash = "sha256:c4dc64260bd72e6d32b9e536e8dd0d9247922f0271f82d1d5132a18f24b388ac"}, - {file = "django_stubs-5.1.1.tar.gz", hash = "sha256:126d354bbdff4906c4e93e6361197f6fbfb6231c3df6def85a291dae6f9f577b"}, -] - -[package.dependencies] -asgiref = "*" -django = "*" -django-stubs-ext = ">=5.1.1" -mypy = {version = ">=1.12,<1.14", optional = true, markers = "extra == \"compatible-mypy\""} -types-PyYAML = "*" -typing-extensions = ">=4.11.0" - -[package.extras] -compatible-mypy = ["mypy (>=1.12,<1.14)"] -oracle = ["oracledb"] -redis = ["redis"] - -[[package]] -name = "django-stubs-ext" -version = "5.1.1" -description = "Monkey-patching and extensions for django-stubs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "django_stubs_ext-5.1.1-py3-none-any.whl", hash = "sha256:3907f99e178c93323e2ce908aef8352adb8c047605161f8d9e5e7b4efb5a6a9c"}, - {file = "django_stubs_ext-5.1.1.tar.gz", hash = "sha256:db7364e4f50ae7e5360993dbd58a3a57ea4b2e7e5bab0fbd525ccdb3e7975d1c"}, -] - -[package.dependencies] -django = "*" -typing-extensions = "*" - -[[package]] -name = "djlint" -version = "1.36.3" -description = "HTML Template Linter and Formatter" -optional = false -python-versions = ">=3.9" -files = [ - {file = "djlint-1.36.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ae7c620b58e16d6bf003bd7de3f71376a7a3daa79dc02e77f3726d5a75243f2"}, - {file = "djlint-1.36.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e155ce0970d4a28d0a2e9f2e106733a2ad05910eee90e056b056d48049e4a97b"}, - {file = "djlint-1.36.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e8bb0406e60cc696806aa6226df137618f3889c72f2dbdfa76c908c99151579"}, - {file = "djlint-1.36.3-cp310-cp310-win_amd64.whl", hash = "sha256:76d32faf988ad58ef2e7a11d04046fc984b98391761bf1b61f9a6044da53d414"}, - {file = "djlint-1.36.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:32f7a5834000fff22e94d1d35f95aaf2e06f2af2cae18af0ed2a4e215d60e730"}, - {file = "djlint-1.36.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3eb1b9c0be499e63e8822a051e7e55f188ff1ab8172a85d338a8ae21c872060e"}, - {file = "djlint-1.36.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c2e0dd1f26eb472b8c84eb70d6482877b6497a1fd031d7534864088f016d5ea"}, - {file = "djlint-1.36.3-cp311-cp311-win_amd64.whl", hash = "sha256:a06b531ab9d049c46ad4d2365d1857004a1a9dd0c23c8eae94aa0d233c6ec00d"}, - {file = "djlint-1.36.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e66361a865e5e5a4bbcb40f56af7f256fd02cbf9d48b763a40172749cc294084"}, - {file = "djlint-1.36.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:36e102b80d83e9ac2e6be9a9ded32fb925945f6dbc7a7156e4415de1b0aa0dba"}, - {file = "djlint-1.36.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ac4b7370d80bd82281e57a470de8923ac494ffb571b89d8787cef57c738c69a"}, - {file = "djlint-1.36.3-cp312-cp312-win_amd64.whl", hash = "sha256:107cc56bbef13d60cc0ae774a4d52881bf98e37c02412e573827a3e549217e3a"}, - {file = "djlint-1.36.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2a9f51971d6e63c41ea9b3831c928e1f21ae6fe57e87a3452cfe672d10232433"}, - {file = "djlint-1.36.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:080c98714b55d8f0fef5c42beaee8247ebb2e3d46b0936473bd6c47808bb6302"}, - {file = "djlint-1.36.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f65a80e0b5cb13d357ea51ca6570b34c2d9d18974c1e57142de760ea27d49ed0"}, - {file = "djlint-1.36.3-cp313-cp313-win_amd64.whl", hash = "sha256:95ef6b67ef7f2b90d9434bba37d572031079001dc8524add85c00ef0386bda1e"}, - {file = "djlint-1.36.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e2317a32094d525bc41cd11c8dc064bf38d1b442c99cc3f7c4a2616b5e6ce6e"}, - {file = "djlint-1.36.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e82266c28793cd15f97b93535d72bfbc77306eaaf6b210dd90910383a814ee6c"}, - {file = "djlint-1.36.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01b2101c2d1b079e8d545e6d9d03487fcca14d2371e44cbfdedee15b0bf4567c"}, - {file = "djlint-1.36.3-cp39-cp39-win_amd64.whl", hash = "sha256:15cde63ef28beb5194ff4137883025f125676ece1b574b64a3e1c6daed734639"}, - {file = "djlint-1.36.3-py3-none-any.whl", hash = "sha256:0c05cd5b76785de2c41a2420c06ffd112800bfc0f9c0f399cc7cea7c42557f4c"}, - {file = "djlint-1.36.3.tar.gz", hash = "sha256:d85735da34bc7ac93ad8ef9b4822cc2a23d5f0ce33f25438737b8dca1d404f78"}, -] - -[package.dependencies] -click = ">=8.0.1" -colorama = ">=0.4.4" -cssbeautifier = ">=1.14.4" -jsbeautifier = ">=1.14.4" -json5 = ">=0.9.11" -pathspec = ">=0.12" -pyyaml = ">=6" -regex = ">=2023" -tqdm = ">=4.62.2" - -[[package]] -name = "editorconfig" -version = "0.12.4" -description = "EditorConfig File Locator and Interpreter for Python" -optional = false -python-versions = "*" -files = [ - {file = "EditorConfig-0.12.4.tar.gz", hash = "sha256:24857fa1793917dd9ccf0c7810a07e05404ce9b823521c7dce22a4fb5d125f80"}, -] - -[[package]] -name = "environs" -version = "11.2.1" -description = "simplified environment variable parsing" -optional = false -python-versions = ">=3.8" -files = [ - {file = "environs-11.2.1-py3-none-any.whl", hash = "sha256:9d2080cf25807a26fc0d4301e2d7b62c64fbf547540f21e3a30cc02bc5fbe948"}, - {file = "environs-11.2.1.tar.gz", hash = "sha256:e068ae3174cef52ba4b95ead22e639056a02465f616e62323e04ae08e86a75a4"}, -] - -[package.dependencies] -dj-database-url = {version = "*", optional = true, markers = "extra == \"django\""} -dj-email-url = {version = "*", optional = true, markers = "extra == \"django\""} -django-cache-url = {version = "*", optional = true, markers = "extra == \"django\""} -marshmallow = ">=3.13.0" -python-dotenv = "*" - -[package.extras] -dev = ["environs[tests]", "pre-commit (>=3.5,<5.0)", "tox"] -django = ["dj-database-url", "dj-email-url", "django-cache-url"] -tests = ["environs[django]", "pytest"] - -[[package]] -name = "gunicorn" -version = "23.0.0" -description = "WSGI HTTP Server for UNIX" -optional = false -python-versions = ">=3.7" -files = [ - {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, - {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, -] - -[package.dependencies] -packaging = "*" - -[package.extras] -eventlet = ["eventlet (>=0.24.1,!=0.36.0)"] -gevent = ["gevent (>=1.4.0)"] -setproctitle = ["setproctitle"] -testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"] -tornado = ["tornado (>=0.2)"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "isort" -version = "5.13.2" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, -] - -[package.extras] -colors = ["colorama (>=0.4.6)"] - -[[package]] -name = "jsbeautifier" -version = "1.15.1" -description = "JavaScript unobfuscator and beautifier." -optional = false -python-versions = "*" -files = [ - {file = "jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24"}, -] - -[package.dependencies] -editorconfig = ">=0.12.2" -six = ">=1.13.0" - -[[package]] -name = "json5" -version = "0.10.0" -description = "A Python implementation of the JSON5 data format." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa"}, - {file = "json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559"}, -] - -[package.extras] -dev = ["build (==1.2.2.post1)", "coverage (==7.5.3)", "mypy (==1.13.0)", "pip (==24.3.1)", "pylint (==3.2.3)", "ruff (==0.7.3)", "twine (==5.1.1)", "uv (==0.5.1)"] - -[[package]] -name = "marshmallow" -version = "3.23.1" -description = "A lightweight library for converting complex datatypes to and from native Python datatypes." -optional = false -python-versions = ">=3.9" -files = [ - {file = "marshmallow-3.23.1-py3-none-any.whl", hash = "sha256:fece2eb2c941180ea1b7fcbd4a83c51bfdd50093fdd3ad2585ee5e1df2508491"}, - {file = "marshmallow-3.23.1.tar.gz", hash = "sha256:3a8dfda6edd8dcdbf216c0ede1d1e78d230a6dc9c5a088f58c4083b974a0d468"}, -] - -[package.dependencies] -packaging = ">=17.0" - -[package.extras] -dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"] -tests = ["pytest", "simplejson"] - -[[package]] -name = "mypy" -version = "1.13.0" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, - {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, - {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, - {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, - {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, - {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, - {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, - {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, - {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, - {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, - {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, - {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, - {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, - {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, - {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, - {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, - {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, - {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, - {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, - {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, - {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, - {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, -] - -[package.dependencies] -mypy-extensions = ">=1.0.0" -typing-extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -faster-cache = ["orjson"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "oauthlib" -version = "3.2.2" -description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -optional = false -python-versions = ">=3.6" -files = [ - {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, - {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, -] - -[package.extras] -rsa = ["cryptography (>=3.0.0)"] -signals = ["blinker (>=1.4.0)"] -signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] - -[[package]] -name = "packaging" -version = "24.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "psycopg2" -version = "2.9.10" -description = "psycopg2 - Python-PostgreSQL Database Adapter" -optional = false -python-versions = ">=3.8" -files = [ - {file = "psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716"}, - {file = "psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a"}, - {file = "psycopg2-2.9.10-cp311-cp311-win32.whl", hash = "sha256:47c4f9875125344f4c2b870e41b6aad585901318068acd01de93f3677a6522c2"}, - {file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"}, - {file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"}, - {file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"}, - {file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"}, - {file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"}, - {file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"}, -] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pyjwt" -version = "2.10.1" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, - {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, -] - -[package.dependencies] -cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - -[[package]] -name = "python-dotenv" -version = "1.0.1" -description = "Read key-value pairs from a .env file and set them as environment variables" -optional = false -python-versions = ">=3.8" -files = [ - {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, - {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, -] - -[package.extras] -cli = ["click (>=5.0)"] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "regex" -version = "2024.11.6" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.8" -files = [ - {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, - {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, - {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, - {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, - {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, - {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, - {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, - {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, - {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, - {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, - {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, - {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, - {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, - {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, - {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, - {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, - {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, - {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, - {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, - {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, - {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, - {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, - {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, - {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, - {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, - {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, - {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, - {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, - {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, - {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, - {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[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 = "requests-oauthlib" -version = "2.0.0" -description = "OAuthlib authentication support for Requests." -optional = false -python-versions = ">=3.4" -files = [ - {file = "requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"}, - {file = "requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36"}, -] - -[package.dependencies] -oauthlib = ">=3.0.0" -requests = ">=2.0.0" - -[package.extras] -rsa = ["oauthlib[signedtoken] (>=3.0.0)"] - -[[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 = "sqlparse" -version = "0.5.2" -description = "A non-validating SQL parser." -optional = false -python-versions = ">=3.8" -files = [ - {file = "sqlparse-0.5.2-py3-none-any.whl", hash = "sha256:e99bc85c78160918c3e1d9230834ab8d80fc06c59d03f8db2618f65f65dda55e"}, - {file = "sqlparse-0.5.2.tar.gz", hash = "sha256:9e37b35e16d1cc652a2545f0997c1deb23ea28fa1f3eefe609eee3063c3b105f"}, -] - -[package.extras] -dev = ["build", "hatch"] -doc = ["sphinx"] - -[[package]] -name = "tqdm" -version = "4.67.1" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, - {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] -discord = ["requests"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "types-pyyaml" -version = "6.0.12.20240917" -description = "Typing stubs for PyYAML" -optional = false -python-versions = ">=3.8" -files = [ - {file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"}, - {file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "tzdata" -version = "2024.2" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, - {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, -] - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[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)"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.12" -content-hash = "b6a1e4f297c97ec3cfa8b4e89d67034e06f3f1a67a72006f1b438770781d43d2" diff --git a/tvdt/pyproject.toml b/tvdt/pyproject.toml deleted file mode 100644 index 5e7c24d..0000000 --- a/tvdt/pyproject.toml +++ /dev/null @@ -1,34 +0,0 @@ -[tool.poetry] -name = "tvdt" -package-mode = false - -[tool.poetry.dependencies] -python = "^3.12" -Django = "^5.1.2" -django-crispy-forms = "^2.3" -crispy-bootstrap5 = "^2024.10" -django-allauth = {extras = ["socialaccount"], version = "^65.2.0"} -django-stubs = {extras = ["compatible-mypy"], version = "^5.1.0"} -environs = {extras = ["django"], version = "^11.2.1"} -psycopg2 = "^2.9.10" - -[tool.poetry.group.dev.dependencies] -mypy = "^1.11.0" -black = "^24.10.0" -isort = "^5.13.2" -djlint = "^1.36.3" - -[tool.poetry.group.prod.dependencies] -gunicorn = "^23.0.0" - -[tool.isort] -profile = "black" - -[tool.mypy] -plugins = ["mypy_django_plugin.main"] - -[tool.django-stubs] -django_settings_module = "tvdt.settings" - -[tool.djlint] -profile="django" diff --git a/tvdt/quiz/__init__.py b/tvdt/quiz/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tvdt/quiz/admin.py b/tvdt/quiz/admin.py deleted file mode 100644 index 2057a5d..0000000 --- a/tvdt/quiz/admin.py +++ /dev/null @@ -1,50 +0,0 @@ -from django.contrib import admin - -from .models import Answer, Candidate, Correction, GivenAnswer, Question, Quiz, Season - - -class CandidatesAdmin(admin.StackedInline): - model = Candidate - extra = 1 - - -@admin.register(Season) -class SeasonAdmin(admin.ModelAdmin): - inlines = [CandidatesAdmin] - - -class QuestionInline(admin.TabularInline): - model = Question - extra = 0 - - -@admin.register(Quiz) -class QuizAdmin(admin.ModelAdmin): - inlines = [QuestionInline] - - -class AnswerInline(admin.TabularInline): - model = Answer - extra = 0 - - -@admin.register(Question) -class QuestionAdmin(admin.ModelAdmin): - list_display = ["question", "quiz__season__name", "quiz__name", "_order"] - ordering = ["quiz__season", "quiz", "_order"] - inlines = [AnswerInline] - - -@admin.register(Candidate) -class CandidateAdmin(admin.ModelAdmin): - pass - - -@admin.register(GivenAnswer) -class GivenAnswerAdmin(admin.ModelAdmin): - pass - - -@admin.register(Correction) -class CorrextionAdmin(admin.ModelAdmin): - pass diff --git a/tvdt/quiz/apps.py b/tvdt/quiz/apps.py deleted file mode 100644 index 59730f9..0000000 --- a/tvdt/quiz/apps.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.apps import AppConfig -from django.utils.translation import gettext_lazy as _ - - -class QuizConfig(AppConfig): - default_auto_field = "django.db.models.BigAutoField" - name = "quiz" - verbose_name = _("quiz") diff --git a/tvdt/quiz/context_processors.py b/tvdt/quiz/context_processors.py deleted file mode 100644 index 6c84987..0000000 --- a/tvdt/quiz/context_processors.py +++ /dev/null @@ -1,2 +0,0 @@ -def get_theme(request) -> dict: - return {"theme": "wie_is_de_mol"} diff --git a/tvdt/quiz/converters.py b/tvdt/quiz/converters.py deleted file mode 100644 index ef47a91..0000000 --- a/tvdt/quiz/converters.py +++ /dev/null @@ -1,28 +0,0 @@ -import base64 -import binascii - -from .models import Candidate, Season - - -class CandidateConverter: - regex = r"[A-Za-z\d]{5}\/[\w\-=]+" - - def to_python(self, value: str) -> Candidate: - season_code, base64_name = value.split("/") - - try: - name = base64.urlsafe_b64decode(base64_name).decode() - except binascii.Error: - raise ValueError - - try: - season = Season.objects.get(season_code=season_code) - - candidate = Candidate.objects.get(name=name, season=season) - return candidate - except [Season.DoesNotExist, Candidate.DoesNotExist]: - raise ValueError - - def to_url(self, candidate: Candidate) -> str: - base64_candidate = base64.urlsafe_b64encode(candidate.name.encode()).decode() - return f"{candidate.season.season_code}/{base64_candidate}" diff --git a/tvdt/quiz/fixtures/krtek.json b/tvdt/quiz/fixtures/krtek.json deleted file mode 100644 index 4360c3b..0000000 --- a/tvdt/quiz/fixtures/krtek.json +++ /dev/null @@ -1,2198 +0,0 @@ -[ -{ - "model": "quiz.answer", - "pk": 1, - "fields": { - "text": "Man", - "question": 1, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 2, - "fields": { - "text": "Vrouw", - "question": 1, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 3, - "fields": { - "text": "Geen", - "question": 2, - "is_right_answer": true, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 4, - "fields": { - "text": "1", - "question": 2, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 5, - "fields": { - "text": "2", - "question": 2, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 6, - "fields": { - "text": "Geen", - "question": 3, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 7, - "fields": { - "text": "Diens eigen verjaardag", - "question": 3, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 8, - "fields": { - "text": "Koningsdag", - "question": 3, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 9, - "fields": { - "text": "Kerst", - "question": 3, - "is_right_answer": true, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 10, - "fields": { - "text": "Oud en nieuw", - "question": 3, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 11, - "fields": { - "text": "Met de auto", - "question": 4, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 12, - "fields": { - "text": "Met het OV", - "question": 4, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 13, - "fields": { - "text": "Claudia", - "question": 5, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 14, - "fields": { - "text": "Eelco", - "question": 5, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 15, - "fields": { - "text": "Elise", - "question": 5, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 16, - "fields": { - "text": "Gert-Jan", - "question": 5, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 17, - "fields": { - "text": "Iris", - "question": 5, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 18, - "fields": { - "text": "Jari", - "question": 5, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 19, - "fields": { - "text": "Laura", - "question": 5, - "is_right_answer": false, - "_order": 6, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 20, - "fields": { - "text": "Lotte", - "question": 5, - "is_right_answer": false, - "_order": 7, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 21, - "fields": { - "text": "Myrthe", - "question": 5, - "is_right_answer": false, - "_order": 8, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 22, - "fields": { - "text": "Remy", - "question": 5, - "is_right_answer": false, - "_order": 9, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 23, - "fields": { - "text": "Robbert", - "question": 5, - "is_right_answer": false, - "_order": 10, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 24, - "fields": { - "text": "Tom", - "question": 5, - "is_right_answer": true, - "_order": 11, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 25, - "fields": { - "text": "Geef je vader een knuffel.", - "question": 6, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 26, - "fields": { - "text": "Trek je wat minder aan van anderen.", - "question": 6, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 27, - "fields": { - "text": "Luister meer naar je eigen gevoel in plaats van naar wat anderen", - "question": 6, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 28, - "fields": { - "text": "Stel niet alles tot het laatste moment uit.", - "question": 6, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 29, - "fields": { - "text": "Altijd doorgaan.", - "question": 6, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 30, - "fields": { - "text": "Probeer ook eens buiten de lijntjes te kleuren", - "question": 6, - "is_right_answer": true, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 31, - "fields": { - "text": "Ga als je groot bent op groepsreis!", - "question": 6, - "is_right_answer": false, - "_order": 6, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 32, - "fields": { - "text": "Trek minder aan van de mening van anderen, het is oké om anders", - "question": 6, - "is_right_answer": false, - "_order": 7, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 33, - "fields": { - "text": "Sneakers", - "question": 7, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 34, - "fields": { - "text": "Wandel-/bergschoenen", - "question": 7, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 35, - "fields": { - "text": "Lederen schoenen", - "question": 7, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 36, - "fields": { - "text": "Pantoffels", - "question": 7, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 37, - "fields": { - "text": "Hakken", - "question": 7, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 38, - "fields": { - "text": "Geen schoenen, alleen sokken", - "question": 7, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 39, - "fields": { - "text": "Fiets", - "question": 8, - "is_right_answer": true, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 40, - "fields": { - "text": "Auto", - "question": 8, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 41, - "fields": { - "text": "Trein", - "question": 8, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 42, - "fields": { - "text": "Ja", - "question": 9, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 43, - "fields": { - "text": "Nee", - "question": 9, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 44, - "fields": { - "text": "Karen", - "question": 10, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 45, - "fields": { - "text": "Gilles de Coster", - "question": 10, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 46, - "fields": { - "text": "Kees Tol", - "question": 10, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 47, - "fields": { - "text": "Harry en John", - "question": 10, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 48, - "fields": { - "text": "Georgina Verbaan", - "question": 10, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 49, - "fields": { - "text": "Marc-Marie Huijbregts", - "question": 10, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 50, - "fields": { - "text": "Fresia Cousiño Arias, Rik van de Westelaken", - "question": 10, - "is_right_answer": false, - "_order": 6, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 51, - "fields": { - "text": "Ellie Lust", - "question": 10, - "is_right_answer": false, - "_order": 7, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 52, - "fields": { - "text": "Bouba", - "question": 10, - "is_right_answer": false, - "_order": 8, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 53, - "fields": { - "text": "Jan Versteegh", - "question": 10, - "is_right_answer": false, - "_order": 9, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 54, - "fields": { - "text": "Dick Jol", - "question": 10, - "is_right_answer": false, - "_order": 10, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 55, - "fields": { - "text": "Karin de Groot", - "question": 10, - "is_right_answer": false, - "_order": 11, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 56, - "fields": { - "text": "Pieter", - "question": 10, - "is_right_answer": false, - "_order": 12, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 57, - "fields": { - "text": "Renée Fokker", - "question": 10, - "is_right_answer": false, - "_order": 13, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 58, - "fields": { - "text": "Sam, Davy", - "question": 10, - "is_right_answer": true, - "_order": 14, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 59, - "fields": { - "text": "Ja", - "question": 11, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 60, - "fields": { - "text": "Nee", - "question": 11, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 61, - "fields": { - "text": "Éénpersoons, losstaand bed", - "question": 12, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 62, - "fields": { - "text": "Éénpersoonsbed, tegen een ander bed aan", - "question": 12, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 63, - "fields": { - "text": "Tweepersoons bed", - "question": 12, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 64, - "fields": { - "text": "5", - "question": 13, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 65, - "fields": { - "text": "6", - "question": 13, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 66, - "fields": { - "text": "7", - "question": 13, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 67, - "fields": { - "text": "8", - "question": 13, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 68, - "fields": { - "text": "Met de rug naar de accommodatie", - "question": 14, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 69, - "fields": { - "text": "Met de rug naar de buitenmuur", - "question": 14, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 70, - "fields": { - "text": "Claudia", - "question": 15, - "is_right_answer": true, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 71, - "fields": { - "text": "Eelco", - "question": 15, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 72, - "fields": { - "text": "Elise", - "question": 15, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 73, - "fields": { - "text": "Gert-Jan", - "question": 15, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 74, - "fields": { - "text": "Iris", - "question": 15, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 75, - "fields": { - "text": "Jari", - "question": 15, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 76, - "fields": { - "text": "Lara", - "question": 15, - "is_right_answer": false, - "_order": 6, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 77, - "fields": { - "text": "Lotte", - "question": 15, - "is_right_answer": false, - "_order": 7, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 78, - "fields": { - "text": "Myrthe", - "question": 15, - "is_right_answer": false, - "_order": 8, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 79, - "fields": { - "text": "Remy", - "question": 15, - "is_right_answer": false, - "_order": 9, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 80, - "fields": { - "text": "Robbert", - "question": 15, - "is_right_answer": false, - "_order": 10, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 81, - "fields": { - "text": "Tom", - "question": 15, - "is_right_answer": false, - "_order": 11, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 83, - "fields": { - "text": "Man", - "question": 16, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 84, - "fields": { - "text": "Vrouw", - "question": 16, - "is_right_answer": true, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 85, - "fields": { - "text": "Nee", - "question": 17, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 86, - "fields": { - "text": "De Krtek is vegetariër", - "question": 17, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 87, - "fields": { - "text": "De Krtek is flexitariër", - "question": 17, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 88, - "fields": { - "text": "De Krtek heeft een allergie", - "question": 17, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 89, - "fields": { - "text": "De Krtek heeft een intolerantie", - "question": 17, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 90, - "fields": { - "text": "De Krtek eet geen rundvlees", - "question": 17, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 91, - "fields": { - "text": "De Krtek eet geen waterdieren", - "question": 17, - "is_right_answer": false, - "_order": 6, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 92, - "fields": { - "text": "Amy, Karel en Floyd", - "question": 18, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 93, - "fields": { - "text": "Flip en Majoor", - "question": 18, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 94, - "fields": { - "text": "Benji", - "question": 18, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 95, - "fields": { - "text": "Sini", - "question": 18, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 96, - "fields": { - "text": "De huisdieren van de Krtek hebben geen naam", - "question": 18, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 97, - "fields": { - "text": "De Krtek heeft geen huisdieren", - "question": 18, - "is_right_answer": true, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 98, - "fields": { - "text": "Koffie", - "question": 19, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 99, - "fields": { - "text": "Thee", - "question": 19, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 100, - "fields": { - "text": "Water", - "question": 19, - "is_right_answer": true, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 101, - "fields": { - "text": "Melk", - "question": 19, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 102, - "fields": { - "text": "Sap", - "question": 19, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 103, - "fields": { - "text": "Niks", - "question": 19, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 104, - "fields": { - "text": "Denemarken", - "question": 20, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 105, - "fields": { - "text": "Drenthe", - "question": 20, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 106, - "fields": { - "text": "Mallorca", - "question": 20, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 107, - "fields": { - "text": "Marokko", - "question": 20, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 108, - "fields": { - "text": "Oostenrijk", - "question": 20, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 109, - "fields": { - "text": "Turkije", - "question": 20, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 110, - "fields": { - "text": "Zweden", - "question": 20, - "is_right_answer": true, - "_order": 6, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 111, - "fields": { - "text": "Het eerste groepje", - "question": 21, - "is_right_answer": true, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 112, - "fields": { - "text": "Het tweede groepje", - "question": 21, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 113, - "fields": { - "text": "Het derde groepje", - "question": 21, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 114, - "fields": { - "text": "Het vierde groepje", - "question": 21, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 115, - "fields": { - "text": "Het vijfde groepje", - "question": 21, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 116, - "fields": { - "text": "Nee", - "question": 22, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 117, - "fields": { - "text": "Het universum", - "question": 22, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 118, - "fields": { - "text": "Toeval", - "question": 22, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 119, - "fields": { - "text": "De Krtek is hindoeïstisch", - "question": 22, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 120, - "fields": { - "text": "Ja", - "question": 23, - "is_right_answer": true, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 121, - "fields": { - "text": "Nee", - "question": 23, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 122, - "fields": { - "text": "Tussen 0:00 en 0:59 uur", - "question": 24, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 123, - "fields": { - "text": "Tussen 1:00 en 1:59 uur", - "question": 24, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 124, - "fields": { - "text": "Tussen 2:00 en 2:59 uur", - "question": 24, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 125, - "fields": { - "text": "Na 3:00", - "question": 24, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 126, - "fields": { - "text": "1", - "question": 25, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 127, - "fields": { - "text": "2", - "question": 25, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 128, - "fields": { - "text": "3", - "question": 25, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 129, - "fields": { - "text": "Geen", - "question": 25, - "is_right_answer": true, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 130, - "fields": { - "text": "Digimon", - "question": 26, - "is_right_answer": true, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 131, - "fields": { - "text": "Floris", - "question": 26, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 132, - "fields": { - "text": "Het huis Anubis", - "question": 26, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 133, - "fields": { - "text": "Sesamstraat", - "question": 26, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 134, - "fields": { - "text": "Spongebob Squarepants", - "question": 26, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 135, - "fields": { - "text": "Teletubbies", - "question": 26, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 136, - "fields": { - "text": "In koffer(s)", - "question": 27, - "is_right_answer": true, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 137, - "fields": { - "text": "In losse tas(sen)", - "question": 27, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 138, - "fields": { - "text": "In een rugzak", - "question": 27, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 139, - "fields": { - "text": "Een vork die door een metalen pan krast", - "question": 28, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 140, - "fields": { - "text": "Smakkende mensen", - "question": 28, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 141, - "fields": { - "text": "Een vork die over een bord schraapt", - "question": 28, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 142, - "fields": { - "text": "Schuren met schuurpapier", - "question": 28, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 143, - "fields": { - "text": "Nagels op een krijtbord", - "question": 28, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 144, - "fields": { - "text": "Servies dat tegen elkaar klettert", - "question": 28, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 145, - "fields": { - "text": "Het geroekoe van een duif", - "question": 28, - "is_right_answer": true, - "_order": 6, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 146, - "fields": { - "text": "Piepschuim", - "question": 28, - "is_right_answer": false, - "_order": 7, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 147, - "fields": { - "text": "Ja", - "question": 29, - "is_right_answer": false, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 148, - "fields": { - "text": "Nee", - "question": 29, - "is_right_answer": true, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 149, - "fields": { - "text": "Claudia", - "question": 30, - "is_right_answer": true, - "_order": 0, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 150, - "fields": { - "text": "Eelco", - "question": 30, - "is_right_answer": false, - "_order": 1, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 151, - "fields": { - "text": "Elise", - "question": 30, - "is_right_answer": false, - "_order": 2, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 152, - "fields": { - "text": "Gert-Jan", - "question": 30, - "is_right_answer": false, - "_order": 3, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 153, - "fields": { - "text": "Iris", - "question": 30, - "is_right_answer": false, - "_order": 4, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 154, - "fields": { - "text": "Jari", - "question": 30, - "is_right_answer": false, - "_order": 5, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 155, - "fields": { - "text": "Lara", - "question": 30, - "is_right_answer": false, - "_order": 6, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 156, - "fields": { - "text": "Lotte", - "question": 30, - "is_right_answer": false, - "_order": 7, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 157, - "fields": { - "text": "Myrthe", - "question": 30, - "is_right_answer": false, - "_order": 8, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 158, - "fields": { - "text": "Remy", - "question": 30, - "is_right_answer": false, - "_order": 9, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 159, - "fields": { - "text": "Robbert", - "question": 30, - "is_right_answer": false, - "_order": 10, - "candidates": [] - } -}, -{ - "model": "quiz.answer", - "pk": 160, - "fields": { - "text": "Tom", - "question": 30, - "is_right_answer": false, - "_order": 11, - "candidates": [] - } -}, -{ - "model": "quiz.question", - "pk": 1, - "fields": { - "question": "Is de Krtek een man of een vrouw", - "quiz": 1, - "enabled": true, - "_order": 0 - } -}, -{ - "model": "quiz.question", - "pk": 2, - "fields": { - "question": "Hoeveel broers heeft de Krtek?", - "quiz": 1, - "enabled": true, - "_order": 1 - } -}, -{ - "model": "quiz.question", - "pk": 3, - "fields": { - "question": "Wat is de lievelingsfeestdag van de Krtek?", - "quiz": 1, - "enabled": true, - "_order": 2 - } -}, -{ - "model": "quiz.question", - "pk": 4, - "fields": { - "question": "Hoe kwam de Krtek naar Kesteren vandaag?", - "quiz": 1, - "enabled": true, - "_order": 3 - } -}, -{ - "model": "quiz.question", - "pk": 5, - "fields": { - "question": "Met wie keek de Krtek de video bij binnenkomst?", - "quiz": 1, - "enabled": true, - "_order": 4 - } -}, -{ - "model": "quiz.question", - "pk": 6, - "fields": { - "question": "Welk advies zou de Krtek zichzelf als kind geven?", - "quiz": 1, - "enabled": true, - "_order": 5 - } -}, -{ - "model": "quiz.question", - "pk": 7, - "fields": { - "question": "Wat voor soort schoenen droeg de Krtek bij het diner?", - "quiz": 1, - "enabled": true, - "_order": 6 - } -}, -{ - "model": "quiz.question", - "pk": 8, - "fields": { - "question": "Met welk vervoersmiddel reist de Krtek het liefste?", - "quiz": 1, - "enabled": true, - "_order": 7 - } -}, -{ - "model": "quiz.question", - "pk": 9, - "fields": { - "question": "Heeft de Krtek een eigen auto?", - "quiz": 1, - "enabled": true, - "_order": 8 - } -}, -{ - "model": "quiz.question", - "pk": 10, - "fields": { - "question": "Van wie is de quote die de Krtek gepakt heeft", - "quiz": 1, - "enabled": true, - "_order": 9 - } -}, -{ - "model": "quiz.question", - "pk": 11, - "fields": { - "question": "Zou de Krtek molboekjes, jokers, vrijstellingen of topito’s uit iemands rugzak stelen om te kunnen winnen?", - "quiz": 1, - "enabled": true, - "_order": 10 - } -}, -{ - "model": "quiz.question", - "pk": 12, - "fields": { - "question": "In wat voor bed slaapt de Krtek dit weekend?", - "quiz": 1, - "enabled": true, - "_order": 11 - } -}, -{ - "model": "quiz.question", - "pk": 13, - "fields": { - "question": "Hoeveel jaar heeft de Krtek gedaan over de middelbare school?", - "quiz": 1, - "enabled": true, - "_order": 12 - } -}, -{ - "model": "quiz.question", - "pk": 14, - "fields": { - "question": "Waar zat de Krtek aan tafel bij het diner?", - "quiz": 1, - "enabled": true, - "_order": 13 - } -}, -{ - "model": "quiz.question", - "pk": 15, - "fields": { - "question": "Wie is de Krtek", - "quiz": 1, - "enabled": true, - "_order": 14 - } -}, -{ - "model": "quiz.question", - "pk": 16, - "fields": { - "question": "Is de Krtek een man of een vrouw?", - "quiz": 2, - "enabled": true, - "_order": 0 - } -}, -{ - "model": "quiz.question", - "pk": 17, - "fields": { - "question": "Heeft de Krtek dieetwensen of allergieën?", - "quiz": 2, - "enabled": true, - "_order": 1 - } -}, -{ - "model": "quiz.question", - "pk": 18, - "fields": { - "question": "Hoe heet het huisdier/de huisdieren van de Krtek?", - "quiz": 2, - "enabled": true, - "_order": 2 - } -}, -{ - "model": "quiz.question", - "pk": 19, - "fields": { - "question": "Wat dronk de Krtek deze ochtend bij het ontbijt?", - "quiz": 2, - "enabled": true, - "_order": 3 - } -}, -{ - "model": "quiz.question", - "pk": 20, - "fields": { - "question": "Waar ging de eerste vakantie die de Krtek zich nog herinnert heen?", - "quiz": 2, - "enabled": true, - "_order": 4 - } -}, -{ - "model": "quiz.question", - "pk": 21, - "fields": { - "question": "Met welk groepje ging de Krtek als eerste het Douanespel in?", - "quiz": 2, - "enabled": true, - "_order": 5 - } -}, -{ - "model": "quiz.question", - "pk": 22, - "fields": { - "question": "Gelooft de Krtek ergens in?", - "quiz": 2, - "enabled": true, - "_order": 6 - } -}, -{ - "model": "quiz.question", - "pk": 23, - "fields": { - "question": "At de Krtek op vrijdagavond heksenkaas tijdens het diner?", - "quiz": 2, - "enabled": true, - "_order": 7 - } -}, -{ - "model": "quiz.question", - "pk": 24, - "fields": { - "question": "Hoe laat ging de Krtek gisteravond naar bed?", - "quiz": 2, - "enabled": true, - "_order": 8 - } -}, -{ - "model": "quiz.question", - "pk": 25, - "fields": { - "question": "Hoeveel batterijen heeft de krtek naar het bord gebracht bij het douanespel?", - "quiz": 2, - "enabled": true, - "_order": 9 - } -}, -{ - "model": "quiz.question", - "pk": 26, - "fields": { - "question": "Wat keek de Krtek als kind graag op TV?", - "quiz": 2, - "enabled": true, - "_order": 10 - } -}, -{ - "model": "quiz.question", - "pk": 27, - "fields": { - "question": "Waarin zat op de heenreis de bagage van de Krtek (voornamelijk)?", - "quiz": 2, - "enabled": true, - "_order": 11 - } -}, -{ - "model": "quiz.question", - "pk": 28, - "fields": { - "question": "Van welk geluid gaan de haren van de Krtek overeind staan?", - "quiz": 2, - "enabled": true, - "_order": 12 - } -}, -{ - "model": "quiz.question", - "pk": 29, - "fields": { - "question": "Wilde de Krtek penningmeester worden?", - "quiz": 2, - "enabled": true, - "_order": 13 - } -}, -{ - "model": "quiz.question", - "pk": 30, - "fields": { - "question": "Wie is de Krtek?", - "quiz": 2, - "enabled": true, - "_order": 14 - } -}, -{ - "model": "quiz.candidate", - "pk": 1, - "fields": { - "season": 1, - "name": "Claudia" - } -}, -{ - "model": "quiz.candidate", - "pk": 2, - "fields": { - "season": 1, - "name": "Eelco" - } -}, -{ - "model": "quiz.candidate", - "pk": 3, - "fields": { - "season": 1, - "name": "Elise" - } -}, -{ - "model": "quiz.candidate", - "pk": 4, - "fields": { - "season": 1, - "name": "Gert-Jan" - } -}, -{ - "model": "quiz.candidate", - "pk": 5, - "fields": { - "season": 1, - "name": "Iris" - } -}, -{ - "model": "quiz.candidate", - "pk": 6, - "fields": { - "season": 1, - "name": "Jari" - } -}, -{ - "model": "quiz.candidate", - "pk": 7, - "fields": { - "season": 1, - "name": "Lara" - } -}, -{ - "model": "quiz.candidate", - "pk": 8, - "fields": { - "season": 1, - "name": "Lotte" - } -}, -{ - "model": "quiz.candidate", - "pk": 9, - "fields": { - "season": 1, - "name": "Myrthe" - } -}, -{ - "model": "quiz.candidate", - "pk": 10, - "fields": { - "season": 1, - "name": "Remy" - } -}, -{ - "model": "quiz.candidate", - "pk": 11, - "fields": { - "season": 1, - "name": "Robbert" - } -}, -{ - "model": "quiz.candidate", - "pk": 12, - "fields": { - "season": 1, - "name": "Tom" - } -}, -{ - "model": "quiz.candidate", - "pk": 14, - "fields": { - "season": 1, - "name": "Marijn" - } -}, -{ - "model": "quiz.candidate", - "pk": 15, - "fields": { - "season": 1, - "name": "Renske" - } -}, -{ - "model": "quiz.candidate", - "pk": 16, - "fields": { - "season": 1, - "name": "Philine" - } -}, -{ - "model": "quiz.quiz", - "pk": 1, - "fields": { - "name": "Test 1", - "season": 1 - } -}, -{ - "model": "quiz.quiz", - "pk": 2, - "fields": { - "name": "Test 2", - "season": 1 - } -}, -{ - "model": "quiz.season", - "pk": 1, - "fields": { - "name": "Krtek", - "active_quiz": 1, - "season_code": "12345", - "preregister_candidates": true, - "owner": [] - } -} -] diff --git a/tvdt/quiz/helpers.py b/tvdt/quiz/helpers.py deleted file mode 100644 index 10d517e..0000000 --- a/tvdt/quiz/helpers.py +++ /dev/null @@ -1,8 +0,0 @@ -import random -import string - - -def generate_season_code(length: int = 5) -> str: - return "".join( - random.choice(string.ascii_uppercase + string.digits) for _ in range(length) - ) diff --git a/tvdt/quiz/locale/nl/LC_MESSAGES/django.po b/tvdt/quiz/locale/nl/LC_MESSAGES/django.po deleted file mode 100644 index 5f1c4f1..0000000 --- a/tvdt/quiz/locale/nl/LC_MESSAGES/django.po +++ /dev/null @@ -1,162 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-11 23:22+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: quiz/apps.py:8 quiz/models/correction.py:17 quiz/models/given_answer.py:19 -#: quiz/models/question.py:23 quiz/models/quiz.py:60 -msgid "quiz" -msgstr "test" - -#: quiz/models/answer.py:10 -msgid "text" -msgstr "tekst" - -#: quiz/models/answer.py:15 quiz/models/question.py:18 -#: quiz/models/question.py:58 -msgid "question" -msgstr "vraag" - -#: quiz/models/answer.py:17 -msgid "is right answer" -msgstr "is goede antwoord" - -#: quiz/models/answer.py:19 quiz/models/candidate.py:50 -msgid "candidates" -msgstr "kandidaten" - -#: quiz/models/answer.py:23 quiz/models/given_answer.py:25 -msgid "answer" -msgstr "antwoord" - -#: quiz/models/answer.py:24 -msgid "answers" -msgstr "antwoorden" - -#: quiz/models/candidate.py:18 quiz/models/quiz.py:12 quiz/models/season.py:12 -msgid "name" -msgstr "naam" - -#: quiz/models/candidate.py:49 quiz/models/correction.py:11 -#: quiz/models/given_answer.py:11 -msgid "candidate" -msgstr "kandidaat" - -#: quiz/models/correction.py:19 -msgid "amount" -msgstr "aantal" - -#: quiz/models/correction.py:23 -msgid "correction" -msgstr "joker" - -#: quiz/models/correction.py:24 -msgid "corrections" -msgstr "jokers" - -#: quiz/models/given_answer.py:36 -msgid "given answer" -msgstr "gegeven antwoord" - -#: quiz/models/given_answer.py:37 -msgid "given answers" -msgstr "gegeven antwoorden" - -#: quiz/models/question.py:25 -msgid "enabled" -msgstr "actief" - -#: quiz/models/question.py:42 -msgid "Error: Question has no answers" -msgstr "Fout: Raar genoeg heeft deze vraag geen antwoorden..." - -#: quiz/models/question.py:47 -msgid "Error: This question has no right answer!" -msgstr "Fout: Raar genoeg heeft deze vraag geen antwoorden..." - -#: quiz/models/question.py:50 -msgid "Warning: This question has multiple correct answers" -msgstr "Waarschuwing: Raar genoeg heeft deze vraag geen antwoorden..." - -#: quiz/models/question.py:59 -msgid "questions" -msgstr "vraag" - -#: quiz/models/quiz.py:17 quiz/models/season.py:43 -msgid "season" -msgstr "seizoen" - -#: quiz/models/quiz.py:21 -msgid "dropouts" -msgstr "afvallers" - -#: quiz/models/quiz.py:61 -msgid "quizzes" -msgstr "tests" - -#: quiz/models/season.py:19 -msgid "active quiz" -msgstr "actieve test" - -#: quiz/models/season.py:23 -msgid "season code" -msgstr "seizoencode" - -#: quiz/models/season.py:26 -msgid "preregister candidates" -msgstr "kandidaten voorregistreren" - -#: quiz/models/season.py:30 -msgid "owners" -msgstr "eigenaren" - -#: quiz/models/season.py:44 -msgid "seasons" -msgstr "seizoenen" - -#: quiz/templates/quiz/base.html:16 -msgid "Tijd voor de test" -msgstr "Tijd voor de test" - -#: quiz/templates/quiz/question.html:15 -msgid "Weirdly enough this question has no answers..." -msgstr "Raar genoeg heeft deze vraag geen antwoorden..." - -#: quiz/views/enternameview.py:15 -msgid "Name" -msgstr "Naam" - -#: quiz/views/enternameview.py:28 -msgid "This season has no active quiz." -msgstr "Dit seizoen heeft geen actieve test." - -#: quiz/views/enternameview.py:40 -msgid "Candidate does not exist" -msgstr "Kandidaat bestaat niet" - -#: quiz/views/questionview.py:23 -msgid "No active quiz for season" -msgstr "Geen active test voor seizoen" - -#: quiz/views/questionview.py:27 -msgid "Quiz done" -msgstr "Test klaar" - -#: quiz/views/selectseasonview.py:30 -msgid "Invalid season code" -msgstr "Ongeldige seizoencode" diff --git a/tvdt/quiz/migrations/0001_initial.py b/tvdt/quiz/migrations/0001_initial.py deleted file mode 100644 index 070f3af..0000000 --- a/tvdt/quiz/migrations/0001_initial.py +++ /dev/null @@ -1,286 +0,0 @@ -# Generated by Django 5.1.3 on 2024-11-25 18:17 - -import django.db.models.deletion -from django.db import migrations, models - -import quiz.helpers - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [] - - operations = [ - migrations.CreateModel( - name="Candidate", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("name", models.CharField(max_length=16, verbose_name="name")), - ], - options={ - "verbose_name": "candidate", - "verbose_name_plural": "candidates", - }, - ), - migrations.CreateModel( - name="Question", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("question", models.CharField(max_length=256, verbose_name="question")), - ("enabled", models.BooleanField(default=True, verbose_name="enabled")), - ], - options={ - "verbose_name": "question", - "verbose_name_plural": "questions", - }, - ), - migrations.CreateModel( - name="Quiz", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("name", models.CharField(max_length=64, verbose_name="name")), - ], - options={ - "verbose_name": "quiz", - "verbose_name_plural": "quizzes", - }, - ), - migrations.CreateModel( - name="Answer", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("text", models.CharField(max_length=64, verbose_name="text")), - ( - "is_right_answer", - models.BooleanField(verbose_name="is right answer"), - ), - ( - "candidates", - models.ManyToManyField( - blank=True, to="quiz.candidate", verbose_name="candidates" - ), - ), - ( - "question", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="answers", - to="quiz.question", - verbose_name="question", - ), - ), - ], - options={ - "verbose_name": "answer", - "verbose_name_plural": "answers", - "order_with_respect_to": "question", - }, - ), - migrations.AddField( - model_name="question", - name="quiz", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="questions", - to="quiz.quiz", - verbose_name="quiz", - ), - ), - migrations.CreateModel( - name="GivenAnswer", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("created", models.DateTimeField(auto_now_add=True)), - ( - "answer", - models.ForeignKey( - null=True, - on_delete=django.db.models.deletion.CASCADE, - to="quiz.answer", - verbose_name="answer", - ), - ), - ( - "candidate", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="answers", - to="quiz.candidate", - verbose_name="candidate", - ), - ), - ( - "quiz", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="+", - to="quiz.quiz", - verbose_name="quiz", - ), - ), - ], - options={ - "verbose_name": "given answer", - "verbose_name_plural": "given answers", - "ordering": ("quiz", "candidate"), - }, - ), - migrations.CreateModel( - name="Season", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("name", models.CharField(max_length=64, verbose_name="name")), - ( - "season_code", - models.CharField( - default=quiz.helpers.generate_season_code, - max_length=5, - verbose_name="season code", - ), - ), - ( - "preregister_candidates", - models.BooleanField( - default=True, verbose_name="preregister candidates" - ), - ), - ( - "active_quiz", - models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="+", - to="quiz.quiz", - verbose_name="active quiz", - ), - ), - ], - options={ - "verbose_name": "season", - "verbose_name_plural": "seasons", - }, - ), - migrations.AddField( - model_name="quiz", - name="season", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="quizzes", - to="quiz.season", - verbose_name="season", - ), - ), - migrations.AddField( - model_name="candidate", - name="season", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="candidates", - to="quiz.season", - verbose_name="season", - ), - ), - migrations.AlterOrderWithRespectTo( - name="question", - order_with_respect_to="quiz", - ), - migrations.CreateModel( - name="Correction", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "candidate", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="corrections_used", - to="quiz.candidate", - verbose_name="candidate", - ), - ), - ( - "quiz", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="corrections_used", - to="quiz.quiz", - verbose_name="quiz", - ), - ), - ], - options={ - "verbose_name": "correction", - "verbose_name_plural": "corrections", - "unique_together": {("candidate", "quiz")}, - }, - ), - migrations.AddIndex( - model_name="candidate", - index=models.Index( - fields=["season", "name"], name="quiz_candid_season__d83118_idx" - ), - ), - migrations.AlterUniqueTogether( - name="candidate", - unique_together={("season", "name")}, - ), - ] diff --git a/tvdt/quiz/migrations/0002_season_owner.py b/tvdt/quiz/migrations/0002_season_owner.py deleted file mode 100644 index 46f11c8..0000000 --- a/tvdt/quiz/migrations/0002_season_owner.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 5.1.3 on 2024-11-30 18:21 - -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("quiz", "0001_initial"), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.AddField( - model_name="season", - name="owner", - field=models.ManyToManyField( - related_name="seasons", - to=settings.AUTH_USER_MODEL, - verbose_name="owners", - ), - ), - ] diff --git a/tvdt/quiz/migrations/0003_correction_amount_alter_correction_candidate_and_more.py b/tvdt/quiz/migrations/0003_correction_amount_alter_correction_candidate_and_more.py deleted file mode 100644 index 56240a2..0000000 --- a/tvdt/quiz/migrations/0003_correction_amount_alter_correction_candidate_and_more.py +++ /dev/null @@ -1,39 +0,0 @@ -# Generated by Django 5.1.3 on 2024-12-01 14:23 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("quiz", "0002_season_owner"), - ] - - operations = [ - migrations.AddField( - model_name="correction", - name="amount", - field=models.FloatField(default=1, verbose_name="amount"), - ), - migrations.AlterField( - model_name="correction", - name="candidate", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="corrections", - to="quiz.candidate", - verbose_name="candidate", - ), - ), - migrations.AlterField( - model_name="correction", - name="quiz", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="corrections", - to="quiz.quiz", - verbose_name="quiz", - ), - ), - ] diff --git a/tvdt/quiz/migrations/0004_quiz_dropouts.py b/tvdt/quiz/migrations/0004_quiz_dropouts.py deleted file mode 100644 index 1503e30..0000000 --- a/tvdt/quiz/migrations/0004_quiz_dropouts.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.1.3 on 2024-12-01 16:57 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("quiz", "0003_correction_amount_alter_correction_candidate_and_more"), - ] - - operations = [ - migrations.AddField( - model_name="quiz", - name="dropouts", - field=models.PositiveSmallIntegerField(default=1, verbose_name="dropouts"), - ), - ] diff --git a/tvdt/quiz/migrations/__init__.py b/tvdt/quiz/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tvdt/quiz/models/__init__.py b/tvdt/quiz/models/__init__.py deleted file mode 100644 index 6b1752d..0000000 --- a/tvdt/quiz/models/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .answer import Answer -from .candidate import Candidate -from .correction import Correction -from .given_answer import GivenAnswer -from .question import Question -from .quiz import Quiz -from .season import Season diff --git a/tvdt/quiz/models/answer.py b/tvdt/quiz/models/answer.py deleted file mode 100644 index 5cb12a0..0000000 --- a/tvdt/quiz/models/answer.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import final - -from django.db import models -from django.utils.translation import gettext_lazy as _ -from django_stubs_ext.db.models import TypedModelMeta - - -@final -class Answer(models.Model): - text = models.CharField(max_length=64, verbose_name=_("text")) - question = models.ForeignKey( - "Question", - on_delete=models.CASCADE, - related_name="answers", - verbose_name=_("question"), - ) - is_right_answer = models.BooleanField(verbose_name=_("is right answer")) - candidates = models.ManyToManyField( - "Candidate", verbose_name=_("candidates"), blank=True - ) - - class Meta(TypedModelMeta): - verbose_name = _("answer") - verbose_name_plural = _("answers") - - order_with_respect_to = "question" diff --git a/tvdt/quiz/models/candidate.py b/tvdt/quiz/models/candidate.py deleted file mode 100644 index 863e7d6..0000000 --- a/tvdt/quiz/models/candidate.py +++ /dev/null @@ -1,50 +0,0 @@ -from typing import Self - -from django.db import models -from django.utils.translation import gettext_lazy as _ -from django_stubs_ext.db.models import TypedModelMeta - -from .given_answer import GivenAnswer -from .question import NoActiveTestForSeason, Question, QuizAlreadyFinished - - -class Candidate(models.Model): - season = models.ForeignKey( - "Season", - on_delete=models.CASCADE, - related_name="candidates", - verbose_name="season", - ) - name = models.CharField(max_length=16, verbose_name=_("name")) - - def get_next_question(self, candidate: Self) -> "Question": - quiz = candidate.season.active_quiz - if quiz is None: - raise NoActiveTestForSeason() - - question = ( - Question.objects.filter(quiz=quiz, enabled=True) - .exclude( - id__in=GivenAnswer.objects.filter( - candidate=candidate, - quiz=quiz, - answer__isnull=False, - ).values_list("answer__question_id", flat=True) - ) - .first() - ) - - if question is None: - raise QuizAlreadyFinished() - - return question - - def __str__(self) -> str: - return f"{self.name} ({self.season})" - - class Meta(TypedModelMeta): - unique_together = ["season", "name"] - indexes = [models.Index(fields=["season", "name"])] - - verbose_name = _("candidate") - verbose_name_plural = _("candidates") diff --git a/tvdt/quiz/models/correction.py b/tvdt/quiz/models/correction.py deleted file mode 100644 index eed4a57..0000000 --- a/tvdt/quiz/models/correction.py +++ /dev/null @@ -1,24 +0,0 @@ -from django.db import models -from django.utils.translation import gettext_lazy as _ -from django_stubs_ext.db.models import TypedModelMeta - - -class Correction(models.Model): - candidate = models.ForeignKey( - "Candidate", - on_delete=models.CASCADE, - related_name="corrections", - verbose_name=_("candidate"), - ) - quiz = models.ForeignKey( - "Quiz", - on_delete=models.CASCADE, - related_name="corrections", - verbose_name=_("quiz"), - ) - amount = models.FloatField(verbose_name=_("amount"), default=1) - - class Meta(TypedModelMeta): - unique_together = ("candidate", "quiz") - verbose_name = _("correction") - verbose_name_plural = _("corrections") diff --git a/tvdt/quiz/models/given_answer.py b/tvdt/quiz/models/given_answer.py deleted file mode 100644 index b6863e7..0000000 --- a/tvdt/quiz/models/given_answer.py +++ /dev/null @@ -1,37 +0,0 @@ -from django.db import models -from django.utils.translation import gettext_lazy as _ -from django_stubs_ext.db.models import TypedModelMeta - - -class GivenAnswer(models.Model): - candidate = models.ForeignKey( - "Candidate", - on_delete=models.CASCADE, - related_name="answers", - verbose_name=_("candidate"), - ) - - quiz = models.ForeignKey( - "Quiz", - on_delete=models.CASCADE, - null=False, - related_name="+", - verbose_name=_("quiz"), - ) - - answer = models.ForeignKey( - "Answer", - on_delete=models.CASCADE, - verbose_name=_("answer"), - null=True, - ) - created = models.DateTimeField(auto_now_add=True) - - def __str__(self): - return f"{self.quiz} - {self.candidate.name} {self.answer}" - - class Meta(TypedModelMeta): - ordering = ("quiz", "candidate") - - verbose_name = _("given answer") - verbose_name_plural = _("given answers") diff --git a/tvdt/quiz/models/question.py b/tvdt/quiz/models/question.py deleted file mode 100644 index 8b961d3..0000000 --- a/tvdt/quiz/models/question.py +++ /dev/null @@ -1,61 +0,0 @@ -from django.db import models -from django.db.models import QuerySet -from django.utils.translation import gettext_lazy as _ -from django_stubs_ext.db.models import TypedModelMeta - -from quiz.models import Answer - - -class NoActiveTestForSeason(Exception): - pass - - -class QuizAlreadyFinished(Exception): - pass - - -class Question(models.Model): - question = models.CharField(max_length=256, verbose_name=_("question")) - quiz = models.ForeignKey( - "Quiz", - on_delete=models.CASCADE, - related_name="questions", - verbose_name=_("quiz"), - ) - enabled = models.BooleanField(default=True, verbose_name=_("enabled")) - - @property - def order(self): - return self._order - - @property - def right_answer(self) -> QuerySet[Answer]: - return self.answers.filter(is_right_answer=True) - - @property - def has_right_answer(self) -> bool: - return self.answers.filter(is_right_answer=True).count() > 0 - - @property - def errors(self) -> str | None: - if self.answers.count() == 0: - return _("Error: Question has no answers") - - n_correct_answers = self.answers.filter(is_right_answer=True).count() - - if n_correct_answers == 0: - return _("Error: This question has no right answer!") - - if n_correct_answers > 1: - return _("Warning: This question has multiple correct answers") - - return None - - def __str__(self) -> str: - return f"{self._order + 1}. {self.question} ({self.quiz}) ({self.answers.count()} answers, {self.answers.filter(is_right_answer=True).count()} correct)" - - class Meta(TypedModelMeta): - verbose_name = _("question") - verbose_name_plural = _("questions") - - order_with_respect_to = "quiz" diff --git a/tvdt/quiz/models/quiz.py b/tvdt/quiz/models/quiz.py deleted file mode 100644 index ded9c1e..0000000 --- a/tvdt/quiz/models/quiz.py +++ /dev/null @@ -1,61 +0,0 @@ -from django.db import models -from django.db.models import F, OuterRef, Subquery -from django.db.models.aggregates import Count, Max, Min -from django.db.models.functions import Coalesce -from django.utils.translation import gettext_lazy as _ -from django_stubs_ext.db.models import TypedModelMeta - -from quiz.models import Candidate, Correction - - -class Quiz(models.Model): - name = models.CharField(max_length=64, verbose_name=_("name")) - season = models.ForeignKey( - "Season", - on_delete=models.CASCADE, - related_name="quizzes", - verbose_name=_("season"), - ) - - dropouts = models.PositiveSmallIntegerField( - verbose_name=_("dropouts"), - default=1, - ) - - def is_valid_quiz(self) -> bool: - return True - # Check > 0 active questions - # Check every question 1 right answer - - def get_score(self): - time_query = ( - Candidate.objects.filter(id=OuterRef("id"), answers__quiz=self) - .annotate(time=Max("answers__created") - Min("answers__created")) - .values("time") - ) - corrections = Correction.objects.filter( - quiz=self, candidate=OuterRef("id") - ).values("amount") - - scores = ( - Candidate.objects.filter( - answers__answer__is_right_answer=True, - answers__quiz=self, - ) - .values("id", "name") - .annotate( - correct=Count("answers"), - corrections=Coalesce(Subquery(corrections), 0.0), - score=F("correct") + F("corrections"), - time=Subquery(time_query), - ) - .order_by("-score", "time") - ) - return scores - - def __str__(self) -> str: - return f"{self.season.name} - {self.name}" - - class Meta(TypedModelMeta): - verbose_name = _("quiz") - verbose_name_plural = _("quizzes") diff --git a/tvdt/quiz/models/season.py b/tvdt/quiz/models/season.py deleted file mode 100644 index 1141d86..0000000 --- a/tvdt/quiz/models/season.py +++ /dev/null @@ -1,44 +0,0 @@ -from django.contrib.auth import get_user_model -from django.db import models -from django.utils.translation import gettext_lazy as _ -from django_stubs_ext.db.models import TypedModelMeta - -from ..helpers import generate_season_code - -User = get_user_model() - - -class Season(models.Model): - name = models.CharField(max_length=64, verbose_name=_("name")) - active_quiz = models.ForeignKey( - "Quiz", - on_delete=models.SET_NULL, - null=True, - blank=True, - default=None, - verbose_name=_("active quiz"), - related_name="+", - ) - season_code = models.CharField( - max_length=5, default=generate_season_code, verbose_name=_("season code") - ) - preregister_candidates = models.BooleanField( - default=True, verbose_name=_("preregister candidates") - ) - owner = models.ManyToManyField( - User, - verbose_name=_("owners"), - related_name="seasons", - ) - - def renew_season_code(self) -> str: - self.season_code = generate_season_code() - self.save() - return self.season_code - - def __str__(self) -> str: - return self.name - - class Meta(TypedModelMeta): - verbose_name = _("season") - verbose_name_plural = _("seasons") diff --git a/tvdt/quiz/static/quiz/de_mol/background.png b/tvdt/quiz/static/quiz/de_mol/background.png deleted file mode 100644 index 3042bd8..0000000 Binary files a/tvdt/quiz/static/quiz/de_mol/background.png and /dev/null differ diff --git a/tvdt/quiz/static/quiz/de_mol/green.png b/tvdt/quiz/static/quiz/de_mol/green.png deleted file mode 100644 index b984a24..0000000 Binary files a/tvdt/quiz/static/quiz/de_mol/green.png and /dev/null differ diff --git a/tvdt/quiz/static/quiz/de_mol/red.png b/tvdt/quiz/static/quiz/de_mol/red.png deleted file mode 100644 index ec37cfb..0000000 Binary files a/tvdt/quiz/static/quiz/de_mol/red.png and /dev/null differ diff --git a/tvdt/quiz/static/quiz/wie_is_de_mol/background.png b/tvdt/quiz/static/quiz/wie_is_de_mol/background.png deleted file mode 100644 index fabe57e..0000000 Binary files a/tvdt/quiz/static/quiz/wie_is_de_mol/background.png and /dev/null differ diff --git a/tvdt/quiz/static/quiz/wie_is_de_mol/green.png b/tvdt/quiz/static/quiz/wie_is_de_mol/green.png deleted file mode 100644 index ab216b5..0000000 Binary files a/tvdt/quiz/static/quiz/wie_is_de_mol/green.png and /dev/null differ diff --git a/tvdt/quiz/static/quiz/wie_is_de_mol/red.png b/tvdt/quiz/static/quiz/wie_is_de_mol/red.png deleted file mode 100644 index 32721a4..0000000 Binary files a/tvdt/quiz/static/quiz/wie_is_de_mol/red.png and /dev/null differ diff --git a/tvdt/quiz/templates/quiz/base.html b/tvdt/quiz/templates/quiz/base.html deleted file mode 100644 index 76fdb21..0000000 --- a/tvdt/quiz/templates/quiz/base.html +++ /dev/null @@ -1,51 +0,0 @@ -{% load i18n %} -{% load static %} - - - - - - - - {% block title %} - {% translate "Tijd voor de test" %} - {% endblock title %} - - - - -
    -
    - {% include "messages.html" %} - {% block body %} - {% endblock body %} -
    - {% block script %} - {% endblock script %} -
    - - diff --git a/tvdt/quiz/templates/quiz/enter_name.html b/tvdt/quiz/templates/quiz/enter_name.html deleted file mode 100644 index 70d639a..0000000 --- a/tvdt/quiz/templates/quiz/enter_name.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "quiz/base.html" %} -{% load crispy_forms_tags %} -{% block body %} - {% crispy form %} -{% endblock body %} diff --git a/tvdt/quiz/templates/quiz/question.html b/tvdt/quiz/templates/quiz/question.html deleted file mode 100644 index 05f42ef..0000000 --- a/tvdt/quiz/templates/quiz/question.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "quiz/base.html" %} -{% load i18n %} -{% block body %} -

    {{ question.question }}

    -
    - {% csrf_token %} - {% for answer in question.answers.all %} -
    - -
    - {% empty %} - {% translate "Weirdly enough this question has no answers..." %} - {% endfor %} -
    -{% endblock body %} diff --git a/tvdt/quiz/templates/quiz/screeen.html b/tvdt/quiz/templates/quiz/screeen.html deleted file mode 100644 index e69de29..0000000 diff --git a/tvdt/quiz/templates/quiz/select_season.html b/tvdt/quiz/templates/quiz/select_season.html deleted file mode 100644 index dc0facb..0000000 --- a/tvdt/quiz/templates/quiz/select_season.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "quiz/base.html" %} -{% load crispy_forms_tags %} -{% load i18n %} -{% block body %} - {% crispy form %} -{% endblock body %} diff --git a/tvdt/quiz/tests.py b/tvdt/quiz/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/tvdt/quiz/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/tvdt/quiz/urls.py b/tvdt/quiz/urls.py deleted file mode 100644 index c4ef4bb..0000000 --- a/tvdt/quiz/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.urls import path, register_converter - -from tvdt.converters import SeasonCodeConverter - -from .converters import CandidateConverter -from .views import SelectSeasonView -from .views.enternameview import EnterNameView -from .views.questionview import QuestionView - -register_converter(SeasonCodeConverter, "season") -register_converter(CandidateConverter, "candidate") -urlpatterns = [ - path("", SelectSeasonView.as_view(), name="index"), - path("/", EnterNameView.as_view(), name="enter_name"), - path("/", QuestionView.as_view(), name="question"), - # path("<>") -] diff --git a/tvdt/quiz/views/__init__.py b/tvdt/quiz/views/__init__.py deleted file mode 100644 index dccd439..0000000 --- a/tvdt/quiz/views/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .selectseasonview import SelectSeasonView diff --git a/tvdt/quiz/views/enternameview.py b/tvdt/quiz/views/enternameview.py deleted file mode 100644 index 95aa77f..0000000 --- a/tvdt/quiz/views/enternameview.py +++ /dev/null @@ -1,51 +0,0 @@ -from crispy_forms.helper import FormHelper -from django import forms -from django.contrib import messages -from django.shortcuts import redirect -from django.urls import reverse -from django.utils.translation import gettext as _ -from django.utils.translation import gettext_lazy -from django.views import View -from django.views.generic.base import TemplateResponseMixin - -from ..models import Candidate, Season - - -class EnterNameForm(forms.Form): - name = forms.CharField(label=_("Name")) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - - -class EnterNameView(View, TemplateResponseMixin): - template_name = "quiz/enter_name.html" - forms_class = EnterNameForm - - def get(self, request, season: Season, *args, **kwargs): - if season.active_quiz == None: - messages.info(request, _("This season has no active quiz.")) - return redirect("home") - - return self.render_to_response({"form": self.forms_class()}) - - def post(self, request, season: Season, *args, **kwargs): - name = request.POST.get("name") - - try: - candidate = Candidate.objects.get(season=season, name__iexact=name) - except Candidate.DoesNotExist: - if season.preregister_candidates: - messages.warning(request, _("Candidate does not exist")) - - return redirect(reverse("quiz", kwargs={"season": season})) - - candidate = Candidate.objects.create(season=season, name=name) - - return redirect( - reverse( - "question", - kwargs={"candidate": candidate}, - ) - ) diff --git a/tvdt/quiz/views/questionview.py b/tvdt/quiz/views/questionview.py deleted file mode 100644 index e5a0bfd..0000000 --- a/tvdt/quiz/views/questionview.py +++ /dev/null @@ -1,59 +0,0 @@ -from django.contrib import messages -from django.core.exceptions import BadRequest -from django.http import Http404, HttpRequest, HttpResponse -from django.shortcuts import redirect -from django.urls import reverse -from django.utils.translation import gettext as _ -from django.views import View -from django.views.generic.base import TemplateResponseMixin - -from ..models import Answer, Candidate, GivenAnswer -from ..models.question import NoActiveTestForSeason, QuizAlreadyFinished - - -class QuestionView(View, TemplateResponseMixin): - template_name = "quiz/question.html" - - def get( - self, request: HttpRequest, candidate: Candidate, *args, **kwargs - ) -> HttpResponse: - try: - question = candidate.get_next_question(candidate) - except NoActiveTestForSeason: - messages.error(request, _("No active quiz for season")) - return redirect("home") - except QuizAlreadyFinished: - if not kwargs.get("from_post"): - messages.error(request, _("Quiz done")) - - return redirect(reverse("enter_name", kwargs={"season": candidate.season})) - - # TODO: On first question -> record time - if ( - GivenAnswer.objects.filter( - candidate=candidate, quiz=candidate.season.active_quiz - ).count() - == 0 - ): - GivenAnswer.objects.create( - candidate=candidate, quiz=question.quiz, answer=None - ) - - return self.render_to_response({"candidate": candidate, "question": question}) - - def post(self, request: HttpRequest, candidate: Candidate, *args, **kwargs): - answer_id = request.POST.get("answer") - if answer_id == None: - raise BadRequest - - try: - answer = Answer.objects.get(id=answer_id) - except Answer.DoesNotExist: - raise BadRequest - - GivenAnswer.objects.create( - candidate=candidate, - quiz=answer.question.quiz, - answer=answer, - ) - return self.get(request, candidate, from_post=True) diff --git a/tvdt/quiz/views/selectseasonview.py b/tvdt/quiz/views/selectseasonview.py deleted file mode 100644 index 523245b..0000000 --- a/tvdt/quiz/views/selectseasonview.py +++ /dev/null @@ -1,39 +0,0 @@ -from crispy_forms.helper import FormHelper -from django import forms -from django.contrib import messages -from django.http import Http404 -from django.shortcuts import redirect -from django.urls import reverse -from django.utils.translation import gettext as _ -from django.views.generic.edit import FormView -from mypy.dmypy.client import request - -from ..models import Season - - -class SelectSeasonForm(forms.Form): - code = forms.CharField(max_length=5) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - - -class SelectSeasonView(FormView): - form_class = SelectSeasonForm - template_name = "quiz/select_season.html" - - def form_valid(self, form): - try: - season = Season.objects.get(season_code=form.cleaned_data["code"].upper()) - except Season.DoesNotExist: - messages.warning(self.request, _("Invalid season code")) - return redirect("home") - - from environs import Env - - env = Env() - env.read_env() - print(env.dump()) - - return redirect(reverse("enter_name", kwargs={"season": season})) diff --git a/tvdt/templates/messages.html b/tvdt/templates/messages.html deleted file mode 100644 index 0162264..0000000 --- a/tvdt/templates/messages.html +++ /dev/null @@ -1,13 +0,0 @@ -{% if messages %} - {% for message in messages %} - - {% endfor %} -{% endif %} diff --git a/tvdt/tvdt/__init__.py b/tvdt/tvdt/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tvdt/tvdt/asgi.py b/tvdt/tvdt/asgi.py deleted file mode 100644 index b88e576..0000000 --- a/tvdt/tvdt/asgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -ASGI config for tvdt project. - -It exposes the ASGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ -""" - -import os - -from django.core.asgi import get_asgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tvdt.settings") - -application = get_asgi_application() diff --git a/tvdt/tvdt/converters.py b/tvdt/tvdt/converters.py deleted file mode 100644 index dcb3a6f..0000000 --- a/tvdt/tvdt/converters.py +++ /dev/null @@ -1,14 +0,0 @@ -from quiz.models import Season - - -class SeasonCodeConverter: - regex = r"[A-Za-z\d]{5}" - - def to_python(self, value: str) -> Season: - try: - return Season.objects.get(season_code=value.upper()) - except Season.DoesNotExist: - raise ValueError - - def to_url(self, value: Season) -> str: - return value.season_code diff --git a/tvdt/tvdt/settings.py b/tvdt/tvdt/settings.py deleted file mode 100644 index c6be8d7..0000000 --- a/tvdt/tvdt/settings.py +++ /dev/null @@ -1,198 +0,0 @@ -""" -Django settings for tvdt project. - -Generated by 'django-backoffice startproject' using Django 5.1.2. - -For more information on this file, see -https://docs.djangoproject.com/en/5.1/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/5.1/ref/settings/ -""" - -from pathlib import Path - -from django.contrib import messages -from django.utils.translation import gettext_lazy as _ -from environs import Env - -env = Env() -env.read_env() -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = env.str("SECRET_KEY") - -# SECURITY WARNING: don't run with debug turned on in production! -# Override in .env for local development -DEBUG = env.bool("DEBUG", default=False) - -ALLOWED_HOSTS: list[str] = ["*"] - - -# Application definition - -INSTALLED_APPS = [ - "quiz.apps.QuizConfig", - "backoffice.apps.BackofficeConfig", - "django.contrib.admin", - "django.contrib.auth", - "django.contrib.contenttypes", - "django.contrib.sessions", - "django.contrib.messages", - "django.contrib.staticfiles", -] - -# crispy -INSTALLED_APPS += [ - "crispy_forms", - "crispy_bootstrap5", -] - -# allauth -INSTALLED_APPS += [ - "allauth", - "allauth.account", - "allauth.socialaccount", - "allauth.socialaccount.providers.google", - "allauth.socialaccount.providers.github", -] - -SOCIALACCOUNT_PROVIDERS = { - "google": { - "APP": { - "client_id": env.str("GOOGLE_CLIENT_ID"), - "secret": env.str("GOOGLE_SECRET"), - } - }, - "github": { - "VERIFIED_EMAIL": True, - "APP": { - "client_id": env.str("GITHUB_CLIENT_ID"), - "secret": env.str("GITHUB_SECRET"), - }, - }, -} - -CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" - -CRISPY_TEMPLATE_PACK = "bootstrap5" - -MIDDLEWARE = [ - "allauth.account.middleware.AccountMiddleware", - "django.middleware.security.SecurityMiddleware", - "django.contrib.sessions.middleware.SessionMiddleware", - "django.middleware.locale.LocaleMiddleware", - "django.middleware.common.CommonMiddleware", - "django.middleware.csrf.CsrfViewMiddleware", - "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.contrib.messages.middleware.MessageMiddleware", - "django.middleware.clickjacking.XFrameOptionsMiddleware", -] - -ROOT_URLCONF = "tvdt.urls" - -TEMPLATES = [ - { - "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [ - BASE_DIR / "templates", - ], - "APP_DIRS": True, - "OPTIONS": { - "context_processors": [ - "django.template.context_processors.debug", - "django.template.context_processors.request", - "django.contrib.auth.context_processors.auth", - "django.contrib.messages.context_processors.messages", - "quiz.context_processors.get_theme", - ], - }, - }, -] - -AUTHENTICATION_BACKENDS = [ - # Needed to login by username in Django backoffice, regardless of `allauth` - "django.contrib.auth.backends.ModelBackend", - # `allauth` specific authentication methods, such as login by email - "allauth.account.auth_backends.AuthenticationBackend", -] - -WSGI_APPLICATION = "tvdt.wsgi.application" - - -# Database -# https://docs.djangoproject.com/en/5.1/ref/settings/#databases - -DATABASES = {"default": env.dj_db_url("DATABASE_URL")} - -# Password validation -# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = ( - [ - { - "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", - }, - ] - if not DEBUG - else [] -) - -MESSAGE_TAGS = { - messages.DEBUG: "alert-info", - messages.INFO: "alert-info", - messages.SUCCESS: "alert-success", - messages.WARNING: "alert-warning", - messages.ERROR: "alert-danger", - 100: "alert-primary", - 110: "alert-secondary", - 120: "alert-light", - 130: "alert-dark", -} - - -# Internationalization -# https://docs.djangoproject.com/en/5.1/topics/i18n/ - -LANGUAGE_CODE = "nl" -LANGUAGES = [("nl", _("Dutch")), ("en", _("English"))] - -TIME_ZONE = "Europe/Amsterdam" - -USE_I18N = True - -USE_TZ = True - -LOCALE_PATHS = [BASE_DIR / "locale"] - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/5.1/howto/static-files/ - -STATIC_URL = "static/" -STATIC_ROOT = BASE_DIR / "staticfiles" - -# Default primary key field type -# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" - -# email is the new username -ACCOUNT_USER_MODEL_USERNAME_FIELD = None -ACCOUNT_EMAIL_REQUIRED = True -ACCOUNT_USERNAME_REQUIRED = False -ACCOUNT_AUTHENTICATION_METHOD = "email" diff --git a/tvdt/tvdt/urls.py b/tvdt/tvdt/urls.py deleted file mode 100644 index c917645..0000000 --- a/tvdt/tvdt/urls.py +++ /dev/null @@ -1,29 +0,0 @@ -""" -URL configuration for tvdt project. - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/5.1/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" - -from django.contrib import admin -from django.contrib.staticfiles.urls import urlpatterns as static_urlpatterns -from django.urls import include, path - -urlpatterns = [ - path("", include("quiz.urls")), - path("backoffice/", include("backoffice.urls")), - path("admin/", admin.site.urls), - path("accounts/", include("allauth.urls")), - path("i18n/", include("django.conf.urls.i18n")), -] -urlpatterns += static_urlpatterns diff --git a/tvdt/tvdt/wsgi.py b/tvdt/tvdt/wsgi.py deleted file mode 100644 index 9bed5b1..0000000 --- a/tvdt/tvdt/wsgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -WSGI config for tvdt 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/5.1/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tvdt.settings") - -application = get_wsgi_application()