Compare commits

9 Commits

Author SHA1 Message Date
7b16f85dd1 update gitignore 2025-10-17 14:27:00 +02:00
0a67502dc5 update README 2025-10-17 14:26:48 +02:00
34ec726c10 update docker compose 2025-10-17 14:25:48 +02:00
54f9394673 add nginx conf for homepage 2025-10-17 14:25:06 +02:00
fc8de40524 add dockerfile only for django project 2025-10-17 14:21:50 +02:00
fb3466ff63 change package management for developing to uv 2025-10-17 14:19:47 +02:00
cd9c81cfc2 add python-version file for uv 2025-10-17 14:12:46 +02:00
83cbf037fc deactivate pdf render 2025-10-17 00:57:41 +02:00
484dce8305 add rental calendar 2025-10-14 13:44:34 +02:00
18 changed files with 1098 additions and 168 deletions

11
.gitignore vendored
View File

@@ -1,7 +1,6 @@
.env/* .env/*
*.pyc *.pyc
*_design1 *_design1
fet2020/files/*
fet2020/.env/* fet2020/.env/*
*.sqlite3 *.sqlite3
.theia/* .theia/*
@@ -11,4 +10,12 @@ run
*.pid *.pid
*~ *~
APIKEY.txt APIKEY.txt
tmp tmp
.ruff_cache
.venv
etherpad
files
flowbite
gallery
tailwind
whoosh_index

182
Readme.md
View File

@@ -1,70 +1,152 @@
##Fet 2020 Django Project # Fet 2020 Django Project
Diese Webseite ist im Jahr 2020 entwickelt worden. Wir haben dazu einige Designentscheidungen getroffen: Diese Webseite ist im Jahr 2020 entwickelt worden. Wir haben dazu einige Designentscheidungen getroffen:
1. Zunächst auf die externen Kernfunktionen fokusieren
2. Python+Django nutzen weil: 1. Zunächst auf die externen Kernfunktionen fokussieren
* Wir Python mögen 2. Python + Django nutzen weil:
* Das Framework uns freiheit gibt zB die Mitglieder Daten entsprechend abzubilden * wir Python mögen
* Das Design unabhängig von der Funktion bleibt * das Framework uns die Freiheit gibt, zB die Mitglieder Daten entsprechend abzubilden
* das Design unabhängig von der Funktion bleibt
* und einiges mehr * und einiges mehr
3. Als Kernfunktionen festgelegt wurden anfangs: 3. Als Kernfunktionen festgelegt wurden anfangs:
* Neuigkeiten posten * Neuigkeiten posten
* FET Sitzungen ankündigen * FET Sitzungen ankündigen
* Etherpad für Agenda und Protokoll * Etherpad für Agenda und Protokoll
* Informationen zu Mitgliedern anzeigen * Informationen zu Mitgliedern anzeigen
4. Unter dem Eindruck eines Jahres des Lockdown wurde zusätzlich hinzugefügt 4. Unter dem Eindruck eines Jahres des Lockdown wurde zusätzlich hinzugefügt
* Ein virtuelles Schwarzesbrett * Ein virtuelles Schwarzesbrett
* Eine virtuelle Aufgabenliste
### Ablage und Entwicklung ## Development
Der Master liegt auf dem virtuellen git Server und kann wie folgt geholt werden:
The main branch is hosted on the FET git server. Clone the repository using the following command:
```bash ```bash
git clone https://git.fet.at/bofh/fet2020 git clone https://git.fet.at/bofh/fet2020
``` ```
### Deployment
{{docker-compose.yml}} ## Debug
<code>
docker-compose up
</code>
### Command Befehle If you are developing on Windows, install Visual Studio Code and Docker Desktop.
Erstellt alle Searchindexes neu: Add a local user/member for login because the project is not connected to FET LDAP in dev mode:
<code>
```bash
python manage.py createsuperuser
```
### Python version
View all python versions:
```bash
uv python list
```
Installing Python executables:
```bash
uv python install $(.python-version) --default
```
Update the following files if the python version is increased:
* .python-version
* pyproject.toml
* run-pre-commit.sh
## Deployment
### Docker image for django
Makemigrations:
```bash
python fet2020/manage.py makemigrations blackboard core finance gallery members posts rental
```
```bash
python fet2020/manage.py makemigrations intern
```
Add all static files to the assets:
```bash
python fet2020/manage.py collectstatic
```
Check if the project is for deployment:
```bash
python fet2020/manage.py check --deploy
```
Build the docker image of django project:
```bash
docker build -t django-image -f fet2020/Dockerfile ./fet2020
```
### Docker image for nginx
Build the docker image of nginx:
```bash
docker build -t django-nginx-image -f nginx/Dockerfile ./nginx
```
### Start docker container
Build the docker containers:
```bash
docker compose -f docker-compose.yml up -d
```
Remove all unused docker images older than 24 hours:
```bash
docker image prune -a --filter "until=24h"
```
## Other Useful Commands
Please use the command carefully! Remove all unused docker volumes:
```bash
docker volume prune -a
```
Rebuilds all search indexes:
```bash
python3 fet2020/manage.py rebuild_index python3 fet2020/manage.py rebuild_index
</code> ```
Aktualisiert alle Searchindexes: Updates all search indexes:
<code>
```bash
python3 fet2020/manage.py update_index python3 fet2020/manage.py update_index
</code>
Fügt alle Cronjobs in diesem Projekt hinzu:
<code>
python3 fet2020/manage.py crontab add
</code>
Fügt alle Staticfiles in die Assets hinzu:
<code>
python3 fet2020/manage.py collectstatic
</code>
Überprüft, ob die Software bereit für die Produktion ist.
<code>
python3 fet2020/manage.py check --deploy
</code>
Code Formatting (zuerst isort und danach black anwenden):
```bash
isort **/*.py
```
```bash
black **/*.py
```
```bash
isort **/templatetags/*.py
```
```bash
black **/templatetags/*.py
``` ```
## TODO
ckeditor -> django-prose-editor
## Version History
Next
* Add rental
2.1.0
* Add finance system
2.0.0
* Update the homepage design
* Add intern
1.0.0
* First release of the new homepage

View File

@@ -1,79 +1,25 @@
version: "2" name: fet-homepage
services: services:
mysql: nginx:
image: mariadb:10.7 container_name: nginx-container
container_name: fet_mysql image: django-nginx-image:latest
networks: ports:
- fetdocker - "80:80"
environment:
MYSQL_DATABASE: fet2020db
MYSQL_USER: user
MYSQL_PASSWORD: hgu
MYSQL_COLLATION: utf8_general_ci
MYSQL_CHARSET: utf8
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
volumes:
#- mysql-volume:/var/lib/mysql
- /srv/initdb/mysql:/docker-entrypoint-initdb.d/
healthcheck:
test: "mysqladmin ping -h localhost && echo 'show tables;' | mysql 'fet2020db' >/dev/null "
timeout: 20s
retries: 20
etherpadsql:
image: mariadb:10.7
container_name: fet_mysql_etherpad
networks:
- fetdocker
environment:
MYSQL_DATABASE: etherpaddb
MYSQL_USER: user
MYSQL_PASSWORD: "hgu"
MYSQL_COLLATION: utf8_general_ci
MYSQL_CHARSET: utf8
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
healthcheck:
test: "mysqladmin ping -h localhost && echo 'show tables;' | mysql --port 3306 --protocol tcp 'etherpaddb' > /dev/null"
timeout: 20s
retries: 20
volumes:
#- ep-mysql-volume:/var/lib/mysql
- /srv/initdb/etherpad:/docker-entrypoint-initdb.d/
etherpad:
image: etherpad/etherpad:1.8.17
container_name: fet_etherpad
networks:
- fetdocker
environment:
DB_TYPE: mysql
DB_HOST: etherpadsql
DB_PORT: 3306
DB_NAME: etherpaddb
DB_USER: root
DB_PASS: ""
DB_CHARSET: utf8
TRUST_PROXY: "true"
REQUIRE_SESSION: "true"
depends_on: depends_on:
etherpadsql: - django-homepage
condition: "service_healthy"
volumes: volumes:
- /srv/APIKEY.txt:/opt/etherpad-lite/APIKEY.txt - files-volume:/usr/src/app/files
restart: unless-stopped
# - ./deployment/mysql.cnf:/etc/mysql/conf.d
healthcheck:
test: "curl --fail localhost:9001 >/dev/null "
timeout: 10s
interval: 15s
retries: 30
fet2020:
image: docker.fet.at/fet2020django
container_name: fet_fet2020
networks: networks:
- fetdocker - fet-network
django-homepage:
container_name: django-container
image: django-image:latest
environment: environment:
HOST_NAME: "fet.at" HOST_NAME: "fet.at"
DEBUG: "False" DEBUG: "False"
SECRET_KEY: "sadfreigjopi4qgjpjrp" LDAP: "True"
SECRET_KEY: "sae34sADfrFr89E!Gl#f!34hdjGR#!jopi4qFEr#4R56rT56zT2#wE1!feGp"
MYSQL_USER: "user" MYSQL_USER: "user"
MYSQL_PASSWORD: "hgu" MYSQL_PASSWORD: "hgu"
ETHERPAD_GROUP: "g.snlbqn7S6ksRbom3" ETHERPAD_GROUP: "g.snlbqn7S6ksRbom3"
@@ -82,21 +28,94 @@ services:
condition: service_healthy condition: service_healthy
etherpad: etherpad:
condition: service_healthy condition: service_healthy
ports: volumes:
- "8000:8080" - ./fet2020:/usr/src/app
- ./gallery:/usr/src/app/files/uploads/gallery:shared
- files-volume:/usr/src/app/files
networks:
- fet-network
- django-db-network
restart: unless-stopped
healthcheck: healthcheck:
test: "python3 manage.py check --database default" test: "python3 manage.py check --database default"
timeout: 20s timeout: 20s
retries: 20 retries: 20
etherpad:
container_name: etherpad-container
image: etherpad/etherpad:1.8.17
# ports:
# - 9001:9001
environment:
DB_TYPE: mysql
DB_HOST: etherpadsql
DB_PORT: 3306
DB_NAME: etherpaddb
DB_USER: user
DB_PASS: "hgu"
DB_CHARSET: utf8
TRUST_PROXY: false
depends_on:
etherpadsql:
condition: "service_healthy"
volumes: volumes:
- /srv/APIKEY.txt:/app/etherpad/APIKEY.txt - ./fet2020/etherpad/APIKEY.txt:/opt/etherpad-lite/APIKEY.txt
- /srv/files:/app/files networks:
- fet-network
- etherpad-db-network
restart: unless-stopped restart: unless-stopped
healthcheck:
test: "curl --fail localhost:9001 >/dev/null "
timeout: 10s
interval: 15s
retries: 30
mysql:
container_name: django-db-container
image: mariadb:10.7
environment:
MYSQL_DATABASE: fet2020db
MYSQL_USER: user
MYSQL_PASSWORD: hgu
MYSQL_COLLATION: utf8_general_ci
MYSQL_CHARSET: utf8
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
volumes:
- mysql-volume:/docker-entrypoint-initdb.d/
networks:
- django-db-network
healthcheck:
test: "mysqladmin ping -h localhost && echo 'show tables;' | mysql 'fet2020db' >/dev/null "
timeout: 20s
retries: 20
etherpadsql:
container_name: etherpad-db-container
image: mariadb:10.7
environment:
MYSQL_DATABASE: etherpaddb
MYSQL_USER: user
MYSQL_PASSWORD: "hgu"
MYSQL_COLLATION: utf8_general_ci
MYSQL_CHARSET: utf8
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
volumes:
- etherpad-mysql-volume:/docker-entrypoint-initdb.d/
networks:
- etherpad-db-network
healthcheck:
test: "mysqladmin ping -h localhost && echo 'show tables;' | mysql --port 3306 --protocol tcp 'etherpaddb' > /dev/null"
timeout: 20s
retries: 20
volumes: volumes:
ep-mysql-volume:
driver: local
mysql-volume: mysql-volume:
driver: local driver: local
etherpad-mysql-volume:
driver: local
files-volume:
driver: local
name: django-files-volume
networks: networks:
fetdocker: fet-network:
name: fetdocker driver: bridge
django-db-network:
driver: bridge
etherpad-db-network:
driver: bridge

View File

@@ -1 +1,7 @@
.git/* .git
.ruff_cache
.venv
files
whoosh_index
Dockerfile
db.sqlite3

1
fet2020/.python-version Normal file
View File

@@ -0,0 +1 @@
3.13

48
fet2020/Dockerfile Normal file
View File

@@ -0,0 +1,48 @@
FROM python:3.13-alpine
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Install system dependencies
RUN apk add --no-cache --virtual .build-deps ca-certificates gcc linux-headers \
musl-dev \
jpeg-dev \
zlib-dev \
libffi-dev \
mysql \
mariadb-dev \
freetype-dev
# Install latest version of uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
# # Maybe needed for mysqlclient >= 2.2.0
# RUN apt-get update \
# && apt-get upgrade -y \
# && apt-get install -y gcc default-libmysqlclient-dev build-essential pkg-config
# Run python in venv
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
WORKDIR /usr/src/app
# Install project dependencies
COPY pyproject.toml .
RUN uv export --no-hashes --no-dev --format requirements-txt > requirements.txt
# RUN uv export --no-hashes --no-dev --frozen --format requirements-txt > requirements.txt
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
# Copy django project
COPY . .
# Create APIKEY.txt file for etherpad
RUN mkdir -p ./etherpad
RUN touch ./etherpad/APIKEY.txt
RUN echo "haDF223lfaH79823qwSSdF" >> ./etherpad/APIKEY.txt
EXPOSE 8000
ENTRYPOINT ["./docker-entrypoint.sh"]

View File

@@ -0,0 +1,16 @@
#!/bin/sh
# # Collect static files
# echo "Collect static files"
# python manage.py collectstatic --noinput
# Apply database migrations
echo "Apply database migrations"
python manage.py migrate
# Start server
echo "Starting server"
# TODO: FIX insecure!!!
python manage.py runserver --insecure 0.0.0.0:8000
exec "$@"

View File

@@ -175,11 +175,12 @@ class Post(models.Model):
@property @property
def agenda_filename(self) -> str | None: def agenda_filename(self) -> str | None:
if self._agenda_filename: # TODO: fix pdf render
return self._agenda_filename # if self._agenda_filename:
# return self._agenda_filename
if self.has_agenda and self.agenda_url: # if self.has_agenda and self.agenda_url:
return self.slug + "-agenda.pdf" # return self.slug + "-agenda.pdf"
return None return None
@@ -207,11 +208,12 @@ class Post(models.Model):
@property @property
def protocol_filename(self) -> str | None: def protocol_filename(self) -> str | None:
if self._protocol_filename: # TODO: fix pdf render
return self._protocol_filename # if self._protocol_filename:
# return self._protocol_filename
if self.has_protocol and self.protocol_url: # if self.has_protocol and self.protocol_url:
return self.slug + "-protokoll.pdf" # return self.slug + "-protokoll.pdf"
return None return None

View File

@@ -1,20 +1,21 @@
from io import BytesIO # from io import BytesIO
from django.http import HttpResponse, HttpResponseServerError, JsonResponse from django.http import HttpResponse, HttpResponseServerError, JsonResponse
from django.utils import timezone from django.utils import timezone
from django.utils.text import slugify from django.utils.text import slugify
from taggit.models import Tag from taggit.models import Tag
from xhtml2pdf import pisa
# from xhtml2pdf import pisa
def render_to_pdf(html): def render_to_pdf(html):
src = BytesIO(html.encode("ISO-8859-1")) # TODO: fix pdf render
dest = BytesIO() # src = BytesIO(html.encode("ISO-8859-1"))
# dest = BytesIO()
pdf = pisa.pisaDocument(src, dest) # pdf = pisa.pisaDocument(src, dest)
if not pdf.err: # if not pdf.err:
return HttpResponse(dest.getvalue(), content_type="application/pdf") # return HttpResponse(dest.getvalue(), content_type="application/pdf")
return None return None

116
fet2020/pyproject.toml Normal file
View File

@@ -0,0 +1,116 @@
[project]
name = "fet-homepage"
version = "2.1.0"
description = "Homepage for Fachschaft Elektrotechnik"
requires-python = ">=3.13"
dependencies = [
"django",
"django-ckeditor<6.7.3",
"django-environ",
"django-filter",
"django-haystack",
"django-static-jquery-ui",
"django-taggit",
"djangorestframework",
"easy-thumbnails",
"etherpad-lite",
"fontawesomefree",
"html2text",
"ldap3",
"mysqlclient",
"pillow",
"pypdf",
"python-dateutil",
"segno",
"Whoosh",
"elasticsearch",
]
[dependency-groups]
dev = [
"djade",
"django-upgrade",
"pyupgrade",
"ruff",
]
[tool.ruff]
line-length = 100
indent-width = 4
target-version = "py313"
exclude = ["tests", "migrations", "search", "tests.py"]
[tool.ruff.format]
docstring-code-format = true
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
[tool.ruff.lint]
ignore = [
# django-all-with-model-form
"DJ007",
# mutable-class-default
"RUF012",
# if-else-block-instead-of-if-exp
"SIM108",
]
select = [
# flake8-bugbear
"B",
# flake8-comprehensions
"C4",
# flake8-datetimez
"DTZ",
# flake8-django
"DJ",
# flake8-errmsg
"EM",
# flake8-implicit-str-concat
"ISC",
# flake8-import-conventions
"ICN",
# flake8-logging
"LOG",
# flake8-logging-format
"G",
# flake8-pie
"PIE",
# flake8-print
"T20",
# flake8-pyi
"PYI",
# flake8-quotes
"Q",
# flake8-return
"RET",
# flake8-self
"SLF",
# flake8-simplify
"SIM",
# flake8-tidy-imports
"TID",
# flake8-use-pathlib
"PTH",
# isort
"I",
# pep8-naming
"N",
# Perflint
"PERF",
# pycodestyle errors
"E",
# pycodestyle warnings
"W",
# Pyflakes errors
"F",
# pyupgrade
"UP",
# refurb
"FURB",
# Ruff-specific rules
"RUF",
# tryceratops
"TRY",
]

View File

@@ -1,11 +1,12 @@
from django.urls import path from django.urls import path
from . import apps from . import apps, views
from .views import RentalCreateDoneView, RentalCreateView, RentalItemDetailView, RentalListView from .views import RentalCreateDoneView, RentalCreateView, RentalItemDetailView, RentalListView
app_name = apps.RentalConfig.name app_name = apps.RentalConfig.name
urlpatterns = [ urlpatterns = [
path("rental_calendar.ics", views.rental_calendar, name="calendar"),
path("rental/", RentalListView.as_view(), name="index"), path("rental/", RentalListView.as_view(), name="index"),
path("request-rental/", RentalCreateView.as_view(), name="rental_create"), path("request-rental/", RentalCreateView.as_view(), name="rental_create"),
path( path(

View File

@@ -2,6 +2,7 @@ import calendar
import datetime import datetime
from django.db.models import Q from django.db.models import Q
from django.shortcuts import render
from django.urls import reverse from django.urls import reverse
from django.views.generic import ListView, TemplateView from django.views.generic import ListView, TemplateView
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
@@ -170,3 +171,21 @@ class RentalCreateDoneView(TemplateView):
class RentalItemDetailView(DetailView): class RentalItemDetailView(DetailView):
model = RentalItem model = RentalItem
template_name = "rental/rentalitem_detail.html" template_name = "rental/rentalitem_detail.html"
def rental_calendar(request):
"""
ICS-calendar for outlook, google calender, ...
"""
rentals = Rental.objects.all()
context = {
"rentals": rentals,
}
response = render(request, "rental/rental_calendar.ics", context, content_type="text/calendar")
# End of line (EOL) must be CRLF, to be compliant with RFC5545. Django/Python set the EOL to LF.
response.content = response.content.replace(b"\n", b"\r\n")
return response

View File

@@ -1,21 +0,0 @@
django==5.2.3
django-ckeditor==6.7.2
django-environ==0.12.0
django-filter==25.1
django-haystack==3.3.0
django-static-jquery-ui==1.13.3.1
django-taggit==6.1.0
djangorestframework==3.16.0
easy-thumbnails==2.9
etherpad-lite==0.5
fontawesomefree==6.6.0
html2text==2025.4.15
ldap3==2.9.1
mysqlclient==2.2.7
pillow==11.1.0
pypdf==5.6.0
python-dateutil==2.9.0.post0
segno==1.6.6
xhtml2pdf==0.2.17
Whoosh==2.7.4
elasticsearch

View File

@@ -13,6 +13,10 @@
Willkommen bei unserem Verleih! Willkommen bei unserem Verleih!
</p> </p>
{% if user.is_authenticated %}
<a href="{% url 'rental:calendar' %}" class="block btn btn-secondary max-w-xs mx-auto sm:w-max sm:mr-0 sm:ml-auto my-6"><i class="fa-solid fa-calendar-days mr-2"></i>Verleih-Kalender abonnieren</a>
{% endif %}
<a href="{% url 'rental:rental_create' %}" class="page-subtitle block btn-small btn-primary max-w-xs mx-auto sm:w-max sm:mr-0 sm:ml-auto"> <a href="{% url 'rental:rental_create' %}" class="page-subtitle block btn-small btn-primary max-w-xs mx-auto sm:w-max sm:mr-0 sm:ml-auto">
<i class="fa-solid fa-plus mr-1"></i> Verleih anfragen <i class="fa-solid fa-plus mr-1"></i> Verleih anfragen
</a> </a>

View File

@@ -0,0 +1,37 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//FET//Verleih Kalender//DE
METHOD:PUBLISH
X-WR-CALNAME:Verleih Kalender
X-WR-CALDESC:Übersicht aller Verleihtermine
X-WR-TIMEZONE:Europe/Vienna
BEGIN:VTIMEZONE
TZID:Europe/Vienna
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19961027T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
TZNAME:MEZ
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19810329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
TZNAME:MESZ
END:DAYLIGHT
END:VTIMEZONE{% for rental in rentals %}{% for rentalitem in rental.rentalitems.all %}
BEGIN:VEVENT
UID:{% now 'Ymd' %}_{{ rental.id }}_{{ rentalitem.id }}@fet.at
ORGANIZER;CN="Fachschaft Elektrotechnik":MAILTO:verleih@fet.at
SUMMARY:#{{ rental.id }}: {{ rentalitem.name }} - {{ rental.get_status_display }}
DESCRIPTION:Anfrage bearbeiten: {{ request.scheme }}://
{{ request.get_host }}{% url 'admin:rental_rental_change' rental.id %}
CLASS:PUBLIC
DTSTART;TZID=Europe/Vienna:{{ rental.date_start|date:'Ymd' }}
DTEND;TZID=Europe/Vienna:{{ rental.date_end|date:'Ymd' }}
DTSTAMP;TZID=Europe/Vienna:{% now 'Ymd' %}T{% now 'His' %}
TRANSP:TRANSPARENT
END:VEVENT{% endfor %}{% endfor %}
END:VCALENDAR

519
fet2020/uv.lock generated Normal file
View File

@@ -0,0 +1,519 @@
version = 1
revision = 3
requires-python = ">=3.13"
[[package]]
name = "asgiref"
version = "3.10.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/46/08/4dfec9b90758a59acc6be32ac82e98d1fbfc321cb5cfa410436dbacf821c/asgiref-3.10.0.tar.gz", hash = "sha256:d89f2d8cd8b56dada7d52fa7dc8075baa08fb836560710d38c292a7a3f78c04e", size = 37483, upload-time = "2025-10-05T09:15:06.557Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/17/9c/fc2331f538fbf7eedba64b2052e99ccf9ba9d6888e2f41441ee28847004b/asgiref-3.10.0-py3-none-any.whl", hash = "sha256:aef8a81283a34d0ab31630c9b7dfe70c812c95eba78171367ca8745e88124734", size = 24050, upload-time = "2025-10-05T09:15:05.11Z" },
]
[[package]]
name = "certifi"
version = "2025.10.5"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" },
]
[[package]]
name = "djade"
version = "1.6.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a9/9c/637184b2595d38d9ddcd31076c7ac6b57cd259821481cc8f029616be2b25/djade-1.6.0.tar.gz", hash = "sha256:a7f173d6949ce248ee538ab85676e3277b4b4ae956c3383f96348355ab8983b7", size = 40150, upload-time = "2025-09-08T15:35:20.097Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/dd/e6/ddfcf10d010a3905232ba2962d2ef00533052913966d06237356871fa48f/djade-1.6.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e43eb2227a02599df038ba64b7a0c8599d6cef9d0de978ac635592d58299d477", size = 1126877, upload-time = "2025-09-08T15:35:02.534Z" },
{ url = "https://files.pythonhosted.org/packages/37/78/ce1cc79f9311f101ea6721498b1027b7698cd40702af6b50a7842442644d/djade-1.6.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fe820c5be3d08952ad42ea9ee5475e1c60d32326fae57ee98a4887e99d2d1765", size = 1054501, upload-time = "2025-09-08T15:35:04.115Z" },
{ url = "https://files.pythonhosted.org/packages/71/db/2b7d51041c47b65ad0f483379958ac44fb12db7a761a390e0f3423932e6e/djade-1.6.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dd8a7919f1fa953e332548aeb3b793dea0563fc5e9f89017da6fe7318b603a2", size = 1098200, upload-time = "2025-09-08T15:35:05.794Z" },
{ url = "https://files.pythonhosted.org/packages/5c/82/8d829ba658337ee9138f8850d91cab4ea9ccad2a6d23a60fb7c3cbb7ae9b/djade-1.6.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:113a8db4657bd488ecf383c3db0953530012afbccb596302a294c7b629573269", size = 1041283, upload-time = "2025-09-08T15:35:07.125Z" },
{ url = "https://files.pythonhosted.org/packages/79/ac/7f3fbedf3f229bed3c55fe0e6db4b669d2b5d995c07918739dd4713997f7/djade-1.6.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53511e1d3d55ff408fe11edc7bc982b0af53ab6225870d031804e209ec0515d8", size = 1222400, upload-time = "2025-09-08T15:35:08.826Z" },
{ url = "https://files.pythonhosted.org/packages/57/2a/3f3053cc7fba84faee5cd8307cb2d548bc26f05e9c4d28bb48b47bf25d0a/djade-1.6.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ed89688c9baa733cbf4ec08b8cc0102bdd1b539bd0775f5ad5be98e20ab934", size = 1195877, upload-time = "2025-09-08T15:35:10.464Z" },
{ url = "https://files.pythonhosted.org/packages/ac/35/9324569b8cfa714c1992dba661deb9bf9001c0471986c71c331172c10388/djade-1.6.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:4c4c42d86f317742ad1d33f4ca85d4d507530b7cfbfc9b2dc015dda4d06199ad", size = 1086171, upload-time = "2025-09-08T15:35:11.923Z" },
{ url = "https://files.pythonhosted.org/packages/64/39/e924089cddb183295f7c51ed1587c2f6c956e0efe8b5b594494104c93037/djade-1.6.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a99661ad8b155c3aa62ac2fdb3879df0e5a5bcb1c66f8a142f3964cd2a0bb1cb", size = 1240677, upload-time = "2025-09-08T15:35:13.761Z" },
{ url = "https://files.pythonhosted.org/packages/ec/2e/5d942c51cd7c5bb868e942fc3fc9d7cd97617d94a56db0bb40da18d0d0ef/djade-1.6.0-py3-none-win32.whl", hash = "sha256:4555387841d0ef6290ff8221ebea48321262ff1011874debd30010e5deba0ff3", size = 963337, upload-time = "2025-09-08T15:35:15.878Z" },
{ url = "https://files.pythonhosted.org/packages/73/ff/3b4a9ff45c0f8584931031d511721c27f5f4d09852611be2164b42eb74e0/djade-1.6.0-py3-none-win_amd64.whl", hash = "sha256:d6111763d133a7a85db0f6f0e59586fdbbd08e6c22238e84de730bb1a21cbab4", size = 1056597, upload-time = "2025-09-08T15:35:17.562Z" },
{ url = "https://files.pythonhosted.org/packages/32/a7/d3f58feeb1169a41c569b63cb8f23886694f0d72290cbc7eb691b083e0aa/djade-1.6.0-py3-none-win_arm64.whl", hash = "sha256:c52efaa5d64572ddc4a986d74202195c8574f969877fcfbdbea3a41718334804", size = 985920, upload-time = "2025-09-08T15:35:18.856Z" },
]
[[package]]
name = "django"
version = "5.2.7"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "asgiref" },
{ name = "sqlparse" },
{ name = "tzdata", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b1/96/bd84e2bb997994de8bcda47ae4560991084e86536541d7214393880f01a8/django-5.2.7.tar.gz", hash = "sha256:e0f6f12e2551b1716a95a63a1366ca91bbcd7be059862c1b18f989b1da356cdd", size = 10865812, upload-time = "2025-10-01T14:22:12.081Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8f/ef/81f3372b5dd35d8d354321155d1a38894b2b766f576d0abffac4d8ae78d9/django-5.2.7-py3-none-any.whl", hash = "sha256:59a13a6515f787dec9d97a0438cd2efac78c8aca1c80025244b0fe507fe0754b", size = 8307145, upload-time = "2025-10-01T14:22:49.476Z" },
]
[[package]]
name = "django-ckeditor"
version = "6.7.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
{ name = "django-js-asset" },
]
sdist = { url = "https://files.pythonhosted.org/packages/8e/ad/73c303e8e58b38ef4f3ed475334dca2cd4509b4bbdfb573f2d13745e3cd8/django_ckeditor-6.7.2.tar.gz", hash = "sha256:a66be4f0ca13924d756e4930260144b31df4164eae8b942ca610f4313df00d5f", size = 1726242, upload-time = "2024-12-05T09:37:53.982Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/16/ed/e48cc43a987facd99e7ad24cc466e2578b0cbdba345a01f068d55daa2a1a/django_ckeditor-6.7.2-py3-none-any.whl", hash = "sha256:2b3f147ce21eba861db481683e9a4639c11f0ad1f0d37c179003ef07f9eb65a4", size = 2455602, upload-time = "2024-12-05T09:37:51.188Z" },
]
[[package]]
name = "django-environ"
version = "0.12.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d6/04/65d2521842c42f4716225f20d8443a50804920606aec018188bbee30a6b0/django_environ-0.12.0.tar.gz", hash = "sha256:227dc891453dd5bde769c3449cf4a74b6f2ee8f7ab2361c93a07068f4179041a", size = 56804, upload-time = "2025-01-13T17:03:37.74Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/83/b3/0a3bec4ecbfee960f39b1842c2f91e4754251e0a6ed443db9fe3f666ba8f/django_environ-0.12.0-py2.py3-none-any.whl", hash = "sha256:92fb346a158abda07ffe6eb23135ce92843af06ecf8753f43adf9d2366dcc0ca", size = 19957, upload-time = "2025-01-13T17:03:32.918Z" },
]
[[package]]
name = "django-filter"
version = "25.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2c/e4/465d2699cd388c0005fb8d6ae6709f239917c6d8790ac35719676fffdcf3/django_filter-25.2.tar.gz", hash = "sha256:760e984a931f4468d096f5541787efb8998c61217b73006163bf2f9523fe8f23", size = 143818, upload-time = "2025-10-05T09:51:31.521Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c1/40/6a02495c5658beb1f31eb09952d8aa12ef3c2a66342331ce3a35f7132439/django_filter-25.2-py3-none-any.whl", hash = "sha256:9c0f8609057309bba611062fe1b720b4a873652541192d232dd28970383633e3", size = 94145, upload-time = "2025-10-05T09:51:29.728Z" },
]
[[package]]
name = "django-haystack"
version = "3.3.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
{ name = "packaging" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b4/09/623634ca5f8b9fe99d07d284491724eb1b0704022e942a1fe815c1d13a02/django_haystack-3.3.0.tar.gz", hash = "sha256:e3ceed6b8000625da14d409eb4dac69894905e2ac8ac18f9bfdb59323ca02eab", size = 467287, upload-time = "2024-06-04T15:09:58.707Z" }
[[package]]
name = "django-js-asset"
version = "3.1.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e6/91/c63f136f553ec24fc46ccf20ac7292a8df04815b383975b6f3f7f0060217/django_js_asset-3.1.2.tar.gz", hash = "sha256:1fc7584199ed1941ed7c8e7b87ca5524bb0f2ba941561d2a104e88ee9f07bedd", size = 9471, upload-time = "2025-03-04T15:22:49.789Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a6/cf/b208767db5e56b5189829f753eec6a14ee75d074922dc2bd19220b22a34d/django_js_asset-3.1.2-py3-none-any.whl", hash = "sha256:b5ffe376aebbd73b7af886d675ac9f43ca63b39540190fa8409c9f8e79145f68", size = 5905, upload-time = "2025-03-04T15:22:51.152Z" },
]
[[package]]
name = "django-static-jquery-ui"
version = "1.13.3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
]
sdist = { url = "https://files.pythonhosted.org/packages/87/51/045015a87bf97d24ce9a1f34e664f75a8a2ea01c04ee965c632ca9843aef/django-static-jquery-ui-1.13.3.1.tar.gz", hash = "sha256:e2bd1b66f5ee604cfb4f2788398c8274c3307c547eb19e7325f9e5626f040a95", size = 1506385, upload-time = "2024-05-12T13:22:58.54Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/92/10/8e4409fe2faa8afa66937f91a8ecf671e180e6437e9198f328d6044aaa4c/django_static_jquery_ui-1.13.3.1-py3-none-any.whl", hash = "sha256:ab2f474619e03d15d5016ec83cc6ed2672411c464cf4e9e3bf046ba002f5cba7", size = 1924566, upload-time = "2024-05-12T13:22:55.787Z" },
]
[[package]]
name = "django-taggit"
version = "6.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
]
sdist = { url = "https://files.pythonhosted.org/packages/34/a6/f1beaf8f552fe90c153cc039316ebab942c23dfbc88588dde081fefca816/django_taggit-6.1.0.tar.gz", hash = "sha256:c4d1199e6df34125dd36db5eb0efe545b254dec3980ce5dd80e6bab3e78757c3", size = 38151, upload-time = "2024-09-29T08:07:39.477Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6b/34/4185c345530b91d05cb82e05d07148f481a5eb5dc2ac44e092b3daa6f206/django_taggit-6.1.0-py3-none-any.whl", hash = "sha256:ab776264bbc76cb3d7e49e1bf9054962457831bd21c3a42db9138b41956e4cf0", size = 75749, upload-time = "2024-09-29T08:07:14.612Z" },
]
[[package]]
name = "django-upgrade"
version = "1.29.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "tokenize-rt" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ee/07/900c8783c26a66aec4cc6afdfa47fdd3b0ba82436988b852412bc9c64663/django_upgrade-1.29.0.tar.gz", hash = "sha256:f981e62fbccd2bbc4f165034c5c95de60010fdf1ad2c46e7ae9a66e9baa6955a", size = 39691, upload-time = "2025-10-06T15:46:51.229Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/16/33b4645fb10e649656354f02af5c794b26ed0ebf7b70c52bb656af5c662c/django_upgrade-1.29.0-py3-none-any.whl", hash = "sha256:05d174815ed86e5cfe91f22b941f9edc424d5f648dad9fd50b967d795b466523", size = 68922, upload-time = "2025-10-06T15:46:49.94Z" },
]
[[package]]
name = "djangorestframework"
version = "3.16.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
]
sdist = { url = "https://files.pythonhosted.org/packages/8a/95/5376fe618646fde6899b3cdc85fd959716bb67542e273a76a80d9f326f27/djangorestframework-3.16.1.tar.gz", hash = "sha256:166809528b1aced0a17dc66c24492af18049f2c9420dbd0be29422029cfc3ff7", size = 1089735, upload-time = "2025-08-06T17:50:53.251Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b0/ce/bf8b9d3f415be4ac5588545b5fcdbbb841977db1c1d923f7568eeabe1689/djangorestframework-3.16.1-py3-none-any.whl", hash = "sha256:33a59f47fb9c85ede792cbf88bde71893bcda0667bc573f784649521f1102cec", size = 1080442, upload-time = "2025-08-06T17:50:50.667Z" },
]
[[package]]
name = "easy-thumbnails"
version = "2.10.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
{ name = "pillow" },
]
sdist = { url = "https://files.pythonhosted.org/packages/04/2f/71f17c3ce65b25dd8fc8e513738c8496eadbd8bab94f39509a511ff99704/easy_thumbnails-2.10.1.tar.gz", hash = "sha256:a50aa5f99387546c35ab5ba1ea9b3cbbc5658e65601cd34949f62137c32c222e", size = 81446, upload-time = "2025-08-17T20:49:11.308Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b0/90/be137d0592501ec08d4a00c8430121e95dfe6c8114a1d4436b5cdd6b9803/easy_thumbnails-2.10.1-py3-none-any.whl", hash = "sha256:24462d63dd31543ef1585538b2bfefe0db96d3409bb431c70b81548fb2cfc5be", size = 79695, upload-time = "2025-08-17T20:49:09.119Z" },
]
[[package]]
name = "elastic-transport"
version = "9.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ae/1f/2d1a1790df2b75e1e1eb90d8a3fe066a47ef95e34430657447e549cc274c/elastic_transport-9.1.0.tar.gz", hash = "sha256:1590e44a25b0fe208107d5e8d7dea15c070525f3ac9baafbe4cb659cd14f073d", size = 76483, upload-time = "2025-07-24T16:41:31.017Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/5d/dd5a919dd887fe20a91f18faf5b4345ee3a058e483d2aa84cef0f2567e17/elastic_transport-9.1.0-py3-none-any.whl", hash = "sha256:369fa56874c74daae4ea10cbf40636d139f38f42bec0e006b9cd45a168ee7fce", size = 65142, upload-time = "2025-07-24T16:41:29.648Z" },
]
[[package]]
name = "elasticsearch"
version = "9.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "elastic-transport" },
{ name = "python-dateutil" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/59/6a/5eecef6f1ac8005b04714405cb65971d46031bd897e47c29af86e0f87353/elasticsearch-9.1.1.tar.gz", hash = "sha256:be20acda2a97591a9a6cf4981fc398ee6fca3291cf9e7a9e52b6a9f41a46d393", size = 857802, upload-time = "2025-09-12T13:27:38.62Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cf/4c/c0c95d3d881732a5d1b28e12c9be4dea5953ade71810f94565bd5bd2101a/elasticsearch-9.1.1-py3-none-any.whl", hash = "sha256:2a5c27c57ca3dd3365f665c82c9dcd8666ccfb550d5b07c688c21ec636c104e5", size = 937483, upload-time = "2025-09-12T13:27:34.948Z" },
]
[[package]]
name = "etherpad-lite"
version = "0.5"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/13/6c/2079dac77d480fd49862d12465ed3369360ad9b8c9bb0e3fb79f1e7b650e/etherpad_lite-0.5.tar.gz", hash = "sha256:07ca67f3f8d0342e9a114f96b908ec055a5c6d23f59bb0cbf5e06e4a06bbdae3", size = 3583, upload-time = "2016-06-01T10:23:40.75Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1a/89/cdba92ddfc894d664ba68fb55fcc547736165e096c594d3d6ab94d66c19b/etherpad_lite-0.5-py3-none-any.whl", hash = "sha256:80844f198a89d355cb39c18aee15f7fa641d67330487b20d4caa6cc498c1d818", size = 4511, upload-time = "2016-06-01T12:31:59.082Z" },
]
[[package]]
name = "fet-homepage"
version = "2.1.0"
source = { virtual = "." }
dependencies = [
{ name = "django" },
{ name = "django-ckeditor" },
{ name = "django-environ" },
{ name = "django-filter" },
{ name = "django-haystack" },
{ name = "django-static-jquery-ui" },
{ name = "django-taggit" },
{ name = "djangorestframework" },
{ name = "easy-thumbnails" },
{ name = "elasticsearch" },
{ name = "etherpad-lite" },
{ name = "fontawesomefree" },
{ name = "html2text" },
{ name = "ldap3" },
{ name = "mysqlclient" },
{ name = "pillow" },
{ name = "pypdf" },
{ name = "python-dateutil" },
{ name = "segno" },
{ name = "whoosh" },
]
[package.dev-dependencies]
dev = [
{ name = "djade" },
{ name = "django-upgrade" },
{ name = "pyupgrade" },
{ name = "ruff" },
]
[package.metadata]
requires-dist = [
{ name = "django" },
{ name = "django-ckeditor", specifier = "<6.7.3" },
{ name = "django-environ" },
{ name = "django-filter" },
{ name = "django-haystack" },
{ name = "django-static-jquery-ui" },
{ name = "django-taggit" },
{ name = "djangorestframework" },
{ name = "easy-thumbnails" },
{ name = "elasticsearch" },
{ name = "etherpad-lite" },
{ name = "fontawesomefree" },
{ name = "html2text" },
{ name = "ldap3" },
{ name = "mysqlclient" },
{ name = "pillow" },
{ name = "pypdf" },
{ name = "python-dateutil" },
{ name = "segno" },
{ name = "whoosh" },
]
[package.metadata.requires-dev]
dev = [
{ name = "djade" },
{ name = "django-upgrade" },
{ name = "pyupgrade" },
{ name = "ruff" },
]
[[package]]
name = "fontawesomefree"
version = "6.6.0"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/bb/e9/d43f5133b73e7ef9047bda28daaa6905e00b7d39f093b547f7e78ee2fc40/fontawesomefree-6.6.0-py3-none-any.whl", hash = "sha256:599b574431c9bd92ed5fc054d1045a07c42335da36c17884f2b934755eef9089", size = 25645298, upload-time = "2024-07-16T18:35:44.818Z" },
]
[[package]]
name = "html2text"
version = "2025.4.15"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f8/27/e158d86ba1e82967cc2f790b0cb02030d4a8bef58e0c79a8590e9678107f/html2text-2025.4.15.tar.gz", hash = "sha256:948a645f8f0bc3abe7fd587019a2197a12436cd73d0d4908af95bfc8da337588", size = 64316, upload-time = "2025-04-15T04:02:30.045Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1d/84/1a0f9555fd5f2b1c924ff932d99b40a0f8a6b12f6dd625e2a47f415b00ea/html2text-2025.4.15-py3-none-any.whl", hash = "sha256:00569167ffdab3d7767a4cdf589b7f57e777a5ed28d12907d8c58769ec734acc", size = 34656, upload-time = "2025-04-15T04:02:28.44Z" },
]
[[package]]
name = "ldap3"
version = "2.9.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyasn1" },
]
sdist = { url = "https://files.pythonhosted.org/packages/43/ac/96bd5464e3edbc61595d0d69989f5d9969ae411866427b2500a8e5b812c0/ldap3-2.9.1.tar.gz", hash = "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f", size = 398830, upload-time = "2021-07-18T06:34:21.786Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4e/f6/71d6ec9f18da0b2201287ce9db6afb1a1f637dedb3f0703409558981c723/ldap3-2.9.1-py2.py3-none-any.whl", hash = "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70", size = 432192, upload-time = "2021-07-18T06:34:12.905Z" },
]
[[package]]
name = "mysqlclient"
version = "2.2.7"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/61/68/810093cb579daae426794bbd9d88aa830fae296e85172d18cb0f0e5dd4bc/mysqlclient-2.2.7.tar.gz", hash = "sha256:24ae22b59416d5fcce7e99c9d37548350b4565baac82f95e149cac6ce4163845", size = 91383, upload-time = "2025-01-10T12:06:00.763Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/29/01/e80141f1cd0459e4c9a5dd309dee135bbae41d6c6c121252fdd853001a8a/mysqlclient-2.2.7-cp313-cp313-win_amd64.whl", hash = "sha256:201a6faa301011dd07bca6b651fe5aaa546d7c9a5426835a06c3172e1056a3c5", size = 208000, upload-time = "2025-01-10T11:56:32.293Z" },
]
[[package]]
name = "packaging"
version = "25.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" },
]
[[package]]
name = "pillow"
version = "12.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload-time = "2025-10-15T18:22:25.758Z" },
{ url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload-time = "2025-10-15T18:22:27.286Z" },
{ url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload-time = "2025-10-15T18:22:28.751Z" },
{ url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload-time = "2025-10-15T18:22:30.641Z" },
{ url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload-time = "2025-10-15T18:22:32.73Z" },
{ url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload-time = "2025-10-15T18:22:34.337Z" },
{ url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload-time = "2025-10-15T18:22:36.402Z" },
{ url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload-time = "2025-10-15T18:22:38.066Z" },
{ url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload-time = "2025-10-15T18:22:39.769Z" },
{ url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload-time = "2025-10-15T18:22:41.437Z" },
{ url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload-time = "2025-10-15T18:22:43.152Z" },
{ url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload-time = "2025-10-15T18:22:44.753Z" },
{ url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload-time = "2025-10-15T18:22:46.838Z" },
{ url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload-time = "2025-10-15T18:22:48.399Z" },
{ url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload-time = "2025-10-15T18:22:49.905Z" },
{ url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload-time = "2025-10-15T18:22:51.587Z" },
{ url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload-time = "2025-10-15T18:22:53.215Z" },
{ url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload-time = "2025-10-15T18:22:54.933Z" },
{ url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload-time = "2025-10-15T18:22:56.605Z" },
{ url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload-time = "2025-10-15T18:22:58.53Z" },
{ url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload-time = "2025-10-15T18:23:00.582Z" },
{ url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload-time = "2025-10-15T18:23:02.627Z" },
{ url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload-time = "2025-10-15T18:23:04.709Z" },
{ url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload-time = "2025-10-15T18:23:06.46Z" },
{ url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload-time = "2025-10-15T18:23:08.194Z" },
{ url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload-time = "2025-10-15T18:23:10.121Z" },
{ url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload-time = "2025-10-15T18:23:12.14Z" },
{ url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload-time = "2025-10-15T18:23:13.962Z" },
{ url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload-time = "2025-10-15T18:23:15.562Z" },
{ url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload-time = "2025-10-15T18:23:17.379Z" },
{ url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload-time = "2025-10-15T18:23:18.971Z" },
{ url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload-time = "2025-10-15T18:23:20.909Z" },
{ url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload-time = "2025-10-15T18:23:23.077Z" },
{ url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload-time = "2025-10-15T18:23:25.005Z" },
{ url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload-time = "2025-10-15T18:23:27.009Z" },
{ url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload-time = "2025-10-15T18:23:29.752Z" },
{ url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload-time = "2025-10-15T18:23:32.06Z" },
{ url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload-time = "2025-10-15T18:23:34.71Z" },
{ url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload-time = "2025-10-15T18:23:36.967Z" },
{ url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload-time = "2025-10-15T18:23:38.573Z" },
{ url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload-time = "2025-10-15T18:23:40.238Z" },
{ url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload-time = "2025-10-15T18:23:42.434Z" },
{ url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload-time = "2025-10-15T18:23:44.29Z" },
{ url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload-time = "2025-10-15T18:23:46.065Z" },
{ url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload-time = "2025-10-15T18:23:47.898Z" },
{ url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload-time = "2025-10-15T18:23:49.607Z" },
{ url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload-time = "2025-10-15T18:23:51.351Z" },
{ url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" },
{ url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" },
{ url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" },
]
[[package]]
name = "pyasn1"
version = "0.6.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" },
]
[[package]]
name = "pypdf"
version = "6.1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a6/85/4c0f12616db83c2e3ef580c3cfa98bd082e88fc8d02e136bad3bede1e3fa/pypdf-6.1.1.tar.gz", hash = "sha256:10f44d49bf2a82e54c3c5ba3cdcbb118f2a44fc57df8ce51d6fb9b1ed9bfbe8b", size = 5074507, upload-time = "2025-09-28T13:29:16.165Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/07/ed/adae13756d9dabdddee483fc7712905bb5585fbf6e922b1a19aca3a29cd1/pypdf-6.1.1-py3-none-any.whl", hash = "sha256:7781f99493208a37a7d4275601d883e19af24e62a525c25844d22157c2e4cde7", size = 323455, upload-time = "2025-09-28T13:29:14.392Z" },
]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
]
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
]
[[package]]
name = "pyupgrade"
version = "3.21.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "tokenize-rt" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cb/11/b08f5e4d50575c944e4ea0a86f070a1ba2c0d5a4dc42fac571a605ada78d/pyupgrade-3.21.0.tar.gz", hash = "sha256:3e63a882ec1d16f5621736d938952df3cdc2446501fb049e711415cb8d273960", size = 45210, upload-time = "2025-10-09T19:32:26.448Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a4/4a/d18f2d6b2f9b90ec7e10843ea10e4cde0dc36091782443ee923e29d653bb/pyupgrade-3.21.0-py2.py3-none-any.whl", hash = "sha256:3a200cdc537980f371b4867f1d662e37166a7869d7713f309c1c3241c310c754", size = 62638, upload-time = "2025-10-09T19:32:25.086Z" },
]
[[package]]
name = "ruff"
version = "0.14.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/9e/58/6ca66896635352812de66f71cdf9ff86b3a4f79071ca5730088c0cd0fc8d/ruff-0.14.1.tar.gz", hash = "sha256:1dd86253060c4772867c61791588627320abcb6ed1577a90ef432ee319729b69", size = 5513429, upload-time = "2025-10-16T18:05:41.766Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8d/39/9cc5ab181478d7a18adc1c1e051a84ee02bec94eb9bdfd35643d7c74ca31/ruff-0.14.1-py3-none-linux_armv6l.whl", hash = "sha256:083bfc1f30f4a391ae09c6f4f99d83074416b471775b59288956f5bc18e82f8b", size = 12445415, upload-time = "2025-10-16T18:04:48.227Z" },
{ url = "https://files.pythonhosted.org/packages/ef/2e/1226961855ccd697255988f5a2474890ac7c5863b080b15bd038df820818/ruff-0.14.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f6fa757cd717f791009f7669fefb09121cc5f7d9bd0ef211371fad68c2b8b224", size = 12784267, upload-time = "2025-10-16T18:04:52.515Z" },
{ url = "https://files.pythonhosted.org/packages/c1/ea/fd9e95863124ed159cd0667ec98449ae461de94acda7101f1acb6066da00/ruff-0.14.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6191903d39ac156921398e9c86b7354d15e3c93772e7dbf26c9fcae59ceccd5", size = 11781872, upload-time = "2025-10-16T18:04:55.396Z" },
{ url = "https://files.pythonhosted.org/packages/1e/5a/e890f7338ff537dba4589a5e02c51baa63020acfb7c8cbbaea4831562c96/ruff-0.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed04f0e04f7a4587244e5c9d7df50e6b5bf2705d75059f409a6421c593a35896", size = 12226558, upload-time = "2025-10-16T18:04:58.166Z" },
{ url = "https://files.pythonhosted.org/packages/a6/7a/8ab5c3377f5bf31e167b73651841217542bcc7aa1c19e83030835cc25204/ruff-0.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5c9e6cf6cd4acae0febbce29497accd3632fe2025c0c583c8b87e8dbdeae5f61", size = 12187898, upload-time = "2025-10-16T18:05:01.455Z" },
{ url = "https://files.pythonhosted.org/packages/48/8d/ba7c33aa55406955fc124e62c8259791c3d42e3075a71710fdff9375134f/ruff-0.14.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fa2458527794ecdfbe45f654e42c61f2503a230545a91af839653a0a93dbc6", size = 12939168, upload-time = "2025-10-16T18:05:04.397Z" },
{ url = "https://files.pythonhosted.org/packages/b4/c2/70783f612b50f66d083380e68cbd1696739d88e9b4f6164230375532c637/ruff-0.14.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:39f1c392244e338b21d42ab29b8a6392a722c5090032eb49bb4d6defcdb34345", size = 14386942, upload-time = "2025-10-16T18:05:07.102Z" },
{ url = "https://files.pythonhosted.org/packages/48/44/cd7abb9c776b66d332119d67f96acf15830d120f5b884598a36d9d3f4d83/ruff-0.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7382fa12a26cce1f95070ce450946bec357727aaa428983036362579eadcc5cf", size = 13990622, upload-time = "2025-10-16T18:05:09.882Z" },
{ url = "https://files.pythonhosted.org/packages/eb/56/4259b696db12ac152fe472764b4f78bbdd9b477afd9bc3a6d53c01300b37/ruff-0.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0bf2be3ae8521e1093a487c4aa3b455882f139787770698530d28ed3fbb37c", size = 13431143, upload-time = "2025-10-16T18:05:13.46Z" },
{ url = "https://files.pythonhosted.org/packages/e0/35/266a80d0eb97bd224b3265b9437bd89dde0dcf4faf299db1212e81824e7e/ruff-0.14.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabcaa9ccf8089fb4fdb78d17cc0e28241520f50f4c2e88cb6261ed083d85151", size = 13132844, upload-time = "2025-10-16T18:05:16.1Z" },
{ url = "https://files.pythonhosted.org/packages/65/6e/d31ce218acc11a8d91ef208e002a31acf315061a85132f94f3df7a252b18/ruff-0.14.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:747d583400f6125ec11a4c14d1c8474bf75d8b419ad22a111a537ec1a952d192", size = 13401241, upload-time = "2025-10-16T18:05:19.395Z" },
{ url = "https://files.pythonhosted.org/packages/9f/b5/dbc4221bf0b03774b3b2f0d47f39e848d30664157c15b965a14d890637d2/ruff-0.14.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5a6e74c0efd78515a1d13acbfe6c90f0f5bd822aa56b4a6d43a9ffb2ae6e56cd", size = 12132476, upload-time = "2025-10-16T18:05:22.163Z" },
{ url = "https://files.pythonhosted.org/packages/98/4b/ac99194e790ccd092d6a8b5f341f34b6e597d698e3077c032c502d75ea84/ruff-0.14.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0ea6a864d2fb41a4b6d5b456ed164302a0d96f4daac630aeba829abfb059d020", size = 12139749, upload-time = "2025-10-16T18:05:25.162Z" },
{ url = "https://files.pythonhosted.org/packages/47/26/7df917462c3bb5004e6fdfcc505a49e90bcd8a34c54a051953118c00b53a/ruff-0.14.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0826b8764f94229604fa255918d1cc45e583e38c21c203248b0bfc9a0e930be5", size = 12544758, upload-time = "2025-10-16T18:05:28.018Z" },
{ url = "https://files.pythonhosted.org/packages/64/d0/81e7f0648e9764ad9b51dd4be5e5dac3fcfff9602428ccbae288a39c2c22/ruff-0.14.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cbc52160465913a1a3f424c81c62ac8096b6a491468e7d872cb9444a860bc33d", size = 13221811, upload-time = "2025-10-16T18:05:30.707Z" },
{ url = "https://files.pythonhosted.org/packages/c3/07/3c45562c67933cc35f6d5df4ca77dabbcd88fddaca0d6b8371693d29fd56/ruff-0.14.1-py3-none-win32.whl", hash = "sha256:e037ea374aaaff4103240ae79168c0945ae3d5ae8db190603de3b4012bd1def6", size = 12319467, upload-time = "2025-10-16T18:05:33.261Z" },
{ url = "https://files.pythonhosted.org/packages/02/88/0ee4ca507d4aa05f67e292d2e5eb0b3e358fbcfe527554a2eda9ac422d6b/ruff-0.14.1-py3-none-win_amd64.whl", hash = "sha256:59d599cdff9c7f925a017f6f2c256c908b094e55967f93f2821b1439928746a1", size = 13401123, upload-time = "2025-10-16T18:05:35.984Z" },
{ url = "https://files.pythonhosted.org/packages/b8/81/4b6387be7014858d924b843530e1b2a8e531846807516e9bea2ee0936bf7/ruff-0.14.1-py3-none-win_arm64.whl", hash = "sha256:e3b443c4c9f16ae850906b8d0a707b2a4c16f8d2f0a7fe65c475c5886665ce44", size = 12436636, upload-time = "2025-10-16T18:05:38.995Z" },
]
[[package]]
name = "segno"
version = "1.6.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1c/2e/b396f750c53f570055bf5a9fc1ace09bed2dff013c73b7afec5702a581ba/segno-1.6.6.tar.gz", hash = "sha256:e60933afc4b52137d323a4434c8340e0ce1e58cec71439e46680d4db188f11b3", size = 1628586, upload-time = "2025-03-12T22:12:53.324Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d6/02/12c73fd423eb9577b97fc1924966b929eff7074ae6b2e15dd3d30cb9e4ae/segno-1.6.6-py3-none-any.whl", hash = "sha256:28c7d081ed0cf935e0411293a465efd4d500704072cdb039778a2ab8736190c7", size = 76503, upload-time = "2025-03-12T22:12:48.106Z" },
]
[[package]]
name = "six"
version = "1.17.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
]
[[package]]
name = "sqlparse"
version = "0.5.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e5/40/edede8dd6977b0d3da179a342c198ed100dd2aba4be081861ee5911e4da4/sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", size = 84999, upload-time = "2024-12-10T12:05:30.728Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415, upload-time = "2024-12-10T12:05:27.824Z" },
]
[[package]]
name = "tokenize-rt"
version = "6.2.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/69/ed/8f07e893132d5051d86a553e749d5c89b2a4776eb3a579b72ed61f8559ca/tokenize_rt-6.2.0.tar.gz", hash = "sha256:8439c042b330c553fdbe1758e4a05c0ed460dbbbb24a606f11f0dee75da4cad6", size = 5476, upload-time = "2025-05-23T23:48:00.035Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl", hash = "sha256:a152bf4f249c847a66497a4a95f63376ed68ac6abf092a2f7cfb29d044ecff44", size = 6004, upload-time = "2025-05-23T23:47:58.812Z" },
]
[[package]]
name = "typing-extensions"
version = "4.15.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
]
[[package]]
name = "tzdata"
version = "2025.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" },
]
[[package]]
name = "urllib3"
version = "2.5.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" },
]
[[package]]
name = "whoosh"
version = "2.7.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", hash = "sha256:7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83", size = 968741, upload-time = "2016-04-04T01:19:32.327Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ba/19/24d0f1f454a2c1eb689ca28d2f178db81e5024f42d82729a4ff6771155cf/Whoosh-2.7.4-py2.py3-none-any.whl", hash = "sha256:aa39c3c3426e3fd107dcb4bde64ca1e276a65a889d9085a6e4b54ba82420a852", size = 468790, upload-time = "2016-04-04T01:19:40.379Z" },
]

4
nginx/Dockerfile Normal file
View File

@@ -0,0 +1,4 @@
FROM nginx:latest
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

69
nginx/nginx.conf Normal file
View File

@@ -0,0 +1,69 @@
upstream fetwebsite {
server django-homepage:8000;
}
upstream etherpadwebsite {
server etherpad:9001;
}
server {
listen 80;
# server_name localhost;
# Logging
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
# Handles all other requests
location / {
# Forward requests to Django application
proxy_pass http://fetwebsite;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /files {
alias /usr/src/app/files/;
}
# location /files/uploads/finance {
# auth_request /auth;
# # error_page 401 = @error401;
# }
# location = /auth {
# proxy_pass http://fetwebsite/auth/login/;
# proxy_pass_request_body off;
# proxy_set_header Content-Length "";
# proxy_set_header X-Original-URI $request_uri;
# }
# location @error401 {
# set $query '';
# if ($request_uri ~* "[^\?]+\?(.*)$") {
# set $query $1;
# }
# return 302 /login/?next=$scheme://$http_host$http_port$request_uri;
# }
location /etherpad {
rewrite /etherpad/(.*) /$1 break;
rewrite ^/etherpad$ /etherpad/ permanent;
proxy_pass http://etherpadwebsite;
proxy_redirect / /etherpad/;
proxy_set_header Host $host;
proxy_buffering off;
# Header weiterleiten
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $host;
}
}