Merge pull request 'Automatic docker image building and releasing (closes #8 #9 #11)' (#32) from dev into main
Reviewed-on: #32
This commit was merged in pull request #32.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
*.sqlite3
|
||||
*.sqlite3-journal
|
||||
|
||||
# Environments
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# VisualStudioCode
|
||||
.vscode/
|
||||
.history/
|
||||
*.vsix
|
||||
*.code-workspace
|
||||
|
||||
# Others
|
||||
.git/
|
||||
.gitignore
|
||||
.prettierignore
|
||||
.github/
|
||||
.gitea/
|
||||
|
||||
# Project specific
|
||||
/static/
|
||||
/media/
|
||||
/docs/
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: "Bug"
|
||||
about: "Report a bug"
|
||||
title: "[BUG] "
|
||||
ref: "main"
|
||||
assignees: ["kennyboy55"]
|
||||
labels:
|
||||
- bug
|
||||
---
|
||||
|
||||
Please describe the bug, and add relevant logs.
|
||||
@@ -0,0 +1,74 @@
|
||||
name: Build dev docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- main
|
||||
tags:
|
||||
- '*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
# Checkout repository for build
|
||||
- name: Checkout friend-event-rsvp repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ gitea.ref }}
|
||||
|
||||
# Login to registry
|
||||
- name: Gitea package registry login
|
||||
run: |
|
||||
echo "${{ secrets.ACCESS_TOKEN }}" | docker login gitea.furb.it \
|
||||
-u "${{ secrets.USERNAME }}" \
|
||||
--password-stdin
|
||||
|
||||
# Build image
|
||||
- name: Build Docker image - gitea.furb.it/${{ gitea.repository }}:${{ gitea.ref_name }}
|
||||
run: |
|
||||
docker build \
|
||||
-f Dockerfile \
|
||||
--label friend-event-rsvp.ref=${{ gitea.ref_name }} \
|
||||
-t gitea.furb.it/${{ gitea.repository }}:${{ gitea.ref_name }} \
|
||||
.
|
||||
|
||||
- name: Tag Docker image - gitea.furb.it/${{ gitea.repository }}:latest
|
||||
if: startsWith(gitea.ref, 'refs/tags/')
|
||||
run: |
|
||||
docker image tag \
|
||||
gitea.furb.it/${{ gitea.repository }}:${{ gitea.ref_name }} \
|
||||
gitea.furb.it/${{ gitea.repository }}:latest
|
||||
|
||||
# Push images
|
||||
- name: Push Docker image
|
||||
run: |
|
||||
docker push gitea.furb.it/${{ gitea.repository }}:${{ gitea.ref_name }}
|
||||
|
||||
- name: Push Docker image :latest
|
||||
if: startsWith(gitea.ref, 'refs/tags/')
|
||||
run: |
|
||||
docker push gitea.furb.it/${{ gitea.repository }}:latest
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: startsWith(gitea.ref, 'refs/tags/')
|
||||
steps:
|
||||
# Create release using gitea-release-action
|
||||
- name: Create release
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
server: "https://gitea.furb.it"
|
||||
token: ${{ secrets.ACCESS_TOKEN }}
|
||||
repository: ${{ gitea.repository }}
|
||||
tag_name: ${{ gitea.ref_name }}
|
||||
name: ${{ gitea.ref_name }}
|
||||
body: |
|
||||
"## Docker images"
|
||||
"`gitea.furb.it/${{ gitea.repository }}:${{ gitea.ref_name }}`"
|
||||
"`gitea.furb.it/${{ gitea.repository }}:latest`"
|
||||
+3
-99
@@ -62,32 +62,6 @@ local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# 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
|
||||
@@ -95,39 +69,6 @@ ipython_config.py
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# UV
|
||||
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
#uv.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
|
||||
@@ -137,43 +78,6 @@ 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/
|
||||
|
||||
# Ruff stuff:
|
||||
.ruff_cache/
|
||||
|
||||
# PyPI configuration file
|
||||
.pypirc
|
||||
|
||||
# ---> VisualStudioCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
@@ -188,6 +92,6 @@ cython_debug/
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# Custom
|
||||
events/static/img/*
|
||||
!events/static/img/placeholder*.jpg
|
||||
# Project specific
|
||||
/static/
|
||||
/media/
|
||||
@@ -0,0 +1,4 @@
|
||||
# ignored files - prettier interferes with django templates and github actions
|
||||
*.html
|
||||
*.yml
|
||||
*.yaml
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["otovo-oss.htmx-tags", "esbenp.prettier-vscode"]
|
||||
}
|
||||
Vendored
+19
-19
@@ -1,20 +1,20 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Python Debugger: Django",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"runserver"
|
||||
],
|
||||
"django": true,
|
||||
"autoStartBrowser": false,
|
||||
"program": "${workspaceFolder}/manage.py"
|
||||
}
|
||||
]
|
||||
}
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python Debugger: Django",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"args": ["runserver"],
|
||||
"django": true,
|
||||
"autoStartBrowser": false,
|
||||
"program": "${workspaceFolder}/manage.py",
|
||||
"env": {
|
||||
"DEBUG": "1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
+4
-9
@@ -1,17 +1,12 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[python]": {
|
||||
"editor.formatOnType": true,
|
||||
"editor.defaultFormatter": "ms-python.black-formatter"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
},
|
||||
"python.analysis.autoImportCompletions": true,
|
||||
"python.analysis.autoFormatStrings": true,
|
||||
"python.analysis.completeFunctionParens": true,
|
||||
"python.analysis.enableTroubleshootMissingImports": true,
|
||||
"github.copilot.editor.enableCodeActions": false,
|
||||
"github.copilot.enable": {
|
||||
"*": false,
|
||||
"plaintext": false,
|
||||
"markdown": false,
|
||||
"scminput": false
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Enable environment",
|
||||
"type": "shell",
|
||||
"command": "pipenv shell",
|
||||
"runOptions": {
|
||||
"runOn": "folderOpen"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Update python packages",
|
||||
"type": "shell",
|
||||
"command": "pipenv update"
|
||||
},
|
||||
{
|
||||
"label": "Make Migrations",
|
||||
"type": "shell",
|
||||
"command": "python3 manage.py makemigrations"
|
||||
},
|
||||
{
|
||||
"label": "Run Migrations",
|
||||
"type": "shell",
|
||||
"command": "python3 manage.py migrate"
|
||||
},
|
||||
{
|
||||
"label": "Setup Dev Server",
|
||||
"dependsOn": ["Make Migrations", "Run Migrations"]
|
||||
},
|
||||
{
|
||||
"label": "Run Dev Server",
|
||||
"type": "shell",
|
||||
"dependsOn": ["Setup Dev Server"],
|
||||
"command": "DEBUG=1 python3 manage.py runserver"
|
||||
}
|
||||
]
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
FROM python:3.12-alpine3.23
|
||||
|
||||
LABEL maintainer="Kenneth van Ewijk (kennyboy55)"
|
||||
|
||||
# Add dependencies
|
||||
#RUN apk add --no-cache postgresql-libs postgresql-client
|
||||
RUN apk add --no-cache tini
|
||||
|
||||
# Install pipenv
|
||||
RUN pip install pipenv
|
||||
|
||||
#Print all logs without buffering it.
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
DOCKER=true
|
||||
|
||||
#Create app dir
|
||||
RUN mkdir -p /opt/rsvp
|
||||
RUN mkdir -p /opt/rsvp/static
|
||||
WORKDIR /opt/rsvp
|
||||
|
||||
# Copy Pipfile and Pipfile.lock
|
||||
COPY Pipfile Pipfile.lock ./
|
||||
|
||||
# Install python dependencies
|
||||
RUN pipenv install --deploy --system
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
RUN mkdir -p /data
|
||||
|
||||
# The volume containing dynamic data
|
||||
VOLUME /data
|
||||
|
||||
#This port will be used by daphne
|
||||
EXPOSE 8000
|
||||
|
||||
# Run the application
|
||||
RUN chmod +x start.sh
|
||||
ENTRYPOINT ["/sbin/tini", "--", "/opt/rsvp/start.sh"]
|
||||
@@ -4,8 +4,13 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
channels = {version = "*", extras = ["daphne", "types"]}
|
||||
daphne = "*"
|
||||
django = "*"
|
||||
django-markdown = "*"
|
||||
pillow = "*"
|
||||
blacknoise = "*"
|
||||
twisted = {extras = ["http2", "tls"], version = "*"}
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
||||
Generated
+657
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "7899ae66bf28a24ee2f8c26aa923021a00ce17118ca4adcc9d7c3da571133239"
|
||||
"sha256": "07e2a33b6016199f2401424d35bc436e5355db12dd734f543d2633b4dd31a22d"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -16,6 +16,14 @@
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"anyio": {
|
||||
"hashes": [
|
||||
"sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708",
|
||||
"sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==4.13.0"
|
||||
},
|
||||
"asgiref": {
|
||||
"hashes": [
|
||||
"sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce",
|
||||
@@ -24,6 +32,278 @@
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==3.11.1"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309",
|
||||
"sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==26.1.0"
|
||||
},
|
||||
"autobahn": {
|
||||
"hashes": [
|
||||
"sha256:0ad4c10c897ad67d31be2ef8547ed2922875d90ddb95553787cc46c271f822de",
|
||||
"sha256:0c226329ddec154c6f3b491ea3e4713035f0326c96ebfd6b305bf90f27a2fba1",
|
||||
"sha256:16df879672c60f1f3fe452138c80f0fd221b3cb2ee5a14390c80f33b994104c1",
|
||||
"sha256:18b12e8af7fc115487715afa10b3f5b5a4b5989bebbe05b71722cf9fce7b1bfb",
|
||||
"sha256:220748f21e91bd4a538d2d3de640cc17ee30b79f1c04a6c3dcdef321d531ee1c",
|
||||
"sha256:3ec6a3719a00fd57b044e4694f3d6e9335892f4ef21f045f090495da7385d240",
|
||||
"sha256:5f079393a7626eb448c8accf21151f5f206d02f8e9cee4313d62a5ca30a3aaed",
|
||||
"sha256:6ffe28048ef96eb0f925f24c2569bd72332e120f4cb31cd6c40dd66718a5f85e",
|
||||
"sha256:754c06a54753aeb7e8d10c5cbf03249ad9e2a1a32bca8be02865c6f00628a98c",
|
||||
"sha256:9abda5cf817c0f8a19a55a67a031adf2fc70ed351719b5bd9e6fa0f5f4bc8f89",
|
||||
"sha256:9b3a6c7d54a9f0434a435d88b86555510e5d0a84aa87042e292f29f707cab237",
|
||||
"sha256:b5297a782fc7d0a26842438ef1342549ceee29496cda52672ac44635c79eeb94",
|
||||
"sha256:ba1867aafdbe585d3d4a5abd35238a78ab54ab3de5bd12a21bca20379c9f512b",
|
||||
"sha256:bc17f6cab9438156d2701c293c76fd02a144f9be0a992c065dfee1935ce4845b",
|
||||
"sha256:c0c3f1d5dafda52f8dc962ab583b6f3473b7b7186cab082d05372ed43a8261a5",
|
||||
"sha256:c840ee136bfaf6560467160129b0b25a0e33c9a51e2b251e98c5474f27583915",
|
||||
"sha256:e9e2a962f2de0bc4c53b452916458417a15f5137c956245ac6d0a783a83fa1f7"
|
||||
],
|
||||
"markers": "python_version >= '3.11'",
|
||||
"version": "==25.12.2"
|
||||
},
|
||||
"automat": {
|
||||
"hashes": [
|
||||
"sha256:0017591a5477066e90d26b0e696ddc143baafd87b588cfac8100bc6be9634de0",
|
||||
"sha256:04e9bce696a8d5671ee698005af6e5a9fa15354140a87f4870744604dcdd3ba1"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==25.4.16"
|
||||
},
|
||||
"blacknoise": {
|
||||
"hashes": [
|
||||
"sha256:1914b179ed37c237e3b914f759afb926371dd60f87649684b5e17a9c55c60b32",
|
||||
"sha256:e44d38fbabba18dffb682d9463b670b63c4fbc94c128263aa1a6365618912593"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"cbor2": {
|
||||
"hashes": [
|
||||
"sha256:0322296b9d52f55880e300ba8ba09ecf644303b99b51138bbb1c0fb644fa7c3e",
|
||||
"sha256:0485d3372fc832c5e16d4eb45fa1a20fc53e806e6c29a1d2b0d3e176cedd52b9",
|
||||
"sha256:08388ea54195738602b4c4999966bcaef6f0b17d293c9658658409d9fff96f57",
|
||||
"sha256:1d02b65f070fd726bdc310d927228975bb655d155bf059b6eb7cacefb3dca86f",
|
||||
"sha256:1da96ce5d852fe3d342c1eb2c202a52d1c97edfddc9230f1be7e02674662bf26",
|
||||
"sha256:1f223dffb1bcdd2764665f04c1152943d9daa4bc124a576cd8dee1cad4264313",
|
||||
"sha256:23606d31ba1368bd1b6602e3020ee88fe9523ca80e8630faf6b2fc904fd84560",
|
||||
"sha256:2372d357d403e7912f104ff085950ffc82a5854d6d717f1ca1ce16a40a0ef5a7",
|
||||
"sha256:25bec7beb2089465382b1be72e78667fe9090598800826559c3e3008cf0db743",
|
||||
"sha256:27695cbd70c90b8de5c4a284642c2836449b14e2c2e07e3ffe0744cb7669a01b",
|
||||
"sha256:2a54fbb32cb828c214f7f333a707e4aec61182e7efdc06ea5d9596d3ecee624a",
|
||||
"sha256:3095dc49e75572841a9534cbfdabc2a17487ea4ee33341436abc4a7ac7245a3a",
|
||||
"sha256:34a6cb15e6ab6a8eae94ad2041731cd3ef786af43a8df99f847969af5b902ee7",
|
||||
"sha256:380e534482b843e43442b87d8777a7bf9bed20cb7526f89b780c3400f617304b",
|
||||
"sha256:420d2490c7836c81151b4bd591c35cffc55391e33e7e333c50fda391bcea7d31",
|
||||
"sha256:422817286c1d0ce947fb2f7eca9212b39bddd7231e8b452e2d2cc52f15332dba",
|
||||
"sha256:4753a6d1bc71054d9179557bc65740860f185095ccb401d46637fff028a5b3ec",
|
||||
"sha256:4aa07b392cc3d76fb31c08a46a226b58c320d1c172ff3073e864409ced7bc50f",
|
||||
"sha256:4cd43d8fc374b31643b2830910f28177a606a7bc84975a62675dd3f2e320fc7b",
|
||||
"sha256:5326336f633cc89dfe543c78829c16c3a6449c2c03277d1ddba99086c3323363",
|
||||
"sha256:53cfa49e0df9c639beb871d480de098eedc81eb63ff29f2dc922720d7577b676",
|
||||
"sha256:55bea0dd9a7d354e35f4e5fe58ceab393e76962713749dc3a0a64a0e5d19545e",
|
||||
"sha256:5e702b02d42a5ace45425b595ffe70fe35aebaf9a3cdfdc2c758b6189c744422",
|
||||
"sha256:65f8eac3268c608533f326f0fd9010ab1b2a8a917b05edaf3853116336821669",
|
||||
"sha256:7221483fad0c63afa4244624d552abf89d7dfdbc5f5edfc56fc1ff2b4b818975",
|
||||
"sha256:7d1ddc4541e7367ac58c2470cc0df847f7137167fe4f5729e2d3cc0b993d7da4",
|
||||
"sha256:837754ece9052b3f607047e1741e5f852a538aa2b0ee3db11c82a8fa11804aa4",
|
||||
"sha256:85c7a46279ac8f226e1059275221e6b3d0e370d2bb6bd0500f9780781615bcea",
|
||||
"sha256:86baf870d4c0bfc6f79de3801f3860a84ab76d9c8b0abb7f081f2c14c38d79d3",
|
||||
"sha256:971d425b3a23b75953d8853d5f9911bdeefa09d759ee3b5e6b07b5ff3cbd9073",
|
||||
"sha256:9a4907e0c3035bb8836116854ed8e56d8aef23909d601fa59706320897ec2551",
|
||||
"sha256:a9d6e4e0f988b0e766509a8071975a8ee99f930e14a524620bf38083106158d2",
|
||||
"sha256:ac684fe195c39821fca70d18afbf748f728aefbfbf88456018d299e559b8cae0",
|
||||
"sha256:ae6c706ac1d85a0b3cb3395308fd0c4d55e3202b4760773675957e93cdff45fc",
|
||||
"sha256:cc5efec69055c3c470997935d95762be7e4bfd1248d88fb1a33bb7e0f45712e9",
|
||||
"sha256:d1a21c006760f95acd9509cc5a7d15d6fc82e58f721f94fa9039b4e77189a6e5",
|
||||
"sha256:d8524a8c142c3cc228e635f8a97499a6c0b18ca91382e8276565658035cdcb6d",
|
||||
"sha256:dcf0f695873e5c94bd072d6af8698e72b8fb7f7a18f37e0bced1041b7111a6cf",
|
||||
"sha256:f29e5c3abcc91c1aeefecde0e057bf33f1655588d3065c6560c30ceb3be6f333",
|
||||
"sha256:f797532d13469f2193e5c16e827d8df7a8c33674b19be755790b54ab231e6a73",
|
||||
"sha256:f7c9751a9611601ab326d8f5837f01379195bbf06175fb4effeb552140e7c9e8",
|
||||
"sha256:fb7afe77f8d269e42d7c4b515c6fd14f1ccc0625379fb6829b269f493d16eddd",
|
||||
"sha256:fbb06f34aa645b4deca66643bba3d400d20c15312d1fe88d429be60c1ab50f27",
|
||||
"sha256:fbdcf4d74acbeb7672e6413e81cd2c1ced1a4a8cf949484ac54e9af5265c3c72"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==5.9.0"
|
||||
},
|
||||
"cffi": {
|
||||
"hashes": [
|
||||
"sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb",
|
||||
"sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b",
|
||||
"sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f",
|
||||
"sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9",
|
||||
"sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44",
|
||||
"sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2",
|
||||
"sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c",
|
||||
"sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75",
|
||||
"sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65",
|
||||
"sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e",
|
||||
"sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a",
|
||||
"sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e",
|
||||
"sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25",
|
||||
"sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a",
|
||||
"sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe",
|
||||
"sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b",
|
||||
"sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91",
|
||||
"sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592",
|
||||
"sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187",
|
||||
"sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c",
|
||||
"sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1",
|
||||
"sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94",
|
||||
"sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba",
|
||||
"sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb",
|
||||
"sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165",
|
||||
"sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529",
|
||||
"sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca",
|
||||
"sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c",
|
||||
"sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6",
|
||||
"sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c",
|
||||
"sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0",
|
||||
"sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743",
|
||||
"sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63",
|
||||
"sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5",
|
||||
"sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5",
|
||||
"sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4",
|
||||
"sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d",
|
||||
"sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b",
|
||||
"sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93",
|
||||
"sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205",
|
||||
"sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27",
|
||||
"sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512",
|
||||
"sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d",
|
||||
"sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c",
|
||||
"sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037",
|
||||
"sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26",
|
||||
"sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322",
|
||||
"sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb",
|
||||
"sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c",
|
||||
"sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8",
|
||||
"sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4",
|
||||
"sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414",
|
||||
"sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9",
|
||||
"sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664",
|
||||
"sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9",
|
||||
"sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775",
|
||||
"sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739",
|
||||
"sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc",
|
||||
"sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062",
|
||||
"sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe",
|
||||
"sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9",
|
||||
"sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92",
|
||||
"sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5",
|
||||
"sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13",
|
||||
"sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d",
|
||||
"sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26",
|
||||
"sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f",
|
||||
"sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495",
|
||||
"sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b",
|
||||
"sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6",
|
||||
"sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c",
|
||||
"sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef",
|
||||
"sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5",
|
||||
"sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18",
|
||||
"sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad",
|
||||
"sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3",
|
||||
"sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7",
|
||||
"sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5",
|
||||
"sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534",
|
||||
"sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49",
|
||||
"sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2",
|
||||
"sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5",
|
||||
"sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453",
|
||||
"sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"channels": {
|
||||
"extras": [
|
||||
"daphne",
|
||||
"types"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:f2bb6bfb73ad7fb4705041d07613c7b4e69528f01ef8cb9fb6c21d9295f15667",
|
||||
"sha256:fef47e9055a603900cf16cef85f050d522d9ac4b3daccf24835bd9580705c176"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==4.3.2"
|
||||
},
|
||||
"constantly": {
|
||||
"hashes": [
|
||||
"sha256:3fd9b4d1c3dc1ec9757f3c52aef7e53ad9323dbe39f51dfd4c43853b68dfa3f9",
|
||||
"sha256:aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==23.10.4"
|
||||
},
|
||||
"cryptography": {
|
||||
"hashes": [
|
||||
"sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70",
|
||||
"sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d",
|
||||
"sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a",
|
||||
"sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0",
|
||||
"sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97",
|
||||
"sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30",
|
||||
"sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759",
|
||||
"sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c",
|
||||
"sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead",
|
||||
"sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275",
|
||||
"sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58",
|
||||
"sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f",
|
||||
"sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361",
|
||||
"sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507",
|
||||
"sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa",
|
||||
"sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b",
|
||||
"sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b",
|
||||
"sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8",
|
||||
"sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8",
|
||||
"sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72",
|
||||
"sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175",
|
||||
"sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e",
|
||||
"sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124",
|
||||
"sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a",
|
||||
"sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c",
|
||||
"sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f",
|
||||
"sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d",
|
||||
"sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4",
|
||||
"sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c",
|
||||
"sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290",
|
||||
"sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca",
|
||||
"sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d",
|
||||
"sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a",
|
||||
"sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed",
|
||||
"sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a",
|
||||
"sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb",
|
||||
"sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8",
|
||||
"sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707",
|
||||
"sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410",
|
||||
"sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736",
|
||||
"sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2",
|
||||
"sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4",
|
||||
"sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013",
|
||||
"sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19",
|
||||
"sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b",
|
||||
"sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738",
|
||||
"sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463",
|
||||
"sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77",
|
||||
"sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4"
|
||||
],
|
||||
"markers": "python_version >= '3.8' and python_full_version not in '3.9.0, 3.9.1'",
|
||||
"version": "==46.0.6"
|
||||
},
|
||||
"daphne": {
|
||||
"hashes": [
|
||||
"sha256:5f898e700a1fda7addf1541d7c328606415e96a7bd768405f0463c312fcb31b3",
|
||||
"sha256:881e96b387b95b35ad85acd855f229d7f5b79073d6649089c8a33f661885e055"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==4.2.1"
|
||||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:2e5974441491ddb34c3f13d5e7a9f97b07ba03bf70234c0a9c68b79bbb235bc3",
|
||||
@@ -33,6 +313,159 @@
|
||||
"markers": "python_version >= '3.12'",
|
||||
"version": "==6.0.3"
|
||||
},
|
||||
"django-markdown": {
|
||||
"hashes": [
|
||||
"sha256:118d3a3b0dda0279785c007720fe594ccf9fa4cc1d6cee878bb81d36a02dd668",
|
||||
"sha256:bab6719cac47c7139c9f489816a99fd656caa56d364a2b7d2137db698219b402"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.8.4"
|
||||
},
|
||||
"django-stubs": {
|
||||
"hashes": [
|
||||
"sha256:d885044bd0876610f3eb969d6b5ed22f386002a879fdcb369cd8efa0502dbbce",
|
||||
"sha256:e1ca63634221b57a55e16562b9b6d1849aeee2cabfd0fc026084dbe8aa893366"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==6.0.1"
|
||||
},
|
||||
"django-stubs-ext": {
|
||||
"hashes": [
|
||||
"sha256:17415759b9a3f4b4da7998ac3b08c7dc5137f9a019490b918aece1a8a4c2ade4",
|
||||
"sha256:633b280f89c0cbb7e3ce2f2f842e0acc43d8091378e75f84921d6be675d052dc"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==6.0.1"
|
||||
},
|
||||
"h2": {
|
||||
"hashes": [
|
||||
"sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1",
|
||||
"sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd"
|
||||
],
|
||||
"version": "==4.3.0"
|
||||
},
|
||||
"hpack": {
|
||||
"hashes": [
|
||||
"sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496",
|
||||
"sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==4.1.0"
|
||||
},
|
||||
"hyperframe": {
|
||||
"hashes": [
|
||||
"sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5",
|
||||
"sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==6.1.0"
|
||||
},
|
||||
"hyperlink": {
|
||||
"hashes": [
|
||||
"sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b",
|
||||
"sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"
|
||||
],
|
||||
"version": "==21.0.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea",
|
||||
"sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"
|
||||
],
|
||||
"version": "==3.11"
|
||||
},
|
||||
"incremental": {
|
||||
"hashes": [
|
||||
"sha256:87d3480dbb083c1d736222511a8cf380012a8176c2456d01ef483242abbbcf8c",
|
||||
"sha256:a34450716b1c4341fe6676a0598e88a39e04189f4dce5dc96f656e040baa10b3"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==24.11.0"
|
||||
},
|
||||
"markdown": {
|
||||
"hashes": [
|
||||
"sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950",
|
||||
"sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==3.10.2"
|
||||
},
|
||||
"msgpack": {
|
||||
"hashes": [
|
||||
"sha256:0051fffef5a37ca2cd16978ae4f0aef92f164df86823871b5162812bebecd8e2",
|
||||
"sha256:04fb995247a6e83830b62f0b07bf36540c213f6eac8e851166d8d86d83cbd014",
|
||||
"sha256:180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931",
|
||||
"sha256:1d1418482b1ee984625d88aa9585db570180c286d942da463533b238b98b812b",
|
||||
"sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b",
|
||||
"sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999",
|
||||
"sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029",
|
||||
"sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0",
|
||||
"sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9",
|
||||
"sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c",
|
||||
"sha256:350ad5353a467d9e3b126d8d1b90fe05ad081e2e1cef5753f8c345217c37e7b8",
|
||||
"sha256:354e81bcdebaab427c3df4281187edc765d5d76bfb3a7c125af9da7a27e8458f",
|
||||
"sha256:365c0bbe981a27d8932da71af63ef86acc59ed5c01ad929e09a0b88c6294e28a",
|
||||
"sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42",
|
||||
"sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e",
|
||||
"sha256:41d1a5d875680166d3ac5c38573896453bbbea7092936d2e107214daf43b1d4f",
|
||||
"sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7",
|
||||
"sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb",
|
||||
"sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef",
|
||||
"sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf",
|
||||
"sha256:5559d03930d3aa0f3aacb4c42c776af1a2ace2611871c84a75afe436695e6245",
|
||||
"sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794",
|
||||
"sha256:59415c6076b1e30e563eb732e23b994a61c159cec44deaf584e5cc1dd662f2af",
|
||||
"sha256:5a46bf7e831d09470ad92dff02b8b1ac92175ca36b087f904a0519857c6be3ff",
|
||||
"sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e",
|
||||
"sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296",
|
||||
"sha256:67016ae8c8965124fdede9d3769528ad8284f14d635337ffa6a713a580f6c030",
|
||||
"sha256:6bde749afe671dc44893f8d08e83bf475a1a14570d67c4bb5cec5573463c8833",
|
||||
"sha256:6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939",
|
||||
"sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa",
|
||||
"sha256:70c5a7a9fea7f036b716191c29047374c10721c389c21e9ffafad04df8c52c90",
|
||||
"sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c",
|
||||
"sha256:80a0ff7d4abf5fecb995fcf235d4064b9a9a8a40a3ab80999e6ac1e30b702717",
|
||||
"sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406",
|
||||
"sha256:897c478140877e5307760b0ea66e0932738879e7aa68144d9b78ea4c8302a84a",
|
||||
"sha256:8b696e83c9f1532b4af884045ba7f3aa741a63b2bc22617293a2c6a7c645f251",
|
||||
"sha256:8e22ab046fa7ede9e36eeb4cfad44d46450f37bb05d5ec482b02868f451c95e2",
|
||||
"sha256:94fd7dc7d8cb0a54432f296f2246bc39474e017204ca6f4ff345941d4ed285a7",
|
||||
"sha256:99e2cb7b9031568a2a5c73aa077180f93dd2e95b4f8d3b8e14a73ae94a9e667e",
|
||||
"sha256:9ade919fac6a3e7260b7f64cea89df6bec59104987cbea34d34a2fa15d74310b",
|
||||
"sha256:9fba231af7a933400238cb357ecccf8ab5d51535ea95d94fc35b7806218ff844",
|
||||
"sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9",
|
||||
"sha256:a605409040f2da88676e9c9e5853b3449ba8011973616189ea5ee55ddbc5bc87",
|
||||
"sha256:a668204fa43e6d02f89dbe79a30b0d67238d9ec4c5bd8a940fc3a004a47b721b",
|
||||
"sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c",
|
||||
"sha256:a8f6e7d30253714751aa0b0c84ae28948e852ee7fb0524082e6716769124bc23",
|
||||
"sha256:ad09b984828d6b7bb52d1d1d0c9be68ad781fa004ca39216c8a1e63c0f34ba3c",
|
||||
"sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e",
|
||||
"sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620",
|
||||
"sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69",
|
||||
"sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f",
|
||||
"sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68",
|
||||
"sha256:d62ce1f483f355f61adb5433ebfd8868c5f078d1a52d042b0a998682b4fa8c27",
|
||||
"sha256:d99ef64f349d5ec3293688e91486c5fdb925ed03807f64d98d205d2713c60b46",
|
||||
"sha256:db6192777d943bdaaafb6ba66d44bf65aa0e9c5616fa1d2da9bb08828c6b39aa",
|
||||
"sha256:e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00",
|
||||
"sha256:e64c8d2f5e5d5fda7b842f55dec6133260ea8f53c4257d64494c534f306bf7a9",
|
||||
"sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84",
|
||||
"sha256:ea5405c46e690122a76531ab97a079e184c0daf491e588592d6a23d3e32af99e",
|
||||
"sha256:f2cb069d8b981abc72b41aea1c580ce92d57c673ec61af4c500153a626cb9e20",
|
||||
"sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e",
|
||||
"sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162"
|
||||
],
|
||||
"markers": "platform_python_implementation == 'CPython'",
|
||||
"version": "==1.1.2"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4",
|
||||
"sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==26.0"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9",
|
||||
@@ -131,6 +564,57 @@
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==12.1.1"
|
||||
},
|
||||
"priority": {
|
||||
"hashes": [
|
||||
"sha256:6bc1961a6d7fcacbfc337769f1a382c8e746566aaa365e78047abe9f66b2ffbe",
|
||||
"sha256:be4fcb94b5e37cdeb40af5533afe6dd603bd665fe9c8b3052610fc1001d5d1eb"
|
||||
],
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"py-ubjson": {
|
||||
"hashes": [
|
||||
"sha256:b9bfb8695a1c7e3632e800fb83c943bf67ed45ddd87cd0344851610c69a5a482"
|
||||
],
|
||||
"version": "==0.16.1"
|
||||
},
|
||||
"pyasn1": {
|
||||
"hashes": [
|
||||
"sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf",
|
||||
"sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==0.6.3"
|
||||
},
|
||||
"pyasn1-modules": {
|
||||
"hashes": [
|
||||
"sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a",
|
||||
"sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==0.4.2"
|
||||
},
|
||||
"pycparser": {
|
||||
"hashes": [
|
||||
"sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29",
|
||||
"sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"
|
||||
],
|
||||
"markers": "implementation_name != 'PyPy'",
|
||||
"version": "==3.0"
|
||||
},
|
||||
"pyopenssl": {
|
||||
"hashes": [
|
||||
"sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81",
|
||||
"sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc"
|
||||
],
|
||||
"version": "==26.0.0"
|
||||
},
|
||||
"service-identity": {
|
||||
"hashes": [
|
||||
"sha256:6b047fbd8a84fd0bb0d55ebce4031e400562b9196e1e0d3e0fe2b8a59f6d4a85",
|
||||
"sha256:b8683ba13f0d39c6cd5d625d2c5f65421d6d707b013b375c355751557cbe8e09"
|
||||
],
|
||||
"version": "==24.2.0"
|
||||
},
|
||||
"sqlparse": {
|
||||
"hashes": [
|
||||
"sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba",
|
||||
@@ -138,6 +622,178 @@
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==0.5.5"
|
||||
},
|
||||
"starlette": {
|
||||
"hashes": [
|
||||
"sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149",
|
||||
"sha256:d3ec55e0bb321692d275455ddfd3df75fff145d009685eb40dc91fc66b03d38b"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==1.0.0"
|
||||
},
|
||||
"twisted": {
|
||||
"extras": [
|
||||
"http2",
|
||||
"tls"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:1deb272358cb6be1e3e8fc6f9c8b36f78eb0fa7c2233d2dbe11ec6fee04ea316",
|
||||
"sha256:8559f654d01a54a8c3efe66d533d43f383531ebf8d81d9f9ab4769d91ca15df7"
|
||||
],
|
||||
"markers": "python_full_version >= '3.8.0'",
|
||||
"version": "==25.5.0"
|
||||
},
|
||||
"txaio": {
|
||||
"hashes": [
|
||||
"sha256:5f6cd6c6b397fc3305790d15efd46a2d5b91cdbefa96543b4f8666aeb56ba026",
|
||||
"sha256:9f232c21e12aa1ff52690e365b5a0ecfd42cc27a6ec86e1b92ece88f763f4b78"
|
||||
],
|
||||
"markers": "python_version >= '3.11'",
|
||||
"version": "==25.12.2"
|
||||
},
|
||||
"types-channels": {
|
||||
"hashes": [
|
||||
"sha256:9aaf517b5bb6599a8ba115859ead443b7ab711745760574e6761fd2979192121",
|
||||
"sha256:fa09eead7716581354fa0ff313a5685e4d54fb6e386b565404ae36607fdb65d4"
|
||||
],
|
||||
"version": "==4.3.0.20260321"
|
||||
},
|
||||
"types-pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3",
|
||||
"sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==6.0.12.20250915"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466",
|
||||
"sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==4.15.0"
|
||||
},
|
||||
"ujson": {
|
||||
"hashes": [
|
||||
"sha256:006428d3813b87477d72d306c40c09f898a41b968e57b15a7d88454ecc42a3fb",
|
||||
"sha256:02f93da7a4115e24f886b04fd56df1ee8741c2ce4ea491b7ab3152f744ad8f8e",
|
||||
"sha256:0727363b05ab05ee737a28f6200dc4078bce6b0508e10bd8aab507995a15df61",
|
||||
"sha256:085b6ce182cdd6657481c7c4003a417e0655c4f6e58b76f26ee18f0ae21db827",
|
||||
"sha256:09b4beff9cc91d445d5818632907b85fb06943b61cb346919ce202668bf6794a",
|
||||
"sha256:0a3ae28f0b209be5af50b54ca3e2123a3de3a57d87b75f1e5aa3d7961e041983",
|
||||
"sha256:0d2e8db5ade3736a163906154ca686203acc7d1d30736cbf577c730d13653d84",
|
||||
"sha256:0e00cec383eab2406c9e006bd4edb55d284e94bb943fda558326048178d26961",
|
||||
"sha256:0fe6b8b8968e11dd9b2348bd508f0f57cf49ab3512064b36bc4117328218718e",
|
||||
"sha256:0fe9128e75c6aa6e9ae06c1408d6edd9179a2fef0fe6d9cda3166b887eba521d",
|
||||
"sha256:14b2e1eb528d77bc0f4c5bd1a7ebc05e02b5b41beefb7e8567c9675b8b13bcf4",
|
||||
"sha256:15d416440148f3e56b9b244fdaf8a09fcf5a72e4944b8e119f5bf60417a2bfc8",
|
||||
"sha256:15e555c4caca42411270b2ed2b2ebc7b3a42bb04138cef6c956e1f1d49709fe2",
|
||||
"sha256:16b4fe9c97dc605f5e1887a9e1224287291e35c56cbc379f8aa44b6b7bcfe2bb",
|
||||
"sha256:1b5c6ceb65fecd28a1d20d1eba9dbfa992612b86594e4b6d47bb580d2dd6bcb3",
|
||||
"sha256:1d072a403d82aef8090c6d4f728e3a727dfdba1ad3b7fa3a052c3ecbd37e73cb",
|
||||
"sha256:2324d9a0502317ffc35d38e153c1b2fa9610ae03775c9d0f8d0cca7b8572b04e",
|
||||
"sha256:2a248750abce1c76fbd11b2e1d88b95401e72819295c3b851ec73399d6849b3d",
|
||||
"sha256:2ea6206043385343aff0b7da65cf73677f6f5e50de8f1c879e557f4298cac36a",
|
||||
"sha256:31348a0ffbfc815ce78daac569d893349d85a0b57e1cd2cdbba50b7f333784da",
|
||||
"sha256:38051f36423f084b909aaadb3b41c9c6a2958e86956ba21a8489636911e87504",
|
||||
"sha256:3c2f947e55d3c7cfe124dd4521ee481516f3007d13c6ad4bf6aeb722e190eb1b",
|
||||
"sha256:3ed5cb149892141b1e77ef312924a327f2cc718b34247dae346ed66329e1b8be",
|
||||
"sha256:3ff4ede90ed771140caa7e1890de17431763a483c54b3c1f88bd30f0cc1affc0",
|
||||
"sha256:40aa43a7a3a8d2f05e79900858053d697a88a605e3887be178b43acbcd781161",
|
||||
"sha256:42d875388fbd091c7ea01edfff260f839ba303038ffb23475ef392012e4d63dd",
|
||||
"sha256:457fabc2700a8e6ddb85bc5a1d30d3345fe0d3ec3ee8161a4e032ec585801dfa",
|
||||
"sha256:460e76a4daff214ae33ab959494962c93918cb44714ea3e3f748b14aa37f8a87",
|
||||
"sha256:50524f4f6a1c839714dbaff5386a1afb245d2d5ec8213a01fbc99cea7307811e",
|
||||
"sha256:51acc750ec7a2df786cdc868fb16fa04abd6269a01d58cf59bafc57978773d8e",
|
||||
"sha256:55ede2a7a051b3b7e71a394978a098d71b3783e6b904702ff45483fad434ae2d",
|
||||
"sha256:561f89cc82deeae82e37d4a4764184926fb432f740a9691563a391b13f7339a4",
|
||||
"sha256:56ba3f7abbd6b0bb282a544dc38406d1a188d8bb9164f49fdb9c2fee62cb29da",
|
||||
"sha256:57930ac9519099b852e190d2c04b1fb5d97ea128db33bce77ed874eccb4c7f09",
|
||||
"sha256:58a11cb49482f1a095a2bd9a1d81dd7c8fb5d2357f959ece85db4e46a825fd00",
|
||||
"sha256:64df53eef4ac857eb5816a56e2885ccf0d7dff6333c94065c93b39c51063e01d",
|
||||
"sha256:6879aed770557f0961b252648d36f6fdaab41079d37a2296b5649fd1b35608e0",
|
||||
"sha256:6ad57654570464eb1b040b5c353dee442608e06cff9102b8fcb105565a44c9ed",
|
||||
"sha256:6c0aed6a4439994c9666fb8a5b6c4eac94d4ef6ddc95f9b806a599ef83547e3b",
|
||||
"sha256:76bf3e7406cf23a3e1ca6a23fb1fb9ea82f4f6bd226fe226e09146b0194f85dc",
|
||||
"sha256:7bbf05c38debc90d1a195b11340cc85cb43ab3e753dc47558a3a84a38cbc72da",
|
||||
"sha256:7ddb08b3c2f9213df1f2e3eb2fbea4963d80ec0f8de21f0b59898e34f3b3d96d",
|
||||
"sha256:7e07f6f644d2c44d53b7a320a084eef98063651912c1b9449b5f45fcbdc6ccd2",
|
||||
"sha256:85833bca01aa5cae326ac759276dc175c5fa3f7b3733b7d543cf27f2df12d1ef",
|
||||
"sha256:8712b61eb1b74a4478cfd1c54f576056199e9f093659334aeb5c4a6b385338e5",
|
||||
"sha256:871c0e5102e47995b0e37e8df7819a894a6c3da0d097545cd1f9f1f7d7079927",
|
||||
"sha256:89e302abd3749f6d6699691747969a5d85f7c73081d5ed7e2624c7bd9721a2ab",
|
||||
"sha256:937794042342006f707837f38d721426b11b0774d327a2a45c0bd389eb750a87",
|
||||
"sha256:93bc91fdadcf046da37a214eaa714574e7e9b1913568e93bb09527b2ceb7f759",
|
||||
"sha256:94c5f1621cbcab83c03be46441f090b68b9f307b6c7ec44d4e3f6d5997383df4",
|
||||
"sha256:973b7d7145b1ac553a7466a64afa8b31ec2693d7c7fff6a755059e0a2885dfd2",
|
||||
"sha256:99cc80facad240b0c2fb5a633044420878aac87a8e7c348b9486450cba93f27c",
|
||||
"sha256:9a5fcbe7b949f2e95c47ea8a80b410fcdf2da61c98553b45a4ee875580418b68",
|
||||
"sha256:9b3b86ec3e818f3dd3e13a9de628e88a9990f4af68ecb0b12dd3de81227f0a26",
|
||||
"sha256:9b3cf13facf6f77c283af0e1713e5e8c47a0fe295af81326cb3cb4380212e797",
|
||||
"sha256:9c5a52987a990eb1bae55f9000994f1afdb0326c154fb089992f839ab3c30688",
|
||||
"sha256:a2d79c6635ccffcbfc1d5c045874ba36b594589be81d50d43472570bb8de9c57",
|
||||
"sha256:a6ec5bf6bc361f2f0f9644907a36ce527715b488988a8df534120e5c34eeda94",
|
||||
"sha256:a7bf9cc97f05048ac8f3e02cd58f0fe62b901453c24345bfde287f4305dcc31c",
|
||||
"sha256:ab9056d94e5db513d9313b34394f3a3b83e6301a581c28ad67773434f3faccab",
|
||||
"sha256:adf28d13a33f9d750fe7a78fb481cac298fa257d8863d8727b2ea4455ea41235",
|
||||
"sha256:b62cb9a7501e1f5c9ffe190485501349c33e8862dde4377df774e40b8166871f",
|
||||
"sha256:bacbd3c69862478cbe1c7ed4325caedec580d8acf31b8ee1b9a1e02a56295cad",
|
||||
"sha256:bb349dbba57c76eec25e5917e07f35aabaf0a33b9e67fc13d188002500106487",
|
||||
"sha256:bd03472c36fa3a386a6deb887113b9e3fa40efba8203eb4fe786d3c0ccc724f6",
|
||||
"sha256:bf85a00ac3b56a1e7a19c5be7b02b5180a0895ac4d3c234d717a55e86960691c",
|
||||
"sha256:ca0c7ce828bb76ab78b3991904b477c2fd0f711d7815c252d1ef28ff9450b052",
|
||||
"sha256:ccbfd94e59aad4a2566c71912b55f0547ac1680bfac25eb138e6703eb3dd434e",
|
||||
"sha256:d1831c07bd4dce53c4b666fa846c7eba4b7c414f2e641a4585b7f50b72f502dc",
|
||||
"sha256:d22cad98c2a10bbf6aa083a8980db6ed90d4285a841c4de892890c2b28286ef9",
|
||||
"sha256:d30ad4359413c8821cc7b3707f7ca38aa8bc852ba3b9c5a759ee2d7740157315",
|
||||
"sha256:e0dd3676ea0837cd70ea1879765e9e9f6be063be0436de9b3ea4b775caf83654",
|
||||
"sha256:e584d0cdd37cac355aca52ed788d1a2d939d6837e2870d3b70e585db24025a50",
|
||||
"sha256:e6369ac293d2cc40d52577e4fa3d75a70c1aae2d01fa3580a34a4e6eff9286b9",
|
||||
"sha256:efae5df7a8cc8bdb1037b0f786b044ce281081441df5418c3a0f0e1f86fe7bb3",
|
||||
"sha256:f19b3af31d02a2e79c5f9a6deaab0fb3c116456aeb9277d11720ad433de6dfc6",
|
||||
"sha256:f7a0430d765f9bda043e6aefaba5944d5f21ec43ff4774417d7e296f61917382",
|
||||
"sha256:fb94245a715b4d6e24689de12772b85329a1f9946cbf6187923a64ecdea39e65"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==5.12.0"
|
||||
},
|
||||
"zope-interface": {
|
||||
"hashes": [
|
||||
"sha256:0009d2d3c02ea783045d7804da4fd016245e5c5de31a86cebba66dd6914d59a2",
|
||||
"sha256:05a0e42d6d830f547e114de2e7cd15750dc6c0c78f8138e6c5035e51ddfff37c",
|
||||
"sha256:0723507127f8269b8f3f22663168f717e9c9742107d1b6c9f419df561b71aa6d",
|
||||
"sha256:16c69da19a06566664ddd4785f37cad5693a51d48df1515d264c20d005d322e2",
|
||||
"sha256:2499de92e8275d0dd68f84425b3e19e9268cd1fa8507997900fa4175f157733c",
|
||||
"sha256:2bf9cf275468bafa3c72688aad8cfcbe3d28ee792baf0b228a1b2d93bd1d541a",
|
||||
"sha256:34f877d1d3bb7565c494ed93828fa6417641ca26faf6e8f044e0d0d500807028",
|
||||
"sha256:3bf73a910bb27344def2d301a03329c559a79b308e1e584686b74171d736be4e",
|
||||
"sha256:46c7e4e8cbc698398a67e56ca985d19cb92365b4aafbeb6a712e8c101090f4cb",
|
||||
"sha256:532367553e4420c80c0fc0cabcc2c74080d495573706f66723edee6eae53361d",
|
||||
"sha256:561ce42390bee90bae51cf1c012902a8033b2aaefbd0deed81e877562a116d48",
|
||||
"sha256:6068322004a0158c80dfd4708dfb103a899635408c67c3b10e9acec4dbacefec",
|
||||
"sha256:624b6787fc7c3e45fa401984f6add2c736b70a7506518c3b537ffaacc4b29d4c",
|
||||
"sha256:6f4b4dfcfdfaa9177a600bb31cebf711fdb8c8e9ed84f14c61c420c6aa398489",
|
||||
"sha256:788c293f3165964ec6527b2d861072c68eef53425213f36d3893ebee89a89623",
|
||||
"sha256:845d14e580220ae4544bd4d7eb800f0b6034fe5585fc2536806e0a26c2ee6640",
|
||||
"sha256:8f094bfb49179ec5dc9981cb769af1275702bd64720ef94874d9e34da1390d4c",
|
||||
"sha256:9a4e785097e741a1c953b3970ce28f2823bd63c00adc5d276f2981dd66c96c15",
|
||||
"sha256:9b05a919fdb0ed6ea942e5a7800e09a8b6cdae6f98fee1bef1c9d1a3fc43aaa0",
|
||||
"sha256:a1ef4b43659e1348f35f38e7d1a6bbc1682efde239761f335ffc7e31e798b65b",
|
||||
"sha256:a87fc7517f825a97ff4a4ca4c8a950593c59e0f8e7bfe1b6f898a38d5ba9f9cf",
|
||||
"sha256:aae807efc7bd26302eb2fea05cd6de7d59269ed6ae23a6de1ee47add6de99b8c",
|
||||
"sha256:afb20c371a601d261b4f6edb53c3c418c249db1a9717b0baafc9a9bb39ba1224",
|
||||
"sha256:bc9ded9e97a0ed17731d479596ed1071e53b18e6fdb2fc33af1e43f5fd2d3aaa",
|
||||
"sha256:c31acfa3d7cde48bec45701b0e1f4698daffc378f559bfb296837d8c834732f6",
|
||||
"sha256:c65ade7ea85516e428651048489f5e689e695c79188761de8c622594d1e13322",
|
||||
"sha256:ccc62b5712dd7bd64cfba3ee63089fb11e840f5914b990033beeae3b2180b6cb",
|
||||
"sha256:ccf52f7d44d669203c2096c1a0c2c15d52e36b2e7a9413df50f48392c7d4d080",
|
||||
"sha256:d2bb8e7364e18f083bf6744ccf30433b2a5f236c39c95df8514e3c13007098ce",
|
||||
"sha256:dfc4f44e8de2ff4eba20af4f0a3ca42d3c43ab24a08e49ccd8558b7a4185b466",
|
||||
"sha256:f777e68c76208503609c83ca021a6864902b646530a1a39abb9ed310d1100664"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==8.2"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
||||
@@ -1,53 +1,68 @@
|
||||

|
||||
|
||||
# friend-event-rsvp
|
||||
|
||||
A personal event RSVP tool. Meant for personal home use and a single administrator. Unique feature is multiple activities per event.
|
||||
|
||||
# Development
|
||||
`pip install --user pipenv`
|
||||
## Production
|
||||
|
||||
Inside the project root: `pipenv install`
|
||||
Make sure there are no deployment issues
|
||||
|
||||
Everytime you start: `pipenv shell`
|
||||
`python manage.py check --deploy`
|
||||
|
||||
Check that is works by running `which python`
|
||||
Collect and compress all static files:
|
||||
|
||||
# To run
|
||||
Requires Daphne (websockets)
|
||||
`python manage.py runserver`
|
||||
`python manage.py collectstatic --clear` <-- Clear is optional
|
||||
|
||||
## So long as the migrations are not part of the repo
|
||||
`python manage.py makemigrations`
|
||||
`python manage.py migrate`
|
||||
`python -m blacknoise.compress static/`
|
||||
|
||||
Run the server
|
||||
`daphne rsvpproject.asgi:application`
|
||||
|
||||
## Development
|
||||
|
||||
### Setup environment
|
||||
|
||||
Install pipenv: `pip install --user pipenv`
|
||||
|
||||
Inside the project root (friend-event-rsvp): `pipenv install`
|
||||
|
||||
Everytime you start work: `pipenv shell`
|
||||
|
||||
Check that is works by running: `which python`. This should return a specific python location inside your user folder.
|
||||
|
||||
Requirements (installed from Pipfile):
|
||||
|
||||
- Django
|
||||
- Channels
|
||||
- Daphne
|
||||
- BlackNoise
|
||||
|
||||
### Publish docker image
|
||||
|
||||
Build
|
||||
`docker build -t gitea.furb.it/kennyboy55/friend-event-rsvp:dev .`
|
||||
|
||||
How to tag:
|
||||
`docker push gitea.furb.it/kennyboy55/friend-event-rsvp:dev`
|
||||
|
||||
### Run
|
||||
|
||||
Run the server during development: `DEBUG=1 python manage.py runserver`
|
||||
|
||||
This will automatically restart on changes and log to the console.
|
||||
|
||||
### Setup database
|
||||
|
||||
This needs to be done every time a model chance is made:
|
||||
|
||||
- Create migrations file (add to repo): `python manage.py makemigrations`
|
||||
- Update local database: `python manage.py migrate`
|
||||
|
||||
### To add a superuser
|
||||
|
||||
You will be prompted for a password:
|
||||
|
||||
## To add a superuser
|
||||
`python manage.py createsuperuser --username <username> --email <email>`
|
||||
|
||||
# Ideas and notes
|
||||
|
||||
## Een
|
||||
Emails! Om te editen, als er comments of wijzigingen zijn!
|
||||
|
||||
## Twee
|
||||
Admin paneel: 4 kolommen op basis van de status: open, incomplete, yes, no
|
||||
Met een websocket.
|
||||
En dat je dan ook live kan zien dat er gasten toegevoegd worden, en als ze dingen veranderen enzo.
|
||||
|
||||
## Drie
|
||||
Als iemand geen gasten mag meenemen, die hele stap niet tonen.
|
||||
|
||||
## Vier
|
||||
Activity start en eind tijd klopt niks van hoe het getoond wordt..
|
||||
|
||||
## Vijf
|
||||
Extra gasten als property van een activity, die gewoon getoont worden als groep?
|
||||
|
||||
## Zes
|
||||
De buttons tijdens een rsvp renderen serverside en met oob-swapping elke keer terugsturen:
|
||||
- Geen previous op eerste pagina
|
||||
- Geen next, maar finish op laatste pagina
|
||||
- hx-confirm op back-to-event als nog niet voltooid.
|
||||
|
||||
# Things to keep in mind
|
||||
- Move to Postgress
|
||||
- Dockerfile
|
||||
- Redis for channels?
|
||||
You can use this to login to the django admin environment: `http://127.0.0.1:8000/django-admin/`
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
app:
|
||||
image: gitea.furb.it/kennyboy55/friend-event-rsvp:dev
|
||||
container_name: friend-event-rsvp
|
||||
ports:
|
||||
- "8000:8000"
|
||||
env_file: .env
|
||||
volumes:
|
||||
- ./data:/data
|
||||
@@ -0,0 +1,15 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# This template contains only required options.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
|
||||
SECRET_KEY=
|
||||
|
||||
# your default timezone See https://timezonedb.com/time-zones for a list of timezones
|
||||
TZ=Europe/Amsterdam
|
||||
|
||||
# allowed hosts (see documentation), must be set to your hostname(s)
|
||||
ALLOWED_HOSTS=events.mydomain.com
|
||||
|
||||
# enable debug log
|
||||
#DEBUG=1
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 6.0 on 2025-12-20 13:32
|
||||
# Generated by Django 6.0.3 on 2026-03-27 12:24
|
||||
|
||||
import datetime
|
||||
import django.db.models.deletion
|
||||
@@ -38,6 +38,7 @@ class Migration(migrations.Migration):
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('location', models.CharField(max_length=255)),
|
||||
('start_time', models.DateTimeField()),
|
||||
('end_time', models.DateTimeField(blank=True, null=True)),
|
||||
('guest_limit', models.PositiveIntegerField(blank=True, null=True)),
|
||||
@@ -66,7 +67,7 @@ class Migration(migrations.Migration):
|
||||
('slug', models.SlugField(max_length=255)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('image', models.ImageField(blank=True, null=True, upload_to=events.models.event_image_path)),
|
||||
('allow_rsvp_without_invite', models.BooleanField(default=True)),
|
||||
('allow_rsvp_without_invite', models.BooleanField(default=False)),
|
||||
('allow_comments', models.BooleanField(default=True)),
|
||||
('default_email_updates_optin', models.BooleanField(default=True)),
|
||||
('guest_limit', models.PositiveIntegerField(blank=True, null=True)),
|
||||
@@ -78,21 +79,6 @@ class Migration(migrations.Migration):
|
||||
'ordering': ['-id'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Comment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('text', models.TextField()),
|
||||
('notify_subscribers', models.BooleanField(default=False)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='events.event')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='activitygroup',
|
||||
name='event',
|
||||
@@ -103,46 +89,6 @@ class Migration(migrations.Migration):
|
||||
name='event',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='events.event'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GuestListTemplate',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GuestListItem',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('email', models.EmailField(blank=True, max_length=254)),
|
||||
('is_main_invitee', models.BooleanField(default=True)),
|
||||
('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='events.guestlisttemplate')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Invite',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('code', models.CharField(db_index=True, max_length=64, unique=True)),
|
||||
('recipient_name', models.CharField(blank=True, max_length=255)),
|
||||
('recipient_email', models.EmailField(blank=True, max_length=254)),
|
||||
('personalized_message', models.TextField(blank=True)),
|
||||
('allow_bring_guests', models.BooleanField(default=False)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invites', to='events.event')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Guest',
|
||||
fields=[
|
||||
@@ -154,7 +100,21 @@ class Migration(migrations.Migration):
|
||||
('is_main_invitee', models.BooleanField(default=False)),
|
||||
('created_by_host', models.BooleanField(default=False)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='guests', to='events.event')),
|
||||
('invite', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='guests', to='events.invite')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Comment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('text', models.TextField()),
|
||||
('notify_subscribers', models.BooleanField(default=False)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='events.event')),
|
||||
('guest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='events.guest')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
@@ -187,25 +147,6 @@ class Migration(migrations.Migration):
|
||||
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='choices', to='events.question')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RSVP',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('edit_token', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
|
||||
('responder_email', models.EmailField(blank=True, max_length=254)),
|
||||
('send_email_updates', models.BooleanField(default=True)),
|
||||
('status', models.CharField(choices=[('yes', 'Yes'), ('no', 'No'), ('maybe', 'Maybe'), ('pending', 'Pending')], default='pending', max_length=10)),
|
||||
('notes', models.TextField(blank=True)),
|
||||
('activities', models.ManyToManyField(related_name='rsvps', through='events.ActivitySelection', to='events.activity')),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rsvps', to='events.event')),
|
||||
('invite', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rsvps', to='events.invite')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Response',
|
||||
fields=[
|
||||
@@ -214,15 +155,60 @@ class Migration(migrations.Migration):
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('value_text', models.TextField(blank=True)),
|
||||
('activity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.activity')),
|
||||
('choice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.questionchoice')),
|
||||
('guest', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.guest')),
|
||||
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.question')),
|
||||
('rsvp', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.rsvp')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ResponseChoice',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('choice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='response_choices', to='events.questionchoice')),
|
||||
('response', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='response_choices', to='events.response')),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('response', 'choice')},
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='response',
|
||||
name='choices',
|
||||
field=models.ManyToManyField(blank=True, related_name='responses', through='events.ResponseChoice', to='events.questionchoice'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RSVP',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('invite', models.SlugField(max_length=255, unique=True)),
|
||||
('edit_token', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
|
||||
('responder_name', models.CharField(blank=True, max_length=255)),
|
||||
('responder_email', models.EmailField(max_length=254)),
|
||||
('send_email_updates', models.BooleanField(default=True)),
|
||||
('personalized_message', models.TextField(blank=True)),
|
||||
('allow_bring_guests', models.BooleanField(default=False)),
|
||||
('page', models.CharField(choices=[('email', 'Email'), ('guests', 'Guests'), ('activities', 'Activities'), ('questions', 'Questions'), ('notes', 'Notes'), ('completed', 'Completed')], default='email', max_length=16)),
|
||||
('furthest_page', models.CharField(choices=[('email', 'Email'), ('guests', 'Guests'), ('activities', 'Activities'), ('questions', 'Questions'), ('notes', 'Notes'), ('completed', 'Completed')], default='email', max_length=16)),
|
||||
('status', models.CharField(choices=[('unopened', 'Not Opened'), ('not_started', 'Not Started'), ('incomplete', 'Incomplete'), ('not_coming', 'Not coming'), ('joining', 'Yes, joining')], default='unopened', max_length=16)),
|
||||
('notes', models.TextField(blank=True)),
|
||||
('activities', models.ManyToManyField(related_name='rsvps', through='events.ActivitySelection', to='events.activity')),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rsvps', to='events.event')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='response',
|
||||
name='rsvp',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.rsvp'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='guest',
|
||||
name='rsvp',
|
||||
|
||||
+5
-17
@@ -1,4 +1,5 @@
|
||||
# models.py
|
||||
import os
|
||||
import uuid
|
||||
from typing import Self
|
||||
from datetime import timedelta
|
||||
@@ -23,8 +24,8 @@ class TimestampedModel(models.Model):
|
||||
|
||||
|
||||
def event_image_path(instance, filename):
|
||||
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
|
||||
return "events/static/img/{0}/{1}".format(instance.slug, filename)
|
||||
# file will be uploaded to MEDIA_ROOT/<event_slug>/overview<.extension>
|
||||
return "{0}/overview{1}".format(instance.slug, os.path.splitext(filename)[1])
|
||||
|
||||
class Event(TimestampedModel):
|
||||
"""The main event which contains activities.
|
||||
@@ -61,13 +62,6 @@ class Event(TimestampedModel):
|
||||
@property
|
||||
def markdown(self) -> str:
|
||||
return markdown.markdown(self.description)
|
||||
|
||||
@property
|
||||
def static_image_url(self) -> str:
|
||||
image_str = str(self.image)
|
||||
if len(image_str) > 0:
|
||||
return image_str[14:]
|
||||
return "img/placeholder.jpg"
|
||||
|
||||
@property
|
||||
def start_time(self):
|
||||
@@ -111,8 +105,8 @@ class ActivityGroup(TimestampedModel):
|
||||
|
||||
|
||||
def activity_image_path(instance, filename):
|
||||
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
|
||||
return "events/static/img/{0}/{1}".format(instance.slug, filename)
|
||||
# file will be uploaded to MEDIA_ROOT/<event_slug>/overview<.extension>
|
||||
return "{0}/{1}{2}".format(instance.event.slug, instance.id, os.path.splitext(filename)[1])
|
||||
|
||||
class Activity(TimestampedModel):
|
||||
"""An individual activity within an event.
|
||||
@@ -143,12 +137,6 @@ class Activity(TimestampedModel):
|
||||
def markdown(self) -> str:
|
||||
return markdown.markdown(self.description)
|
||||
|
||||
def static_image_url(self) -> str:
|
||||
image_str = str(self.image)
|
||||
if len(image_str) > 0:
|
||||
return image_str[14:]
|
||||
return "img/placeholder_activity.jpg"
|
||||
|
||||
def is_locked(self) -> bool:
|
||||
if not self.allow_rsvp:
|
||||
return True
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 191 KiB |
@@ -15,10 +15,11 @@
|
||||
|
||||
</div>
|
||||
|
||||
{% if event.image %}
|
||||
<div class="card">
|
||||
{% load static %}
|
||||
<img src="{% static event.static_image_url %}">
|
||||
<img src="/media/{{ event.image }}" alt="{{ event.title }} image">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if response %}
|
||||
<div class="card {% if response.joining %}bg-green{% elif response.not_coming %}bg-red{% elif response.in_progress %}bg-orange{% endif %}">
|
||||
|
||||
@@ -52,7 +52,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% load static %}
|
||||
<img class="thumbnail" src="{% static activity.static_image_url %}" alt="{{ activity.title }} image">
|
||||
{% if activity.image %}
|
||||
<img class="thumbnail" src="/media/{{ activity.image }}" alt="{{ activity.title }} image">
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
+18
-1
@@ -8,15 +8,32 @@ https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
|
||||
from channels.auth import AuthMiddlewareStack
|
||||
from channels.routing import ProtocolTypeRouter, URLRouter
|
||||
from channels.security.websocket import AllowedHostsOriginValidator
|
||||
|
||||
from blacknoise import BlackNoise
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
logger = logging.getLogger(__file__)
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rsvpproject.settings')
|
||||
|
||||
django_asgi_app = get_asgi_application()
|
||||
from django.conf import settings
|
||||
|
||||
if settings.DEBUG:
|
||||
logger.warning("DEBUG enabled")
|
||||
|
||||
if settings.DOCKER:
|
||||
logger.warning("DOCKER enabled")
|
||||
|
||||
logger.info(f"ALLOWED_HOSTS={settings.ALLOWED_HOSTS}")
|
||||
|
||||
django_asgi_app = BlackNoise(get_asgi_application())
|
||||
django_asgi_app.add(settings.STATIC_ROOT, "/static")
|
||||
django_asgi_app.add(settings.MEDIA_ROOT, "/media")
|
||||
|
||||
from events.routing import websocket_urlpatterns
|
||||
|
||||
|
||||
+54
-15
@@ -10,24 +10,59 @@ For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/6.0/ref/settings/
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
bool_map = {"true": True, "false": False}
|
||||
|
||||
def extract_bool(env_key, default:bool):
|
||||
|
||||
retval = default
|
||||
env_val = os.getenv(env_key)
|
||||
|
||||
if env_val:
|
||||
# Try as int
|
||||
try:
|
||||
bool_as_num = int(env_val)
|
||||
retval = bool(bool_as_num)
|
||||
# Try as string
|
||||
except ValueError:
|
||||
# Convert string to boolean using the dictionary
|
||||
retval = bool_map.get(env_val.lower(), default)
|
||||
|
||||
return retval
|
||||
|
||||
|
||||
def extract_comma_list(env_key, default=None):
|
||||
if os.getenv(env_key):
|
||||
return [item.strip() for item in os.getenv(env_key).split(',')] # pyright: ignore[reportOptionalMemberAccess]
|
||||
else:
|
||||
if default:
|
||||
return [default]
|
||||
else:
|
||||
return []
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-!o*-8y!xf%@2@wm3qd43^)sj6019#lv@!ze3z$81ndn@*$0$4*'
|
||||
SECRET_KEY = os.getenv('SECRET_KEY', 'INSECURE_STANDARD_KEY_SET_IN_ENV')
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
DEBUG = extract_bool('DEBUG', False)
|
||||
DOCKER = extract_bool('DOCKER', False)
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
ALLOWED_HOSTS = extract_comma_list('ALLOWED_HOSTS', '127.0.0.1')
|
||||
CSRF_TRUSTED_ORIGINS = extract_comma_list('CSRF_TRUSTED_ORIGINS')
|
||||
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
DOCKER_DIR = BASE_DIR
|
||||
|
||||
if DOCKER:
|
||||
# We are running in docker
|
||||
DOCKER_DIR = Path('/data')
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
@@ -83,24 +118,24 @@ LOGGING = {
|
||||
'handlers': {
|
||||
'console': {
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'standard',
|
||||
},
|
||||
'file': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.FileHandler',
|
||||
'filename': 'error.log',
|
||||
'formatter': 'simple',
|
||||
},
|
||||
# 'file': {
|
||||
# 'level': 'DEBUG' if DEBUG else 'INFO',
|
||||
# 'class': 'logging.FileHandler',
|
||||
# 'filename': 'error.log',
|
||||
# 'formatter': 'simple',
|
||||
# },
|
||||
},
|
||||
'loggers': {
|
||||
'events': {
|
||||
'handlers': ['file', 'console'],
|
||||
'level': 'DEBUG',
|
||||
'handlers': ['console'],
|
||||
'level': 'DEBUG' if DEBUG else 'INFO',
|
||||
'propagate': True,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
WSGI_APPLICATION = 'rsvpproject.wsgi.application'
|
||||
ASGI_APPLICATION = 'rsvpproject.asgi.application'
|
||||
|
||||
|
||||
@@ -110,7 +145,7 @@ ASGI_APPLICATION = 'rsvpproject.asgi.application'
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
'NAME': DOCKER_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,3 +198,7 @@ USE_TZ = True
|
||||
# https://docs.djangoproject.com/en/6.0/howto/static-files/
|
||||
|
||||
STATIC_URL = 'static/'
|
||||
STATIC_ROOT = BASE_DIR / 'static'
|
||||
|
||||
MEDIA_URL = 'media/'
|
||||
MEDIA_ROOT = DOCKER_DIR / 'media'
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
"""
|
||||
WSGI config for rsvpproject 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/6.0/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rsvpproject.settings')
|
||||
|
||||
application = get_wsgi_application()
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
echo "Migrating database"
|
||||
|
||||
python manage.py migrate
|
||||
|
||||
echo "Collecting and optimizing static files, this may take a while..."
|
||||
|
||||
python manage.py collectstatic --noinput --clear
|
||||
python -m blacknoise.compress static/
|
||||
|
||||
echo "Creating all necessary directories..."
|
||||
|
||||
mkdir -p /data/media
|
||||
|
||||
echo "Done"
|
||||
|
||||
daphne -b 0.0.0.0 -p 8000 rsvpproject.asgi:application
|
||||
Reference in New Issue
Block a user