Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • apiv2-events
  • chore/conference-singleton
  • chore/singleton/tag-name
  • apiv2-conference
  • apiv2-init
  • develop
  • add-django-ninja
  • stable-38c3
  • chore/update-rooms
  • chore/backoffice-list
  • feature/show_vods
  • feature/event_import_slugs_of_serial_event
  • feature/audit_log
  • 720-schedule_source
  • room-docu
  • chore/event-views
  • 607-schedule-versions
  • feature/conference-query-set
  • feat/unit-integration-tests
  • camp23-prod
  • production
  • andi/schedule-api
  • feat/dynamic-link-forms
  • andi/speaker_import
  • andi/develop
  • cyroxx/add_edit_links
  • cyroxx/bulletin_description
  • 299-delete-planed-assemblies
  • 302-habitat-info
  • feature/mqtt
  • feature/pypy
  • feature/scheduleimport_skippedrooms
  • feature/parallax-css-testpage
  • feature/bg-eyecandy
  • feature/RegisterSpeaker
  • editMail
  • camp23-prod
  • camp23-prod-archive
  • prod-2024-10-14_22-49
  • prod-2024-10-20_23-27
  • prod-2024-10-29_09-45
  • prod-2024-10-31_13-17
  • prod-2024-11-01_11-14
  • prod-2024-11-02_21-16
  • prod-2024-11-03_01-42
  • prod-2024-11-03_12-10
  • prod-2024-11-16_03-41
  • prod-2024-12-04_00-57
  • prod-2024-12-05_00-48
  • prod-2024-12-05_10-09
  • prod-2024-12-10_00-17
  • prod-2024-12-10_07-23
  • prod-2024-12-10_23-04
  • prod-2024-12-14_03-24
  • prod-2024-12-16_02-27
  • prod-2024-12-17_15-05
  • prod-2024-12-19_02-32
  • prod-2024-12-20_12-25
  • prod-2024-12-21_10-44
  • prod-2024-12-21_13-42
  • prod-2024-12-22_00-55
  • prod-2024-12-22_01-34
  • prod-2024-12-22_17-25
  • prod-2024-12-22_21-12
  • prod-2024-12-23_23-39
  • prod-2024-12-24_14-48
  • prod-2024-12-25_01-29
  • prod-2024-12-25_15-54
  • prod-2024-12-25_21-04
  • prod-2024-12-26_00-21
  • prod-2024-12-26_13-12
  • prod-2024-12-26_21-45
  • prod-2024-12-27_00-34
  • prod-2024-12-27_13-29
  • prod-2024-12-27_16-01
  • prod-2024-12-27_16-37
  • prod-2024-12-27_20-15
  • prod-2024-12-27_21-15
  • prod-2024-12-28_02-32
  • prod-2024-12-28_12-24
  • prod-2024-12-28_18-32
  • prod-2024-12-29_02-25
  • prod-2024-12-29_02-55
  • prod-2024-12-29_03-20
  • prod-2024-12-29_03-32
  • prod-2024-12-29_20-35
  • prod-2024-12-30_03-16
  • prod-2024-12-30_12-40
  • prod-2024-12-31_09-54
  • prod-2025-01-07_13-15
  • prod-2025-01-20_00-20
  • prod-2025-01-21_22-00
  • prod-2025-01-21_22-46
  • prod-2025-04-18_22-42
94 results

Target

Select target project
No results found
Select Git revision
  • ical-export
  • develop
  • feature/audit_log
  • fix/index
  • badge-redeem-404
  • 720-schedule_source
  • room-docu
  • chore/event-views
  • 511-schedule-foo-fixed
  • 607-schedule-versions
  • deploy/curl-verbose
  • fix/public-badge-access-rights
  • 445-schedule-redirects
  • 623-wiki-im-baustellenmodus-sollte-mal-als-wiki-admin-trotzdem-seiten-anlegen-bearbeiten-konnen
  • fix/registration_mail_subject
  • feature/conference-query-set
  • feature/568-habitatmanagement
  • feat/unit-integration-tests
  • camp23-prod
  • production
  • andi/schedule-api
  • feat/dynamic-link-forms
  • andi/speaker_import
  • andi/develop
  • cyroxx/add_edit_links
  • cyroxx/bulletin_description
  • 299-delete-planed-assemblies
  • 302-habitat-info
  • feature/mqtt
  • feature/pypy
  • feature/scheduleimport_skippedrooms
  • feature/parallax-css-testpage
  • feature/bg-eyecandy
  • feature/RegisterSpeaker
  • editMail
  • camp23-prod
  • camp23-prod-archive
  • prod-2024-10-14_22-49
  • prod-2024-10-20_23-27
  • prod-2024-10-29_09-45
  • prod-2024-10-31_13-17
  • prod-2024-11-01_11-14
  • prod-2024-11-02_21-16
  • prod-2024-11-03_01-42
  • prod-2024-11-03_12-10
  • prod-2024-11-16_03-41
  • prod-2024-12-04_00-57
  • prod-2024-12-05_00-48
  • prod-2024-12-05_10-09
  • prod-2024-12-10_00-17
  • prod-2024-12-10_07-23
  • prod-2024-12-10_23-04
  • prod-2024-12-14_03-24
  • prod-2024-12-16_02-27
  • prod-2024-12-17_15-05
  • prod-2024-12-19_02-32
  • prod-2024-12-20_12-25
  • prod-2024-12-21_10-44
  • prod-2024-12-21_13-42
  • prod-2024-12-22_00-55
  • prod-2024-12-22_01-34
  • prod-2024-12-22_17-25
  • prod-2024-12-22_21-12
  • prod-2024-12-23_23-39
  • prod-2024-12-24_14-48
  • prod-2024-12-25_01-29
  • prod-2024-12-25_15-54
  • prod-2024-12-25_21-04
  • prod-2024-12-26_00-21
  • prod-2024-12-26_13-12
  • prod-2024-12-26_21-45
  • prod-2024-12-27_00-34
  • prod-2024-12-27_13-29
  • prod-2024-12-27_16-01
  • prod-2024-12-27_16-37
  • prod-2024-12-27_20-15
76 results
Show changes
482 files
+ 15524
12168
Compare changes
  • Side-by-side
  • Inline

Files

+6 −0
Original line number Diff line number Diff line
@@ -10,3 +10,9 @@ src/hub/.settings.secret

# local media files
src/media/

.tools/
.vscode/
.venv*/

