No description
  • Python 78.8%
  • HTML 18.3%
  • Shell 1.9%
  • Dockerfile 0.9%
Find a file
2026-10-30 12:29:28 +00:00
antibooking fitst commit 2026-10-23 18:35:46 +01:00
core Sposta import dei test del seed in cima al modulo 2026-10-25 18:17:03 +00:00
infra Adatta Compose a Nginx Proxy Manager con frontend per media 2026-10-29 16:39:20 +00:00
static fitst commit 2026-10-23 18:35:46 +01:00
templates Aggiungi sito web ai promoter e guida di deploy su Hetzner 2026-10-23 18:43:28 +01:00
.dockerignore fitst commit 2026-10-23 18:35:46 +01:00
.env.example fitst commit 2026-10-23 18:35:46 +01:00
.gitignore Adatta Compose a Nginx Proxy Manager con frontend per media 2026-10-29 16:39:20 +00:00
build_css.sh fitst commit 2026-10-23 18:35:46 +01:00
docker-compose.yml Adatta Compose a Nginx Proxy Manager con frontend per media 2026-10-29 16:39:20 +00:00
Dockerfile fitst commit 2026-10-23 18:35:46 +01:00
manage.py fitst commit 2026-10-23 18:35:46 +01:00
README.md aggiorna TODO.md 2026-10-30 12:29:28 +00:00
requirements.txt fitst commit 2026-10-23 18:35:46 +01:00
TODO.md aggiorna TODO.md 2026-10-30 12:29:28 +00:00

Antibooking

Piattaforma web indipendente per mettere in contatto direttamente artisti e promoter/locali per concerti dal vivo nel circuito indipendente.

  • Artisti: profilo con bio, generi, città, embed audio/video, scheda tecnica e press kit in PDF, calendario delle disponibilità.
  • Promoter/locali: profilo con capienza, impianto audio e vitto/alloggio, ricerca degli artisti per genere, città e disponibilità last minute.

conceptz: https://pad.cisti.org/p/antibooking

stack

  • python 3.12 e django 5.2 (SQLite in modalità WAL)
  • django templates (SSR), HTMX per ricerca e filtri, Tailwind CSS per lo stile (binario standalone, niente Node.js)
  • Gunicorn e WhiteNoise in produzione, Docker Compose per il deploy
  • Reverse proxy HTTPS esterno all'app

sviluppo locale

setup

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env

nel .env locale imposta DJANGO_SECRET_KEY (una stringa casuale, ad esempio python3 -c "import secrets; print(secrets.token_urlsafe(50))") e DJANGO_DEBUG=True. Poi:

./build_css.sh                     # genera static/css/output.css
python manage.py migrate
python manage.py createsuperuser   # opzionale, per l'admin
python manage.py runserver

Il sito è su http://127.0.0.1:8000/, l'admin su http://127.0.0.1:8000/admin/.

variabili d'ambiente