**/*_cache
+1 −1
Original line number Diff line number Diff line
@@ -13,5 +13,5 @@ trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false

[*.py]
[*.py, *.toml]
indent_size = 4
+0 −9
Original line number Diff line number Diff line
@@ -83,15 +83,6 @@ db.sqlite3-journal
profile_default/
ipython_config.py

# 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/#use-with-ide
.pdm.toml
.pdm-python

# Environments
.env
.venv
+38 −28
Original line number Diff line number Diff line
@@ -29,10 +29,14 @@ workflow:
# Use build cache to speed up CI
default:
  cache:
    - key:
        files:
          - uv.lock
      paths:
        - $UV_CACHE_DIR
    - key: "python-default"
      paths:
        - .cache/pip
        - .cache/pdm
    - key:
        files:
          - src/plainui/yarn.lock
@@ -68,6 +72,7 @@ default:
    POSTGRES_USER: ci
    SSO_SECRET_GENERATE: "True"
    STORAGE_TYPE: local
    UV_CACHE_DIR: .uv-cache

# Kaniko build setup
.build:
@@ -111,6 +116,8 @@ default:
        "ci": true
      }
      EOF
  after_script:
    - uv cache prune --ci

# Crane setup
.crane:
@@ -122,29 +129,32 @@ default:
  before_script:
    - '[ -n "$DOCKER_CONFIG" ] || export DOCKER_CONFIG=$HOME/.docker'
    - crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

meta_build:
  stage: prepare
  extends: .build
  variables:
    PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
    UV_CACHE_DIR: .uv-cache
  script:
    - /kaniko/executor
      $KANIKO_ARGS
      $KANIKO_CACHE_ARGS
      --dockerfile $CI_PROJECT_DIR/Dockerfile
      --target base
      --destination $CI_REGISTRY_IMAGE/build_image:bi-$CI_PIPELINE_ID
      --target meta
      --destination $CI_REGISTRY_IMAGE/meta_image:mi-$CI_PIPELINE_ID
  rules:
    - when: always

.test:
  extends:
    - .django_runner_settings
  image: $CI_REGISTRY_IMAGE/build_image:bi-$CI_PIPELINE_ID
  image: $CI_REGISTRY_IMAGE/meta_image:mi-$CI_PIPELINE_ID
  variables:
    PDM_CACHE_DIR: .cache/pdm
    UV_CACHE_DIR: .uv-cache
  needs:
    - meta_build
  after_script:
    - uv cache prune --ci

app_version:
  stage: test
@@ -155,8 +165,8 @@ app_version:
    DATABASE_URL: "postgis://ci:runner@db_server/migrations"
  script:
    - python3 -V
    - pdm sync -d --no-editable -G dev
    - pdm app_version
    - uv sync
    - uv run task app_version
  allow_failure: true
  rules:
    - when: always
@@ -166,8 +176,7 @@ lint:
  extends: .test
  script:
    - python3 -V
    - pdm sync -d --no-editable -G dev
    - pdm run lint
    - tox -e py-lint,html-lint
  allow_failure: true
  rules:
    - when: always
@@ -177,8 +186,7 @@ format:
  extends: .test
  script:
    - python3 -V
    - pdm sync -d --no-editable -G dev
    - pdm run format
    - tox -e py-format,html-format
    - git diff --exit-code -- . ':!src/version.json'
  allow_failure: true
  rules:
@@ -191,11 +199,11 @@ format_prettier:
  before_script:
    - apk add --no-cache git
    - corepack enable
    - 'echo "cacheFolder: \".yarn/cache/\"" > .yarnrc.yml'
    - 'echo "cacheFolder: \".yarn/cache/\"" >> .yarnrc.yml'
    - yarn install --immutable
  script:
    - yarn format
    - git diff --exit-code -- . ':!src/version.json'
    - git diff --exit-code -- . ':!src/version.json' ':!.yarnrc.yml'
  allow_failure: true
  rules:
    - when: always
@@ -209,8 +217,8 @@ migration_check:
    DATABASE_URL: "postgis://ci:runner@db_server/migrations"
  script:
    - python3 -V
    - pdm sync -d --no-editable -G dev
    - pdm run check-migrations
    - uv run task manage makemigrations --check
    - uv run task manage makemigrations --dry-run

translations_check:
  stage: test
@@ -222,8 +230,8 @@ translations_check:
  allow_failure: true
  script:
    - python3 -V
    - pdm install --no-editable --prod
    - pdm manage makemessages
    - uv sync
    - uv run task manage makemessages
    - git diff --exit-code -- . ':!src/version.json'

requirements_export:
@@ -231,16 +239,16 @@ requirements_export:
  extends: .test
  script:
    - python3 -V
    - pdm lock --check
    - pdm export --no-hashes -o requirements.txt --prod
    - pdm export --no-hashes -o requirements.dev.txt --de
    - uv lock --check
    - uv export --frozen -o=requirements.dev.txt --no-hashes --all-groups
    - uv export --frozen -o=requirements.txt --no-hashes --no-dev
    - git diff --exit-code -- . ':!src/version.json'
  rules:
    - changes:
        - requirements.txt
        - requirements.dev.txt
        - project.toml
        - pdm.lock
        - uv.lock

django-tests:
  stage: test
@@ -256,16 +264,18 @@ django-tests:
    DATABASE_URL: "postgis://ci:runner@db_server/self_test"
  script:
    - python3 -V
    - pdm sync -d --no-editable -G dev
    - pdm run test
    - pdm run coverage xml -i
    - pdm run coverage report
    - tox -e django-test
    - tox -e coverage-report
  coverage: '/(?i)total(?:\s+\d+){4}\s+(\d+)%/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: .tools/coverage/coverage.xml
        path: .tools/coverage/report.xml
    paths:
      - .tools/coverage/html_report/
    expire_in: 1 week
    expose_as: "HTML Coverage Report"

build_nginx:
  stage: build
@@ -515,7 +525,7 @@ cleanup-ci-images:
    - crane delete $CI_REGISTRY_IMAGE/ci/hub:ci-${CI_PIPELINE_ID}
    - crane delete $CI_REGISTRY_IMAGE/ci/nginx:ci-${CI_PIPELINE_ID}
    - crane delete $CI_REGISTRY_IMAGE/ci/hub:ci-${CI_PIPELINE_ID}-test
    - crane delete $CI_REGISTRY_IMAGE/build_image:bi-$CI_PIPELINE_ID
    - crane delete $CI_REGISTRY_IMAGE/meta_image:mi-$CI_PIPELINE_ID
  needs:
    - job: publish-production
      optional: true
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ repos:
      - id: check-merge-conflict
      - id: check-ast
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.8.0
    rev: v0.9.7
    hooks:
      - id: ruff
        args: [--fix]
@@ -18,37 +18,40 @@ repos:
    rev: v1.0.0
    hooks:
      - id: check-json5
  - repo: https://github.com/pdm-project/pdm
    rev: 2.20.1
    hooks:
      - name: check production requirements
        id: pdm-export
        args: ["-o", "requirements.txt", "--without-hashes", "--prod"]
        files: ^pdm.lock$
  - repo: https://github.com/pdm-project/pdm
    rev: 2.20.1
    hooks:
      - name: check development requirements
        id: pdm-export
        args: ["-o", "requirements.dev.txt", "--without-hashes", "--dev"]
        files: ^pdm.lock$
  - repo: https://github.com/pdm-project/pdm
    rev: 2.20.1
    hooks:
      - id: pdm-lock-check
  - repo: https://github.com/djlint/djLint
    rev: v1.36.2
    rev: v1.36.4
    hooks:
      - id: djlint-reformat-django
      - id: djlint-reformat-jinja
      - id: djlint-django
      - id: djlint-jinja
  - repo: https://github.com/astral-sh/uv-pre-commit
    rev: 0.6.2
    hooks:
      - id: uv-lock
  - repo: https://github.com/astral-sh/uv-pre-commit
    rev: 0.6.2
    hooks:
      - name: uv-export-prod
        id: uv-export
        args:
          - --frozen
          - -o=requirements.txt
          - --no-hashes
          - --no-dev
      - name: uv-export-dev
        id: uv-export
        args:
          - --frozen
          - -o=requirements.dev.txt
          - --no-hashes
          - --all-groups
  - repo: local
    hooks:
      - name: Check for uncreated migrations.
        id: migrations-check
        language: system
        entry: sh -c "pdm manage makemigrations --check --dry-run"
        entry: sh -c "uv run task manage makemigrations --check --dry-run"
        files: "models/.*.py$"
        types:
          - python
+2 −0
Original line number Diff line number Diff line
**/*.html
**/*.j2
.yarn
.yarnrc.yml
.venv*

static.dist/
**/vendor/**/*
Original line number Diff line number Diff line
@@ -2,8 +2,6 @@ activitypub
Andi
ASGI
backoffice
bigbluebutton
BIGBLUEBUTTON
blocktranslate
clonbares
CLUBFRIENDS

.yarnrc.yml

0 → 100644
+1 −0
Original line number Diff line number Diff line
yarnPath: .yarn/releases/yarn-4.6.0.cjs
+22 −24
Original line number Diff line number Diff line
@@ -50,11 +50,10 @@ Um eine andere Demo Datei zu laden kann die Umgebungsvariable `DJANGO_LOAD_FIXTU
   - Linux: Pakete `python3`, `postgresql` und `gettext`
   - Mac: `brew install python3 postgresql gettext` bzw. https://postgresapp.com/
   - Windows: [latest stable Python 3 release](https://www.python.org/downloads/windows/) und [PostgreSQL Installer](https://www.postgresql.org/download/windows/) und [gettext binaries](https://mlocati.github.io/articles/gettext-iconv-windows.html)
   - Python Paketmanager: `pdm`:
     Kann mit OS Installationsmitteln, mit `pip install pdm` oder `pipx install pdm` installiert werden.
   - Python Paketmanager: `uv`:
     Kann mit OS Installationsmitteln, mit `pip install uv` oder `pipx install uv` installiert werden. (Siehe die [Offizielle Dokumentation](https://docs.astral.sh/uv/getting-started/installation/))
1. Klone dieses Repository an beliebigen Ort.
1. Erstelle die virtuelle Umgebung mit `pdm info`
1. Installiere die python dependencies mit `pdm install`
1. Installiere die python dependencies mit `uv sync`
1. (falls nicht bereits vorhanden) lege einen PostgreSQL-User an (`createuser -P hub_app`) sowie eine Datenbank (`createdb -O hub_app hub`) - unter Linux ggf. via `sudo -u postgres`
1. Konfiguriere deine Instanz mittels:
   - Umgebungsvariablen (z.B. direnv, oder env Datei)
@@ -84,18 +83,17 @@ DATABASES = {
}
```