variabile uso default
DJANGO_SECRET_KEY chiave segreta (obbligatoria, l'app non parte senza) —
DJANGO_DEBUG True solo in locale False
DJANGO_ALLOWED_HOSTS host accettati, separati da virgola vuoto
DJANGO_CSRF_TRUSTED_ORIGINS origini https per i form in produzione vuoto
DJANGO_DEFAULT_FROM_EMAIL mittente delle email Antibooking <noreply@antibooking.local>
EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, EMAIL_USE_TLS SMTP se EMAIL_HOST è vuoto, le email vanno in console

dati di prova

python manage.py seed_test_data

crea 10 artisti (artista01@example.com … artista10@example.com) e 3 promoter (promoter01@example.com … promoter03@example.com), tutti con password test-password-123. I link audio e video sono video YouTube pubblici e generici, usati solo per provare gli embed. Il comando è idempotente e rifiuta di girare se DJANGO_DEBUG non è True.

test

python manage.py test core

comandi utili

python manage.py shell                 # shell Django con i modelli già importati
python manage.py makemigrations core   # dopo una modifica ai modelli
python manage.py check                 # controlli di sistema
python manage.py showmigrations core   # stato delle migrazioni

debug

  • Con DJANGO_DEBUG=True gli errori mostrano il traceback completo nel browser. Non impostarlo mai sul server.
  • Le email di contatto (/contatta/<id>/) non partono davvero: compaiono nel terminale dove gira runserver.
  • Per ispezionare il database usa python manage.py dbshell oppure un browser SQLite sul file data/db.sqlite3. Con WAL attivo, chiudi il server prima di copiare il file a mano.

errori frequenti:

sintomo causa probabile
DJANGO_SECRET_KEY non è impostata manca il .env o la variabile
unable to open database file cartella data/ mancante o non scrivibile
400 Bad Request con dominio corretto host assente in DJANGO_ALLOWED_HOSTS
403 CSRF verification failed in produzione origine https assente in DJANGO_CSRF_TRUSTED_ORIGINS
429 sul form di contatto più di 2 messaggi in un minuto dalla stessa sessione: aspetta un minuto
pagina senza stile manca static/css/output.css: esegui ./build_css.sh

produzione

Antibooking ha un unico deploy di produzione. La gestione del server, degli accessi e del proxy resta separata da questo README; qui sono raccolti i comandi dell'applicazione, da eseguire nella directory del progetto con Docker Compose disponibile.

L'app gira in due container:

  • web: Gunicorn con l'applicazione, sulla rete privata del progetto, senza porte pubblicate.
  • antibooking-frontend: Nginx che serve /media/ in sola lettura e inoltra il resto a web. È l'unico servizio collegato alla rete proxy_default, condivisa con il reverse proxy.

Il reverse proxy esterno termina HTTPS e inoltra il dominio a antibooking-frontend:80, passando X-Forwarded-Proto. I file statici sono serviti da WhiteNoise. Il Compose non pubblica alcuna porta sull'host.

configurazione

cp .env.example .env && chmod 600 .env
nano .env

imposta almeno:

DJANGO_SECRET_KEY=<stringa casuale nuova, diversa da quella locale>
DJANGO_DEBUG=False
DJANGO_ALLOWED_HOSTS=antibooking.example.org
DJANGO_CSRF_TRUSTED_ORIGINS=https://antibooking.example.org
DJANGO_DEFAULT_FROM_EMAIL=Antibooking <noreply@example.org>
EMAIL_HOST=<server SMTP>
EMAIL_PORT=587
EMAIL_HOST_USER=<utente SMTP>
EMAIL_HOST_PASSWORD=<password SMTP>
EMAIL_USE_TLS=True

crea le cartelle prima del primo avvio, altrimenti Docker le crea di proprietà di root:

mkdir -p data media
sudo chown -R 1000:1000 data media

Il container usa UID/GID 1000:1000. Verifica anche che l'utente che esegue i backup possa leggere il database e scrivere in data/, senza allargare indiscriminatamente i permessi.

primo avvio

docker compose build                                  # esegue build_css.sh e collectstatic
docker compose run --rm web python manage.py migrate
docker compose run --rm web python manage.py createsuperuser
docker compose up -d
docker compose exec web python manage.py check --deploy

pre deploy: prova login, form, invio email, CSS e caricamento e apertura degli upload. Valuta HSTS solo dopo aver verificato HTTPS. Con il redirect HTTP→HTTPS fatto dal proxy, check --deploy segnala ancora security.W008; finché HSTS non è attivo, segnala anche security.W004. Sono entrambi attesi.

backup

Lo script richiede sqlite3 sull'host. Provalo con lo stesso utente che eseguira' i backup programmati:

bash infra/backup.sh

I backup finiscono in data/backup_YYYY-MM-DD.sqlite3, ne restano 7. Programma l'esecuzione sul server e copia i backup anche fuori dal server. Salva separatamente gli upload in media/, il .env e la configurazione di deploy, proteggendo le copie che contengono credenziali. Prova anche il ripristino.

procedure operative

Eseguire dalla directory del progetto sul server.

Aggiornare il sito:

bash infra/backup.sh
git pull --ff-only
docker compose up -d --build
docker compose exec web python manage.py migrate

Diagnosi:

docker compose ps
docker compose logs -f web
docker compose exec web python manage.py check --deploy

Ripristino da backup (con il sito fermo):

docker compose stop
cp data/backup_YYYY-MM-DD.sqlite3 data/db.sqlite3
rm -f data/db.sqlite3-wal data/db.sqlite3-shm
sudo chown 1000:1000 data/db.sqlite3
docker compose start

Non riavviare gli altri progetti del server per aggiornare Antibooking.

test

python manage.py test core

struttura repo

antibooking/          configurazione Django (settings, urls, wsgi/asgi)
core/
  models.py           User, Artist, Promoter, Availability
  backends.py         autenticazione con email
  forms.py            ricerca, login, registrazione, profili, disponibilità, contatto
  views.py            search, dettagli, profilo, contatto (con limite di invio)
  validators.py       whitelist dei domini per gli embed
  templatetags/
    embed_tags.py     filtro generate_embed (regex per Mirlo, Bandcamp, Spotify, YouTube)
  management/commands/
    seed_test_data.py dati di prova (solo con DEBUG)
  admin.py            backoffice
templates/            base.html, pagine in templates/core/
static/src/input.css  sorgente Tailwind
static/vendor/        htmx.min.js servito localmente
build_css.sh          build del CSS con il binario standalone di Tailwind
infra/backup.sh       backup giornaliero di SQLite
Dockerfile            immagine dell'app (Gunicorn, uid 1000)
docker-compose.yml    servizi web (Gunicorn) e antibooking-frontend (Nginx)
infra/nginx/antibooking.conf  configurazione Nginx del frontend: media e proxy verso web

note

  • Il login avviene con email e password; lo username è generato automaticamente alla registrazione.
  • L'email reale non compare mai nell'HTML: per contattare un utente si usa il form su /contatta/<id>/, che invia il messaggio via send_mail.
  • Gli embed non sono salvati come HTML: il filtro ricostruisce l'iframe solo dagli ID estratti da URL validati, con sandbox attivo.
  • Le immagini caricate finiscono in media/.
  • Le decisioni aperte e i punti da sistemare prima del deploy sono in TODO.md.