8. Lege die Datenbanktabellen an: `pdm manage migrate`
9. Richte einen Admin-Nutzer (für die Anwendung) ein: `pdm manage createsuperuser`
10. optional: Import von Demo-Daten: `pdm manage.py loaddata .src/core/fixtures/rc3_2021.json`
8. Lege die Datenbanktabellen an: `uv run task manage migrate`
9. Richte einen Admin-Nutzer (für die Anwendung) ein: `uv run task manage createsuperuser`
10. optional: Import von Demo-Daten: `uv run task.py loaddata .src/core/fixtures/rc3_2021.json`
11. optional: Für deinen Adminuser via [Admin-Seite](http://localhost:8000/c3admin/) einen `ConferenceMember` anlegen um den User für das Frontend freizuschalten

## Nutzung

1. Aktiviere das virtual env `pdm venv activate`
2. Wende ggf. vorhandene DB-Migrations an (wenn du gerade aus dem Git geupdatet hast): `pdm manage migrate`
3. Stelle sicher dass alle Translations aktuell sind: `pdm manage compilemessages`
4. Lasse alle staticfiles einsammeln: `pdm manage collectstatic --noinput`
5. Starte den Dev-Server: `pdm manage runserver`
2. Wende ggf. vorhandene DB-Migrations an (wenn du gerade aus dem Git geupdatet hast): `uv run task manage migrate`
3. Stelle sicher dass alle Translations aktuell sind: `uv run task manage compilemessages`
4. Lasse alle staticfiles einsammeln: `uv run task manage collectstatic --noinput`
5. Starte den Dev-Server: `uv run task manage runserver`
6. Besuche die lokale Instanz: [Admin-Seite](http://localhost:8000/c3admin/), [API](http://localhost:8000/api/) und [plainui-Frontend](http://localhost:8000/)

## PlainUI Development Tipps
@@ -136,26 +134,26 @@ Wiederverwendbare Elemente können als Komponenten integriert werden. Dafür gib

### Abhängigkeitsverwaltung

Zur Verwaltung der verwendeten python Abhängigkeiten wir der [Paketmanager PDM](https://pdm-project.org/en/latest/) verwendet.
Zur Verwaltung der verwendeten python Abhängigkeiten wir der [Paketmanager UV](https://docs.astral.sh/uv/) verwendet.
Mittels diesem werden die `requirements.txt` und die `requirements.dev.txt` erzeugt.

#### Installation der aktuellen Abhängigkeiten

Um die aktuellen python Abhängigkeiten zu installieren kann das Kommando `pdm install` verwendet werden.
Mit dem Kommando `pdm sync --clean` kann sichergestellt werden, dass genau die Versionen aus dem pdm lock file installiert werden.
Um die aktuellen python Abhängigkeiten zu installieren kann das Kommando `uv sync` verwendet werden.
Mit dem Kommando `ur sync --frozen` kann sichergestellt werden, dass genau die Versionen aus dem uv lock file installiert werden.
_Achtung_: **Nicht in der Lock Datei enthaltene python Pakete werden deinstalliert!**

#### Hinzufügen von neuen Abhängigkeiten

Um neue Abhängigkeiten hinzuzufügen kann das Kommando `pdm add` verwendet werden. Mit dem Parameter `--dev` kann eine Abhängigkeit als Entwicklungs-Abhängigkeit deklariert werden. Diese wird dann in den Produktivinstanzen nicht installiert.
Um neue Abhängigkeiten hinzuzufügen kann das Kommando `uv add` verwendet werden. Mit dem Parameter `--dev` kann eine Abhängigkeit als Entwicklungs-Abhängigkeit deklariert werden. Diese wird dann in den Produktivinstanzen nicht installiert.

Anschließend müssen die `requirements.txt` und `requirements.dev.txt` angepasst werden.
Wenn `pre-commit` verwendet wird, passiert dies automatisch beim commit.
Alternativ können die folgenden Kommandos verwendet werden

```bash
pdm export --no-hashes -o requirements.txt --prod
pdm export --no-hashes -o requirements.dev.txt --dev
uv export --format requirements-txt --no-hashes -o requirements.txt --no-dev
uv export --format requirements-txt --no-hashes -o requirements.dev.txt --all-groups
```

### Debugging DJANGO
@@ -177,9 +175,9 @@ oder:

### Übersetzungen extrahieren & compilieren

- `pdm manage makemessages`
- `uv run task manage makemessages`
- Die Übersetzungsdateien in `<app>/locale/<sprache>/LC_MESSAGES/django.po` wurden um alle neuen Übersetzungsstrings erweitert. Bearbeiten und jeweils bei `msgstr` die Übersetzungen einfügen!
- `pdm manage compilemessages`
- `uv run task manage compilemessages`
- Zum Ausprobieren müsst ihr django neu starten um die neuen Übersetzungsdateien zu laden

### Übersetzungen definineren
@@ -189,7 +187,7 @@ oder:

### Static Files einsammeln lassen

- `pdm manage collectstatic`
- `uv run task manage collectstatic`
- ohne dies brechen u.a. Unittests mit Fehlern wie "Missing staticfiles manifest entry" ab

### Tests
@@ -216,8 +214,8 @@ self.assertEqual(translation, "NoTIcket_trans")
Um die Tests ausführen zu können muss der Datenbanknutzer das Recht haben neue Datenbaken anzulegen.
Dafür mit `psql postgres` die Datenbankkonsole starten. Dort `ALTER USER hub_app CREATEDB;` ausführen (ggf. `hub_app` durch den gewählten Nutzernamen ersetzen). Am Ende mit `Strg-D` Konsole wieder schließen.

Um die Django Tests auszuführen kann das Kommando `pdm test` verwendet werden. \
Um nur die Tests einer App auszuführen stattdessen `pdm test -- <app>.tests` ausführen. \
Um die Django Tests auszuführen kann das Kommando `uv run tox -e django-test` verwendet werden. \
Um nur die Tests einer App auszuführen stattdessen `uv run tox -e django-test -- <app>.tests` ausführen. \
Hilfreiche Argumente sind `-v 2` um die ausgeführten Tests anzuzeigen, `--failfast` um nach dem ersten Fehler abzubrechen, und `--keepdb` um nicht jedes mal die Migrationen durchführen zu müssen. \
Für weitere Infos zu dem Befehl ist https://docs.djangoproject.com/en/3.1/ref/django-admin/#django-admin-test hilfreich.

@@ -244,7 +242,7 @@ Dieses hat die folgenden Kommandos:
- `ruff check`: Diess Kommando checkt auf häufige Fehler in python code und hat auch teilweise Möglichkeiten diese zu beheben
- `ruff format`: Dieses Kommando re-formatiert alle python dateien nach einem voregebenen Code-Style

### djLink
### djLint

**Leider ist es nicht möglich djLint so zu konfigurieren, dass es automatisch die richtigen Profile verwendet.**
**Wenn eine Integration in einen Editor gewünscht ist, muss dies berücksichtigt werden!**
+24 −25
Original line number Diff line number Diff line
ARG REGISTRY=""
FROM ${REGISTRY}python:3.13-bookworm AS base
COPY --from=ghcr.io/astral-sh/uv:0.5.21 /uv /uvx /bin/

ENV DEBIAN_FRONTEND=noninteractive
ENV PDM_CHECK_UPDATE=false
# Set up uv environment
ENV UV_LINK_MODE=copy UV_COMPILE_BYTECODE=1 UV_TOOL_BIN_DIR=/opt/uv-bin/

RUN echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/99-unattended-minimal && \
    echo 'APT::Install-Suggests "false";' >> /etc/apt/apt.conf.d/99-unattended-minimal && \
@@ -10,7 +12,6 @@ RUN echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/99-unattended-

RUN --mount=target=/var/lib/apt/lists/,type=cache,sharing=locked \
    --mount=target=/var/cache/apt/archives/,type=cache,sharing=locked \
    --mount=target=/root/.cache/pip,type=cache,sharing=locked \
    # Prevent apt cache cleaning
    rm -f /etc/apt/apt.conf.d/docker-clean && \
    apt-get update && \
@@ -21,12 +22,16 @@ RUN --mount=target=/var/lib/apt/lists/,type=cache,sharing=locked \
    dpkg-reconfigure locales && \
       locale-gen C.UTF-8 && \
       /usr/sbin/update-locale LANG=C.UTF-8 && \
    pip install -U pdm && \
    # Fix caching issue with kaniko see: https://github.com/GoogleContainerTools/kaniko/issues/3246
    mkdir -p /app/plainui

# Add path for future pdm location
ENV PATH="/install/.venv/bin:$PATH"
    # Add path for future uv location
    ENV PATH="/install/.venv/bin:/opt/uv-bin:$PATH"

######################################### [meta] #############################
FROM base AS meta

RUN uv tool install tox --with tox-uv

######################################### [build] #############################

@@ -38,25 +43,24 @@ RUN --mount=target=/var/lib/apt/lists/,type=cache,sharing=locked \
    --mount=target=/var/cache/apt/archives/,type=cache,sharing=locked \
    apt-get update && \
    apt-get install \
        build-essential \
        yarnpkg && \
    /usr/bin/yarnpkg global bin corepack enable &&\
        build-essential && \
    mkdir /install

WORKDIR /install
COPY pyproject.toml pdm.lock README.md /install/
RUN --mount=target=/root/.cache/pdm,type=cache,sharing=locked \
    pdm install --check --prod --no-editable
COPY pyproject.toml uv.lock README.md /install/
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-install-project --no-editable

######################################### [build-dev] #########################

FROM build AS build-dev

WORKDIR /install
RUN --mount=target=/root/.cache/pdm,type=cache,sharing=locked \
    pdm install --check --dev --no-editable
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-install-project --no-editable

######################################### [node-build] ########################

FROM ${REGISTRY}node:20-alpine AS node-base

RUN mkdir -p /app/plainui/
@@ -68,16 +72,6 @@ RUN corepack enable && \
    /usr/local/bin/yarnpkg set version stable && \
    /usr/local/bin/yarnpkg install

######################################### [nginx-forwarder] ###################

FROM ${REGISTRY}nginx:1-alpine-slim AS nginx-forwarder
ENV APP_SOCKET="/run/hub/app.sock"
ENV SCRIPT_NAME=""

COPY deployment/docker/index.html deployment/docker/error_*.html /www/default/
COPY deployment/docker/nginx.conf /etc/nginx/templates/default.conf.template


######################################### [webworker-base] ####################

FROM base AS webworker-base
@@ -96,7 +90,6 @@ COPY deployment/docker/app.sh /usr/local/bin/app
COPY deployment/docker/check_django.sh /usr/local/bin/hub_healthcheck
COPY deployment/docker/check_psql.py /usr/local/bin/postgres_healthcheck

COPY --from=build /install/.venv /install/.venv
ENV PATH="/install/.venv/bin:$PATH"

RUN install -d -m 0755 -o appuser -g appuser /app/hub /data /app/media /run/hub && \
@@ -133,7 +126,12 @@ RUN export DJANGO_SETTINGS_MODULE='hub.settings.build' && \

######################################### [nginx] #############################

FROM nginx-forwarder AS nginx
FROM ${REGISTRY}nginx:1-alpine-slim AS nginx
ENV APP_SOCKET="/run/hub/app.sock"
ENV SCRIPT_NAME=""

COPY deployment/docker/index.html deployment/docker/error_*.html /www/default/
COPY deployment/docker/nginx.conf /etc/nginx/templates/default.conf.template

COPY --from=build-static /app/static.dist /www/static

@@ -141,6 +139,7 @@ COPY --from=build-static /app/static.dist /www/static

FROM webworker-base AS webworker

COPY --from=build /install/.venv /install/.venv
COPY --from=build-static --chown=appuser /app /app
USER appuser

+24 −1
Original line number Diff line number Diff line
@@ -39,9 +39,18 @@ Prodinstanz: <https://api.events.ccc.de/congress/2024/>

| Kategorie  | Endpunkt                                 | GET | POST | PUT | DEL | Beschreibung                                          |
| ---------- | ---------------------------------------- | --- | ---- | --- | --- | ----------------------------------------------------- |
| Auth       | `/auth/get-token`                        |     | x    |     |     | Ausstellen eines API-Tokens                           |
| Persönlich | `/me`                                    | x   |      | x   |     | eigenes Profil / Settings                             |
| Persönlich | `/me/friends`                            | x   |      | x   | x   | Liste der Buddies                                     |
| Persönlich | `/me/badges`                             | x   |      |     |     | Liste aller Badges/Achievements                       |
| Persönlich | `/me/events`                             | x   |      |     |     | Favorisierte Events                                   |
| Persönlich | `/me/events/<uuid>/`                     |     |      | x   | x   | Events (ent-)favorisieren                             |
| Persönlich | `/me/friends`                            | x   |      | x   | x   | Liste der Buddies                                     |
| Persönlich | `/me/received-messages/`                 | x   |      |     |     | Übersicht empfangener PN                              |
| Persönlich | `/me/received-messages/<uuid>`           | x   |      |     |     | Details einer empfangenen PN                          |
| Persönlich | `/me/send-message`                       |     | x    |     |     | Send a new PN                                         |
| Persönlich | `/me/sent-messages/`                     | x   |      |     |     | Übersicht gesendeter PN                               |
| Persönlich | `/me/sent-messages/<uuid>`               | x   |      |     |     | Details einer gesendeten PN                           |
| Persönlich | `/me/delete-message/<uuid>`              | x   |      |     |     | PN löschen                                            |
| Konferenz  | `/`                                      | x   |      |     |     | Metadaten des Konferenz                               |
| Konferenz  | `/tags`                                  | x   |      |     |     | Liste aller Tags auf der Konferenz                    |
| Konferenz  | `/tracks`                                | x   | x    |     |     | Liste der Tracks                                      |
@@ -64,6 +73,20 @@ Prodinstanz: <https://api.events.ccc.de/congress/2024/>
Per POST werden neue Einträge angelegt, per PUT bestehende verändert.
Details zu den einzelnen Endpunkten folgen in Kürze™.

### API-Beispiel mit cURL

Zuerst einen Token generieren:

```bash
curl https://{API_URL}/api/auth/get-token -H "Content-Type: application/json" -X POST --data '{"username": "{USERNAME}", "password": "{PASSWORD}"}'
```

Mit diesem Token können dann Endpunkte aufgerufen werden die eine Authentifizierung erfordern:

```bash
curl https://{API_URL}/api/me -H "Content-Type: application/json" -H "Authorization: Token {API_TOKEN}"
```

## Development

see [Development.md](./Development.md)
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ if [ ! -e "$HOME/$ADMIN_CREATED" -a -n "$DJANGO_CREATE_ADMIN_PASSWORD" ]; then
    touch $HOME/$ADMIN_CREATED
fi

touch $HOME/PREPARATION_DONE

if [ "$1" == "webworker" -o "$STARTMODE" == "webworker" ]; then
    # start gunicorn (might be called indirectly via supervisor when started with 'all')
    gunicorn_params=()
@@ -75,12 +77,7 @@ if [ "$1" == "shell" -o "$1" == "createsuperuser" -o "$1" == "test" ]; then
fi

if [ "$1" == "housekeeping" ]; then
    interval="${HOUSEKEEPING_SLEEP_SECONDS:-300}"
    if [ "$interval" -gt 0 ]; then
        python3 $APP_HOME/manage.py housekeeping --forever --forever-delay="$interval"
    else
        python3 $APP_HOME/manage.py housekeeping
    fi
    python3 $APP_HOME/manage.py housekeeping --forever
fi

cat <<EOD
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ TOKEN = env('API_TOKEN')
PER_PAGE = 100
DELETE_ALL = datetime.now(tz=UTC) - timedelta(weeks=env('THRESHOLD_ALL'))
DELETE_FAILED = datetime.now(tz=UTC) - timedelta(weeks=env('THRESHOLD_FAILED'))
BASE_URL = f'{env('CI_API_V4_URL')}/projects/{env("CI_PROJECT_ID")}'
BASE_URL = f'{env("CI_API_V4_URL")}/projects/{env("CI_PROJECT_ID")}'

if TOKEN is None:
    raise ValueError('API_TOKEN is required')

pdm.lock

deleted100644 → 0
+0 −2126

File deleted.

Preview size limit exceeded, changes collapsed.

+220 −50
Original line number Diff line number Diff line
@@ -2,9 +2,7 @@
name = "hub"
dynamic = ["version"]
description = "Management tool for chaos events."
authors = [
    {name = "Roang", email = "lucas@brandstaetter.tech"},
]
authors = [{ name = "Hub Team", email = "hub@cccv.de" }]
dependencies = [
    "babel~=2.16",
    "bleach~=6.1",
@@ -39,69 +37,59 @@ dependencies = [
    "segno~=1.6.1",
    "sentry-sdk>=2.17.0,<3",
    "tzdata~=2024.2",
    "pdm>=2.11.2",
    "psycopg[binary,pool]>=3.2.3",
    "gunicorn>=23.0.0",
    "pydantic>=2.9.2",
    "django-rich>=1.13.0",
    "django-csp>=3.8",
    "rules>=3.5",
    "django-ical>=1.9.2",
    "django-stubs-ext>=5.1.2",
    "ipython>=8.31.0",
    "django-extensions>=3.2.3",
    "python-magic>=0.4.27",
]
requires-python = "==3.13.*"
readme = "README.md"
license = { text = "MIT" }

[project.optional-dependencies]
watchfiles = [
    "django-watchfiles>=1.0.0",
]
[tool.pdm]
distribution = false

[tool.pdm.version]
source = "scm"
write_to = "version.txt"

[tool.pdm.dev-dependencies]
lint = [
    "ruff>=0.1.11",
    "djlint>=1.35.4",
]
local = [
    "debugpy>=1.8.0",
    "icecream>=2.1.3",
]
[dependency-groups]
dev = [
    "tox>=4.11.4",
    "coverage>=7.4.0",
    "tox-pdm>=0.7.2",
    "pre-commit>=3.6.0",
    "docutils>=0.21.2",
    "pre-commit>=3.6.0",
    "tblib>=3.0.0",
    "tox-uv>=1.19.0",
    "tox>=4.11.4",
    "taskipy>=1.14.1",
]
lint = ["ruff>=0.1.11", "djlint>=1.35.4"]
local = ["debugpy>=1.8.0", "icecream>=2.1.3"]
typing = [
    "django-stubs[mypy-compatible]>=5.1.1",
]
static-analysis = [
    "pylint>=3.3.1",
    "pylint-django>=2.6.1",
    "pyright>=1.1.392.post0",
    "djangorestframework-stubs[compatible-mypy]>=1.4.0",
    "django-stubs>=5.1.2",
]
static-analysis = ["pylint>=3.3.1", "pylint-django>=2.6.1"]
watchfiles = ["django-watchfiles>=1.0.0"]

[tool.pdm.scripts]
# Generic scripts
whoami = { shell = "echo `{pdm} -V` was called as '{pdm} -V'" }
# uv currently has no task runner, use taskipy instead.
# Ref: https://github.com/astral-sh/uv/issues/5903
[tool.taskipy.tasks]
# Application version
app_version = "./src/manage.py appversion"
# Django scripts
start = "./src/manage.py runserver"
shell = "./src/manage.py shell"
manage = "./src/manage.py"
start = { cmd = "./src/manage.py runserver", cwd = "." }
shell = { cmd = "./src/manage.py shell_plus", cwd = "." }
manage = { cmd = "./src/manage.py", cwd = "." }
compilemessages = { cmd = "./manage.py compilemessages", cwd = "./src" }
# TOX scripts
all = "tox"
check-migrations = "tox -e migrations"
coverage-report = "tox -e coverage-report"
style-check = {composite = ["format", "lint"]}
format = {composite = ["py-format", "html-format"]}
lint = {composite = ["py-lint", "html-lint"]}
style-check = "task format && task lint"
format = "tox -e py-format,html-format"
lint = "tox -e py-lint,html-lint"
py-format = "tox -e py-format"
py-lint = "tox -e py-lint"
html-format = "tox -e html-format"
@@ -112,15 +100,20 @@ live-test = "tox -e live-test"
[tool.coverage.run]
data_file = ".tools/coverage/coverage"
dynamic_context = "test_function"
omit =[
    "*/migrations/*"]
omit = ["*/migrations/*"]
branch = true

[tool.coverage.report]
show_missing = true
exclude_also = [
    "def __repr__",
    "if settings.DEBUG",
    "if TYPE_CHECKING:",
    "raise NotImplementedError",
]

[tool.coverage.xml]
output = ".tools/coverage/coverage.xml"
output = ".tools/coverage/report.xml"

[tool.coverage.html]
directory = ".tools/coverage/html_report"
@@ -130,10 +123,187 @@ indent = 2
ignore = "H006,H013,H021,H022,H030,H031"
linter_output_format = "{filename}:{line}: {code} {message} {match}"
preserve_blank_lines = true
extend_exclude=".tools"
# We neeed to override the default settings for the GitLab CI
# Ref: https://github.com/djlint/djLint/issues/1028
exclude = ".venv"
extend_exclude = "__pypackages__,_build,.bzr,.direnv,.eggs,.git,.git-rewrite,.hg,.ipynb_checkpoints,.mypy_cache,.nox,.pants.d,.pytest_cache,.pytype,.ruff_cache,.svn,.tox,.venv,.vscode,buck-out,dist,node_modules,venv,.tools"

[tool.mypy]
plugins = ["mypy_django_plugin.main"]

[tool.django-stubs]
django_settings_module = "hub.settings.base"

[tool.tox]
requires = ["tox>=4"]
env_list = [
    "py-lint",
    "py-format",
    "html-lint",
    "html-format",
    "django-test",
    "coverage-repor",
]
work_dir = ".tools/tox"

[tool.tox.env_run_base]
runner = "uv-venv-lock-runner"
skip_install = true

[tool.tox.env.hub.set_env]
ALLOWED_HOSTS = { replace = "env", name = "ALLOWED_HOSTS" }
DATABASE_URL = { replace = "env", name = "DATABASE_URL" }
DJANGO_DEBUG = "I_KNOW_WHAT_I_AM_DOING"
DJANGO_SETTINGS_MODULE = "hub.settings.test"
DISABLE_REQUEST_LOGGING = "True"
SERVE_API = "True"
SERVE_BACKOFFICE = "True"
SERVE_FRONTEND = "True"
SSO_SECRET_GENERATE = "True"
STORAGE_TYPE = "local"
USE_PLAIN_STATICFILES = "True"
METRICS_SERVER_IPS = "127.0.0.1,localhost"

[tool.tox.env.py-lint]
uv_sync_flags = ["--only-group=lint"]
commands = [["ruff", "check", "."]]

[tool.tox.env.py-format]
uv_sync_flags = ["--only-group=lint"]
commands = [["ruff", "format", ".", "--diff"]]

[tool.tox.env.html-lint]
uv_sync_flags = ["--only-group=lint"]
commands = [
    [
        "djlint",
        "--profile",
        "jinja",
        "-e",
        "j2",
        "--lint",
        ".",
    ],
    [
        "djlint",
        "--profile",
        "django",
        "-e",
        "html",
        "--lint",
        ".",
    ],
]

[tool.tox.env.html-format]
uv_sync_flags = ["--only-group=lint"]
commands = [
    [
        "djlint",
        "--profile",
        "jinja",
        "-e",
        "j2",
        "--reformat",
        ".",
    ],
    [
        "djlint",
        "--profile",
        "django",
        "-e",
        "html",
        "--reformat",
        ".",
    ],
]

[tool.tox.env.django-test]
set_env = [
    { replace = "ref", of = [
        "tool",
        "tox",
        "env",
        "hub",
        "set_env",
    ] },
    { PYTHONWARNINGS = "always" },
]
allowlist_externals = ["coverage"]
dependency_groups = ["dev"]
commands = [
    [
        "coverage",
        "run",
        "--concurrency=multiprocessing",
        "{toxinidir}/src/manage.py",
        "test",
        "-v",
        "2",
        "--parallel=8",
        'src',
        { replace = "posargs", extend = true },
    ],
    [
        "coverage",
        "combine",
    ],
]

[tool.tox.env.django-test-single]
set_env = [
    { replace = "ref", of = [
        "tool",
        "tox",
        "env",
        "hub",
        "set_env",
    ] },
    { PYTHONWARNINGS = "always" },
]
dependency_groups = ["dev"]
change_dir = "{toxinidir}/src"
allowlist_externals = ["coverage"]
commands = [
    [
        "coverage",
        "run",
        "./manage.py",
        "test",
        "-v",
        "2",
        { replace = "posargs", extend = true },
    ],
]

[tool.tox.env.live-test]
dependency_groups = ["dev"]
change_dir = "{toxinidir}"
commands = [["python", "-m", "unittest", "{posargs}"]]

[tool.tox.env.live-test.set_env]
PYTHONWARNINGS = "always"
SERVE_API = "yes"

[tool.tox.env.coverage-report]
deps = ["coverage"]
commands = [["coverage", "report"], ["coverage", "xml"], ["coverage", "html"]]

[tool.pyright]

include = ["src"]
exclude = [
    "**/node_modules",
    "**/dist",
    "**/build",
    "**/.venv",
    "**/.vscode",
    "**/.tools",
]
venvPath = "."
venv = ".venv"
verboseOutput = true

reportMissingTypeArgument = "information"
reportPrivateUsage = "information"
typeCheckingMode = "off"             # "off", "basic", "standard", "strict"
Original line number Diff line number Diff line
# This file is @generated by PDM.
# Please do not edit it manually.

# This file was autogenerated by uv via the following command:
#    uv export --frozen -o=requirements.dev.txt --no-hashes --all-groups
annotated-types==0.7.0
anyio==4.6.2.post1
anyio==4.8.0
asgiref==3.8.1
astroid==3.3.5
asttokens==2.4.1
babel==2.16.0
beautifulsoup4==4.12.3
astroid==3.3.8
asttokens==3.0.0
babel==2.17.0
beautifulsoup4==4.13.3
bleach==6.2.0
blinker==1.9.0
boto3==1.35.71
botocore==1.35.71
cachetools==5.5.0
certifi==2024.8.30
cffi==1.17.1; platform_python_implementation != "PyPy"
boto3==1.36.26
botocore==1.36.26
cachetools==5.5.2
certifi==2025.1.31
cffi==1.17.1 ; platform_python_implementation != 'PyPy'
cfgv==3.4.0
chardet==5.2.0
charset-normalizer==3.4.0
click==8.1.7
charset-normalizer==3.4.1
click==8.1.8
colorama==0.4.6
coverage==7.6.8
cryptography==43.0.3
cssbeautifier==1.15.1
debugpy==1.8.9
coverage==7.6.12
cryptography==44.0.1
cssbeautifier==1.15.3
debugpy==1.8.12
decorator==5.2.0
defusedxml==0.7.1
dep-logic==0.4.9
dill==0.3.9; python_version >= "3.11"
dill==0.3.9
distlib==0.3.9
django==5.1.3
django==5.1.6
django-bootstrap5==24.3
django-cors-headers==4.6.0
django-cors-headers==4.7.0
django-csp==3.8
django-debug-toolbar==4.4.6
django-environ==0.11.2
django-modeltranslation==0.19.11
django-extensions==3.2.3
django-ical==1.9.2
django-modeltranslation==0.19.12
django-oauth-toolkit==3.0.1
django-ratelimit==4.1.0
django-recurrence==1.11.1
django-redis==5.4.0
django-rich==1.13.0
django-storages==1.14.4
django-stubs-ext==5.1.1
django-stubs[mypy-compatible]==5.1.1
django-rich==1.14.0
django-storages==1.14.5
django-stubs==5.1.3
django-stubs-ext==5.1.3
django-timezone-field==7.0
django-watchfiles==1.1.0
django-widget-tweaks==1.5.0
djangorestframework==3.15.2
djlint==1.36.2
djangorestframework-stubs==3.15.3
djlint==1.36.4
docutils==0.21.2
editorconfig==0.12.4
editorconfig==0.17.0
et-xmlfile==2.0.0
executing==2.1.0
filelock==3.16.1
findpython==0.6.2
executing==2.2.0
filelock==3.17.0
freezegun==1.5.1
gunicorn==23.0.0
h11==0.14.0
hishel==0.0.33
httpcore==1.0.7
httpx[socks]==0.27.2
icecream==2.1.3
identify==2.6.2
icalendar==6.1.1
icecream==2.1.4
identify==2.6.7
idna==3.10
installer==0.7.0
isort==5.13.2
jinja2==3.1.4
ipython==8.32.0
isort==6.0.0
jedi==0.19.2
jinja2==3.1.5
jmespath==1.0.1
jsbeautifier==1.15.1
json5==0.9.28
jsbeautifier==1.15.3
json5==0.10.0
jwcrypto==1.5.6
lxml==5.3.0
lxml==5.3.1
markdown-it-py==3.0.0
markdownify==0.13.1
markupsafe==3.0.2
matplotlib-inline==0.1.7
mccabe==0.7.0
mdurl==0.1.2
mistletoe==1.4.0
msgpack==1.1.0
mslex==1.3.0 ; sys_platform == 'win32'
mypy==1.15.0
mypy-extensions==1.0.0
nodeenv==1.9.1
numpy==2.1.3; python_version >= "3.12"
numpy==2.2.3
oauthlib==3.2.2
odfpy==1.4.1
openpyxl==3.1.5
ordered-set==4.1.0
packaging==24.2
pandas==2.2.3
parso==0.8.4
pathspec==0.12.1
pbs-installer==2024.10.16
pdm==2.21.0
pexpect==4.9.0 ; sys_platform != 'emscripten' and sys_platform != 'win32'
pillow==10.4.0
platformdirs==4.3.6
pluggy==1.5.0
pre-commit==4.0.1
psycopg-binary==3.2.3; implementation_name != "pypy"
psycopg-pool==3.2.4
psycopg[binary,pool]==3.2.3
pycparser==2.22; platform_python_implementation != "PyPy"
pydantic==2.10.2
pydantic-core==2.27.1
pygments==2.18.0
pre-commit==4.1.0
prompt-toolkit==3.0.50
psutil==6.1.1
psycopg==3.2.4
psycopg-binary==3.2.4 ; implementation_name != 'pypy'
psycopg-pool==3.2.5
ptyprocess==0.7.0 ; sys_platform != 'emscripten' and sys_platform != 'win32'
pure-eval==0.2.3
pycparser==2.22 ; platform_python_implementation != 'PyPy'
pydantic==2.10.6
pydantic-core==2.27.2
pygments==2.19.1
pyjwt==2.9.0
pylint==3.3.1
pylint==3.3.4
pylint-django==2.6.1
pylint-plugin-utils==0.8.2
pyproject-api==1.8.0
pyproject-hooks==1.2.0
pyproject-api==1.9.0
pyright==1.1.394
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
pytz==2024.2
python-magic==0.4.27
pytz==2025.1
pyyaml==6.0.2
redis==5.2.0
redis==5.2.1
regex==2024.11.6
requests==2.32.3
requests-file==2.1.0
resolvelib==1.1.0
rich==13.9.4
ruff==0.8.0
ruff==0.9.7
rules==3.5
s3transfer==0.10.4
s3transfer==0.11.2
segno==1.6.1
sentry-sdk==2.19.0
shellingham==1.5.4
six==1.16.0
sentry-sdk==2.22.0
six==1.17.0
sniffio==1.3.1
socksio==1.0.0
soupsieve==2.6
sqlparse==0.5.2
sqlparse==0.5.3
stack-data==0.6.3
taskipy==1.14.1
tblib==3.0.0
tomli==2.2.1
tomlkit==0.13.2
tox==4.23.2
tox-pdm==0.7.2
tox==4.24.1
tox-uv==1.25.0
tqdm==4.67.1
truststore==0.10.0; python_version >= "3.10"
types-pyyaml==6.0.12.20240917
traitlets==5.14.3
types-pyyaml==6.0.12.20241230
types-requests==2.32.0.20241016
typing-extensions==4.12.2
tzdata==2024.2
unearth==0.17.2
urllib3==2.2.3
virtualenv==20.27.1
urllib3==2.3.0
uv==0.6.2
virtualenv==20.29.2
watchfiles==1.0.4
wcwidth==0.2.13
webencodings==0.5.1
+53 −58
Original line number Diff line number Diff line
# This file is @generated by PDM.
# Please do not edit it manually.

# This file was autogenerated by uv via the following command:
#    uv export --frozen -o=requirements.txt --no-hashes --no-dev
annotated-types==0.7.0
anyio==4.6.2.post1
asgiref==3.8.1
babel==2.16.0
beautifulsoup4==4.12.3
asttokens==3.0.0
babel==2.17.0
beautifulsoup4==4.13.3
bleach==6.2.0
blinker==1.9.0
boto3==1.35.71
botocore==1.35.71
certifi==2024.8.30
cffi==1.17.1; platform_python_implementation != "PyPy"
charset-normalizer==3.4.0
cryptography==43.0.3
boto3==1.36.26
botocore==1.36.26
certifi==2025.1.31
cffi==1.17.1 ; platform_python_implementation != 'PyPy'
charset-normalizer==3.4.1
colorama==0.4.6 ; sys_platform == 'win32'
cryptography==44.0.1
decorator==5.2.0
defusedxml==0.7.1
dep-logic==0.4.9
distlib==0.3.9
django==5.1.3
django==5.1.6
django-bootstrap5==24.3
django-cors-headers==4.6.0
django-cors-headers==4.7.0
django-csp==3.8
django-debug-toolbar==4.4.6
django-environ==0.11.2
django-modeltranslation==0.19.11
django-extensions==3.2.3
django-ical==1.9.2
django-modeltranslation==0.19.12
django-oauth-toolkit==3.0.1
django-ratelimit==4.1.0
django-recurrence==1.11.1
django-redis==5.4.0
django-rich==1.13.0
django-storages==1.14.4
django-rich==1.14.0
django-storages==1.14.5
django-stubs-ext==5.1.3
django-timezone-field==7.0
django-widget-tweaks==1.5.0
djangorestframework==3.15.2
et-xmlfile==2.0.0
filelock==3.16.1
findpython==0.6.2
executing==2.2.0
freezegun==1.5.1
gunicorn==23.0.0
h11==0.14.0
hishel==0.0.33
httpcore==1.0.7
httpx[socks]==0.27.2
icalendar==6.1.1
idna==3.10
installer==0.7.0
jinja2==3.1.4
ipython==8.32.0
jedi==0.19.2
jinja2==3.1.5
jmespath==1.0.1
jwcrypto==1.5.6
lxml==5.3.0
lxml==5.3.1
markdown-it-py==3.0.0
markdownify==0.13.1
markupsafe==3.0.2
matplotlib-inline==0.1.7
mdurl==0.1.2
mistletoe==1.4.0
msgpack==1.1.0
numpy==2.1.3; python_version >= "3.12"
numpy==2.2.3
oauthlib==3.2.2
odfpy==1.4.1
openpyxl==3.1.5
ordered-set==4.1.0
packaging==24.2
pandas==2.2.3
pbs-installer==2024.10.16
pdm==2.21.0
parso==0.8.4
pexpect==4.9.0 ; sys_platform != 'emscripten' and sys_platform != 'win32'
pillow==10.4.0
platformdirs==4.3.6
psycopg-binary==3.2.3; implementation_name != "pypy"
psycopg-pool==3.2.4
psycopg[binary,pool]==3.2.3
pycparser==2.22; platform_python_implementation != "PyPy"
pydantic==2.10.2
pydantic-core==2.27.1
pygments==2.18.0
prompt-toolkit==3.0.50
psycopg==3.2.4
psycopg-binary==3.2.4 ; implementation_name != 'pypy'
psycopg-pool==3.2.5
ptyprocess==0.7.0 ; sys_platform != 'emscripten' and sys_platform != 'win32'
pure-eval==0.2.3
pycparser==2.22 ; platform_python_implementation != 'PyPy'
pydantic==2.10.6
pydantic-core==2.27.2
pygments==2.19.1
pyjwt==2.9.0
pyproject-hooks==1.2.0
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
pytz==2024.2
redis==5.2.0
python-magic==0.4.27
pytz==2025.1
redis==5.2.1
requests==2.32.3
requests-file==2.1.0
resolvelib==1.1.0
rich==13.9.4
rules==3.5
s3transfer==0.10.4
s3transfer==0.11.2
segno==1.6.1
sentry-sdk==2.19.0
shellingham==1.5.4
six==1.16.0
sniffio==1.3.1
socksio==1.0.0
sentry-sdk==2.22.0
six==1.17.0
soupsieve==2.6
sqlparse==0.5.2
tomlkit==0.13.2
truststore==0.10.0; python_version >= "3.10"
sqlparse==0.5.3
stack-data==0.6.3
traitlets==5.14.3
typing-extensions==4.12.2
tzdata==2024.2
unearth==0.17.2
urllib3==2.2.3
virtualenv==20.27.1
urllib3==2.3.0
wcwidth==0.2.13
webencodings==0.5.1

src/.pdm-python

0 → 100644
+1 −0
Original line number Diff line number Diff line
/install/.venv/bin/python
 No newline at end of file

src/api/ical.py

0 → 100644
+75 −0
Original line number Diff line number Diff line
from typing import Optional

from django_ical.views import ICalFeed

from django.utils.text import slugify

from core.models import (
    Conference,
    Event,
)


class EventICalFeed(ICalFeed):
    """
    EventICalFeed serializes Events to an iCal response.
    """

    def __init__(self, events: list[Event], name: Optional[str] = None, conference: Optional[Conference] = None):
        super().__init__()
        self.name = name
        self.conference = conference
        self.events = events

    def product_id(self) -> str:
        issuer = self.conference.name if self.conference else 'Hub'
        product = self.name if self.name else 'iCal export'
        return f'-//{issuer}//{product}'

    def title(self) -> str:
        if self.name:
            return self.name
        return 'Hub iCal export'

    def items(self) -> list[Event]:
        return self.events

    def item_title(self, item) -> str:
        return item.name

    def item_description(self, item) -> str:
        return item.description

    def item_start_datetime(self, item):
        return item.schedule_start

    def item_end_datetime(self, item):
        return item.schedule_end

    def item_location(self, item) -> str:
        if item.room:
            return item.room.name
        if item.location:
            return item.location
        return ''

    def item_guid(self, item) -> str:
        return item.pk

    def item_categories(self, item) -> list[str]:
        categories = []
        if item.recording == Event.Recording.YES:
            categories.append('recorded')
        elif item.recording == Event.Recording.NO:
            categories.append('not recorded')

        if item.kind == Event.Kind.OFFICIAL or item.assembly.is_official:
            categories.append('official')

        if item.track:
            categories.append(item.track.name)

        return categories

    def file_name(self) -> str:
        return slugify(self.title()) + '.ics'
+0 −36
Original line number Diff line number Diff line
# Generated by Django 3.1.2 on 2020-10-31 14:30

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('core', '0005_remove_children_and_fsk'),
    ]

    operations = [
        migrations.CreateModel(
            name='StickerToken',
            fields=[
                ('token', models.CharField(max_length=50, primary_key=True, serialize=False)),
                ('permanent', models.BooleanField(default=False)),
                ('issued', models.DateTimeField(auto_now_add=True)),
                ('sticker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.sticker')),
            ],
        ),
        migrations.CreateModel(
            name='RoomLinkUserId',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
                ('roomlink', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.roomlink')),
                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)),
            ],
        ),
    ]
Original line number Diff line number Diff line
# Generated by Django 3.1.2 on 2020-11-09 10:36

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('core', '0007_rename_stickers_to_badges'),
        ('api', '0001_initial'),
    ]

    operations = [
        migrations.AlterField(
            model_name='StickerToken',
            name='sticker',
            field=models.ForeignKey(on_delete=models.deletion.CASCADE, related_name='+', to='core.badge'),
        ),
        migrations.RenameModel(old_name='StickerToken', new_name='BadgeToken'),
        migrations.RenameField(model_name='BadgeToken', old_name='sticker', new_name='badge'),
    ]
+0 −16
Original line number Diff line number Diff line
# Generated by Django 3.1.4 on 2020-12-25 21:21

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('api', '0002_rename_stickers_to_badges'),
    ]

    operations = [
        migrations.DeleteModel(
            name='BadgeToken',
        ),
    ]
Original line number Diff line number Diff line
# Generated by Django 3.2.10 on 2022-01-26 21:50

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('api', '0003_delete_badgetoken'),
    ]

    database_operations = [
        migrations.AlterModelTable('RoomLinkUserId', 'core_roomlinkuserid')
    ]

    state_operations = [
        migrations.DeleteModel('RoomLinkUserId')
    ]

    operations = [
        migrations.SeparateDatabaseAndState(
            database_operations=database_operations,
            state_operations=state_operations)
    ]