From a9741b685955fbb0d6bcbc8289c1b02cb1a3c866 Mon Sep 17 00:00:00 2001 From: kai Date: Wed, 26 Aug 2026 17:08:10 +0200 Subject: [PATCH] Add social features and harden beta release --- .gitignore | 1 + app/Dockerfile | 2 +- app/main.py | 1086 +++++++++++++++-- app/static/css/style.css | 37 +- app/static/images/black-denim-texture.webp | Bin 0 -> 169970 bytes app/static/style.css | 60 + app/templates/_user_menu.html | 10 + app/templates/account_link.html | 4 + app/templates/admin_patches.html | 2 +- app/templates/admin_users.html | 10 +- app/templates/admin_venues.html | 25 +- app/templates/concert_detail.html | 90 +- app/templates/edit_concert.html | 63 +- app/templates/index.html | 177 ++- app/templates/login.html | 1 + app/templates/messages.html | 60 + app/templates/new_concert.html | 67 +- app/templates/password_reset.html | 4 + app/templates/profile.html | 145 ++- app/templates/register.html | 2 + compose.yml | 1 + db/init/01_initial.sql | 56 +- db/migrations/05_event_categories.sql | 10 + db/migrations/06_user_instagram.sql | 2 + db/migrations/07_friendships_and_privacy.sql | 18 + db/migrations/08_direct_messages.sql | 15 + .../09_profile_privacy_and_flyer_links.sql | 12 + db/migrations/10_release_safety.sql | 28 + 28 files changed, 1804 insertions(+), 184 deletions(-) create mode 100644 app/static/images/black-denim-texture.webp create mode 100644 app/templates/_user_menu.html create mode 100644 app/templates/account_link.html create mode 100644 app/templates/messages.html create mode 100644 app/templates/password_reset.html create mode 100644 db/migrations/05_event_categories.sql create mode 100644 db/migrations/06_user_instagram.sql create mode 100644 db/migrations/07_friendships_and_privacy.sql create mode 100644 db/migrations/08_direct_messages.sql create mode 100644 db/migrations/09_profile_privacy_and_flyer_links.sql create mode 100644 db/migrations/10_release_safety.sql diff --git a/.gitignore b/.gitignore index 73ce422..357235e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ env/ .env .env.* !.env.example +compose.dev.yml # Logs *.log diff --git a/app/Dockerfile b/app/Dockerfile index 7bb86f1..8e391ed 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -2,7 +2,7 @@ FROM python:3.13-slim WORKDIR /app -RUN pip install --no-cache-dir fastapi uvicorn "psycopg[binary]" python-multipart jinja2 httpx bcrypt +RUN pip install --no-cache-dir fastapi uvicorn "psycopg[binary]" python-multipart jinja2 httpx bcrypt Pillow COPY . . diff --git a/app/main.py b/app/main.py index bac8473..b25f54f 100644 --- a/app/main.py +++ b/app/main.py @@ -3,6 +3,11 @@ import uuid import secrets import hashlib import re +import time +import threading +from collections import defaultdict, deque +from io import BytesIO +from urllib.parse import urlparse from contextlib import asynccontextmanager from datetime import datetime, timedelta @@ -10,6 +15,11 @@ import bcrypt import httpx import psycopg +try: + from PIL import Image, ImageOps, UnidentifiedImageError +except ImportError: + Image = ImageOps = UnidentifiedImageError = None + from fastapi import FastAPI, File, Form, Request, UploadFile from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.staticfiles import StaticFiles @@ -56,13 +66,18 @@ os.makedirs(PATCH_DIR, exist_ok=True) SESSION_COOKIE = "pingu_session" SESSION_DAYS = 30 +COOKIE_SECURE = os.environ.get("COOKIE_SECURE", "false").lower() in {"1", "true", "yes"} ALLOWED_IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp"} MAX_IMAGE_BYTES = 10 * 1024 * 1024 +MAX_IMAGE_PIXELS = 25_000_000 +rate_limit_buckets = defaultdict(deque) +rate_limit_lock = threading.Lock() INITIAL_ADMIN_USERNAME = os.environ.get("INITIAL_ADMIN_USERNAME") INITIAL_ADMIN_PASSWORD = os.environ.get("INITIAL_ADMIN_PASSWORD") INITIAL_ADMIN_EMAIL = os.environ.get("INITIAL_ADMIN_EMAIL") BADGE_DEFINITIONS = ( + ("founder", "Gründer", "⚔️", None, "Von Anfang an dabei und Pingu Concerts mit aufgebaut", "special"), ("beta_tester", "Beta Tester", "🧪", None, "In der Beta dabei", "beta"), ("first_gig", "Erster Gig", "🎸", 1, "Dein erstes besuchtes Konzert", "attendance"), ("regular", "Stammgast", "🤘", 5, "5 Konzerte besucht", "attendance"), @@ -152,13 +167,30 @@ def ensure_schema(): concert_id INTEGER NOT NULL REFERENCES concerts(id) ON DELETE CASCADE, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, status VARCHAR(20) NOT NULL CHECK ( - status IN ('attending', 'maybe', 'ticket_search') + status IN ('attending', 'maybe', 'ticket_search', 'ticket_offer') ), updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (concert_id, user_id) ) """, """ + DO $$ + BEGIN + IF EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conname = 'concert_attendance_status_check' + AND NOT ( + pg_get_constraintdef(oid) LIKE '%ticket_search%' + AND pg_get_constraintdef(oid) LIKE '%ticket_offer%' + ) + ) THEN + ALTER TABLE concert_attendance DROP CONSTRAINT concert_attendance_status_check; + ALTER TABLE concert_attendance ADD CONSTRAINT concert_attendance_status_check + CHECK (status IN ('attending', 'maybe', 'ticket_search', 'ticket_offer')); + END IF; + END $$ + """, + """ CREATE TABLE IF NOT EXISTS user_badges ( user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, badge_code VARCHAR(50) NOT NULL, @@ -190,6 +222,118 @@ def ensure_schema(): CREATE INDEX IF NOT EXISTS idx_venue_aliases_alias ON venue_aliases (LOWER(alias)) """, + """ + ALTER TABLE concerts + ADD COLUMN IF NOT EXISTS event_type VARCHAR(20) NOT NULL DEFAULT 'concert' + CHECK (event_type IN ('concert', 'festival', 'other')) + """, + """ + ALTER TABLE concerts + ADD COLUMN IF NOT EXISTS parent_event_id INTEGER + REFERENCES concerts(id) ON DELETE SET NULL + """, + """ + CREATE INDEX IF NOT EXISTS idx_concerts_parent_event_id + ON concerts (parent_event_id) + """, + """ + ALTER TABLE users + ADD COLUMN IF NOT EXISTS instagram_url VARCHAR(500) + """, + """ + ALTER TABLE users DROP COLUMN IF EXISTS email_verified + """, + """ + CREATE TABLE IF NOT EXISTS account_tokens ( + id SERIAL PRIMARY KEY, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + purpose VARCHAR(30) NOT NULL CHECK (purpose = 'password_reset'), + token_hash TEXT NOT NULL UNIQUE, + expires_at TIMESTAMP NOT NULL, + used_at TIMESTAMP, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + ) + """, + """ + DO $$ + BEGIN + IF EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conname = 'account_tokens_purpose_check' + AND pg_get_constraintdef(oid) LIKE '%verify_email%' + ) THEN + DELETE FROM account_tokens WHERE purpose = 'verify_email'; + ALTER TABLE account_tokens DROP CONSTRAINT account_tokens_purpose_check; + ALTER TABLE account_tokens ADD CONSTRAINT account_tokens_purpose_check + CHECK (purpose = 'password_reset'); + END IF; + END $$ + """, + """ + CREATE INDEX IF NOT EXISTS idx_account_tokens_lookup + ON account_tokens (token_hash, purpose, expires_at) + """, + """ + ALTER TABLE users + ADD COLUMN IF NOT EXISTS profile_visibility VARCHAR(20) NOT NULL DEFAULT 'friends' + CHECK (profile_visibility IN ('public', 'friends', 'nobody')) + """, + """ + ALTER TABLE users ALTER COLUMN profile_visibility SET DEFAULT 'friends' + """, + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conname = 'users_profile_visibility_check' + AND pg_get_constraintdef(oid) LIKE '%nobody%' + ) THEN + ALTER TABLE users DROP CONSTRAINT IF EXISTS users_profile_visibility_check; + ALTER TABLE users ADD CONSTRAINT users_profile_visibility_check + CHECK (profile_visibility IN ('public', 'friends', 'nobody')); + END IF; + END $$ + """, + """ + ALTER TABLE concerts ADD COLUMN IF NOT EXISTS flyer_url TEXT + """, + """ + CREATE TABLE IF NOT EXISTS friendships ( + id SERIAL PRIMARY KEY, + requester_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + addressee_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + status VARCHAR(20) NOT NULL DEFAULT 'pending' + CHECK (status IN ('pending', 'accepted')), + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CHECK (requester_id <> addressee_id), + UNIQUE (requester_id, addressee_id) + ) + """, + """ + CREATE UNIQUE INDEX IF NOT EXISTS idx_friendships_pair + ON friendships (LEAST(requester_id, addressee_id), GREATEST(requester_id, addressee_id)) + """, + """ + CREATE TABLE IF NOT EXISTS direct_messages ( + id SERIAL PRIMARY KEY, + sender_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + recipient_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + body TEXT NOT NULL, + read_at TIMESTAMP, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CHECK (sender_id <> recipient_id) + ) + """, + """ + CREATE INDEX IF NOT EXISTS idx_direct_messages_conversation + ON direct_messages (sender_id, recipient_id, created_at) + """, + """ + CREATE INDEX IF NOT EXISTS idx_direct_messages_unread + ON direct_messages (recipient_id, read_at) + """, ] with get_db_connection() as connection: @@ -199,12 +343,11 @@ def ensure_schema(): if INITIAL_ADMIN_USERNAME and INITIAL_ADMIN_PASSWORD: cursor.execute( - "SELECT id FROM users WHERE username = %s", - (INITIAL_ADMIN_USERNAME,), + "SELECT EXISTS (SELECT 1 FROM users)", ) - existing_user = cursor.fetchone() + users_exist = cursor.fetchone()[0] - if not existing_user: + if not users_exist: cursor.execute( """ INSERT INTO users ( @@ -239,12 +382,56 @@ async def lifespan(_app: FastAPI): app = FastAPI(title="Pingu Concerts", lifespan=lifespan) +@app.middleware("http") +async def security_controls(request: Request, call_next): + if request.method in {"POST", "PUT", "PATCH", "DELETE"}: + origin = request.headers.get("origin") + fetch_site = request.headers.get("sec-fetch-site") + origin_host = urlparse(origin).netloc if origin else None + expected_host = request.headers.get("host", request.url.netloc) + if fetch_site == "cross-site" or (origin_host and origin_host != expected_host): + return HTMLResponse("Anfrage aus fremder Quelle abgelehnt.", status_code=403) + + path = request.url.path + if path == "/login": + bucket_name, limit, window = "login", 10, 15 * 60 + elif path == "/register" or path.startswith("/password-reset"): + bucket_name, limit, window = "account", 10, 60 * 60 + elif path.startswith("/messages/"): + bucket_name, limit, window = "messages", 30, 60 + elif any(part in path for part in ("/photos", "/patches")) or path in {"/profile", "/concerts"}: + bucket_name, limit, window = "uploads", 20, 60 * 60 + else: + bucket_name, limit, window = "writes", 120, 60 + client_host = request.client.host if request.client else "unknown" + key = (client_host, bucket_name) + now = time.monotonic() + with rate_limit_lock: + bucket = rate_limit_buckets[key] + while bucket and bucket[0] <= now - window: + bucket.popleft() + if len(bucket) >= limit: + return HTMLResponse("Zu viele Anfragen. Bitte später erneut versuchen.", status_code=429, + headers={"Retry-After": str(window)}) + bucket.append(now) + + response = await call_next(request) + response.headers["X-Content-Type-Options"] = "nosniff" + response.headers["X-Frame-Options"] = "DENY" + response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin" + response.headers["Permissions-Policy"] = "camera=(), microphone=(), geolocation=()" + if COOKIE_SECURE: + response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains" + return response + + @app.middleware("http") async def require_login(request: Request, call_next): if ( request.url.path == "/login" or request.url.path == "/register" or request.url.path.startswith("/register/") + or request.url.path.startswith("/password-reset") or request.url.path.startswith("/static/") ): return await call_next(request) @@ -294,6 +481,25 @@ def generate_token() -> str: return secrets.token_urlsafe(32) +def create_account_token(user_id: int, purpose: str, hours: int = 24) -> str: + token = generate_token() + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + "DELETE FROM account_tokens WHERE user_id = %s AND purpose = %s AND used_at IS NULL", + (user_id, purpose), + ) + cursor.execute( + """ + INSERT INTO account_tokens (user_id, purpose, token_hash, expires_at) + VALUES (%s, %s, %s, %s) + """, + (user_id, purpose, hash_token(token), datetime.now() + timedelta(hours=hours)), + ) + connection.commit() + return token + + def user_from_row(row): if not row: return None @@ -303,6 +509,9 @@ def user_from_row(row): "username": row[1], "display_name": row[2] or row[1], "is_admin": bool(row[3]), + "pending_friend_count": row[4], + "unread_message_count": row[5], + "notification_count": row[4] + row[5], } @@ -320,7 +529,11 @@ def get_current_user(request: Request): users.id, users.username, users.display_name, - users.is_admin + users.is_admin, + (SELECT COUNT(*) FROM friendships + WHERE addressee_id = users.id AND status = 'pending'), + (SELECT COUNT(*) FROM direct_messages + WHERE recipient_id = users.id AND read_at IS NULL) FROM sessions JOIN users ON users.id = sessions.user_id @@ -363,6 +576,8 @@ def attach_session(response: RedirectResponse, token: str) -> RedirectResponse: max_age=SESSION_DAYS * 24 * 60 * 60, httponly=True, samesite="lax", + secure=COOKIE_SECURE, + path="/", ) return response @@ -379,6 +594,85 @@ def concert_is_past(start_datetime, end_datetime) -> bool: return end < datetime.now() +EVENT_TYPES = { + "concert": "Konzert", + "festival": "Festival", + "other": "Sonstiges", +} + + +def get_linkable_events(exclude_id: int | None = None): + with get_db_connection() as connection: + with connection.cursor() as cursor: + exclude_clause = "AND id <> %s" if exclude_id is not None else "" + parameters = (exclude_id,) if exclude_id is not None else () + cursor.execute( + f""" + SELECT id, artist, start_datetime, event_type + FROM concerts + WHERE event_type IN ('concert', 'festival') + AND DATE( + CASE + WHEN event_type = 'festival' + THEN COALESCE(end_datetime, start_datetime) + ELSE start_datetime + END + ) >= CURRENT_DATE + {exclude_clause} + ORDER BY start_datetime DESC + """, + parameters, + ) + rows = cursor.fetchall() + return [ + { + "id": row[0], + "title": row[1], + "date": row[2].strftime("%d.%m.%Y"), + "event_type": row[3], + "event_type_label": EVENT_TYPES[row[3]], + } + for row in rows + ] + + +def resolve_event_relationship(cursor, event_type: str, parent_event_id: str, event_id=None): + if event_type not in EVENT_TYPES: + raise ValueError("Ungültige Veranstaltungskategorie.") + if event_type != "other" or not parent_event_id: + return None + + try: + parent_id = int(parent_event_id) + except ValueError as error: + raise ValueError("Ungültige Hauptveranstaltung.") from error + if event_id is not None and parent_id == event_id: + raise ValueError("Eine Veranstaltung kann nicht mit sich selbst verknüpft werden.") + + cursor.execute( + """ + SELECT + event_type, + DATE( + CASE + WHEN event_type = 'festival' + THEN COALESCE(end_datetime, start_datetime) + ELSE start_datetime + END + ) >= CURRENT_DATE AS is_linkable + FROM concerts + WHERE id = %s + """, + (parent_id,), + ) + parent = cursor.fetchone() + if not parent or parent[0] not in {"concert", "festival"}: + raise ValueError("Die Hauptveranstaltung muss ein Konzert oder Festival sein.") + if not parent[1]: + raise ValueError("Die Hauptveranstaltung ist bereits beendet und kann nicht mehr verknüpft werden.") + return parent_id + + def load_concert(concert_id: int): with get_db_connection() as connection: with connection.cursor() as cursor: @@ -401,10 +695,17 @@ def load_concert(concert_id: int): venues.city, venues.country, venues.latitude, - venues.longitude + venues.longitude, + concerts.event_type, + concerts.parent_event_id, + parent_event.artist, + parent_event.event_type, + concerts.flyer_url FROM concerts LEFT JOIN venues ON concerts.venue_id = venues.id + LEFT JOIN concerts AS parent_event + ON concerts.parent_event_id = parent_event.id WHERE concerts.id = %s """, (concert_id,), @@ -427,6 +728,7 @@ def load_concert(concert_id: int): "ticket_url": row[5], "ticket_price": row[6], "flyer_path": row[7], + "flyer_url": row[21], "created_by": row[8], "is_past": is_past, "date": start_datetime.strftime("%d.%m.%Y"), @@ -435,6 +737,14 @@ def load_concert(concert_id: int): "end_date": end_datetime.strftime("%d.%m.%Y") if end_datetime else None, "end_time": end_datetime.strftime("%H:%M") if end_datetime else None, "end_local": end_datetime.strftime("%Y-%m-%dT%H:%M") if end_datetime else "", + "event_type": row[17], + "event_type_label": EVENT_TYPES[row[17]], + "parent_event": { + "id": row[18], + "title": row[19], + "event_type": row[20], + "event_type_label": EVENT_TYPES.get(row[20]), + } if row[18] else None, "venue": { "id": row[9], "name": row[10] or "Veranstaltungsort unbekannt", @@ -477,7 +787,7 @@ def can_delete_concert(user, concert) -> bool: def serialize_concert_card(row): - concert_id, artist, start_datetime, venue, city = row + concert_id, artist, start_datetime, end_datetime, venue, city, event_type, parent_event_id = row venue_text = venue or "Veranstaltungsort unbekannt" if city: venue_text += f", {city}" @@ -487,10 +797,118 @@ def serialize_concert_card(row): "artist": artist, "date": start_datetime.strftime("%d.%m.%Y"), "time": start_datetime.strftime("%H:%M"), + "end_date": end_datetime.strftime("%d.%m.%Y") if end_datetime else None, "venue": venue_text, + "event_type": event_type, + "event_type_label": EVENT_TYPES[event_type], + "parent_event_id": parent_event_id, + "children": [], + "_start_datetime": start_datetime, + "_end_datetime": end_datetime, } +def build_event_overview(rows): + cards = {row[0]: serialize_concert_card(row) for row in rows} + roots = [] + for card in cards.values(): + parent = cards.get(card["parent_event_id"]) + if card["event_type"] == "other" and parent: + parent["children"].append(card) + else: + roots.append(card) + + for card in roots: + card["children"].sort(key=lambda child: child["_start_datetime"]) + + upcoming = [card for card in roots if not concert_is_past( + card["_start_datetime"], card["_end_datetime"] + )] + past = [card for card in roots if card not in upcoming] + upcoming.sort(key=lambda card: card["_start_datetime"]) + past.sort(key=lambda card: card["_start_datetime"], reverse=True) + return upcoming, past + + +def load_event_overview(search_query: str = ""): + query = """ + SELECT concerts.id, concerts.artist, concerts.start_datetime, + concerts.end_datetime, venues.name, venues.city, + concerts.event_type, concerts.parent_event_id + FROM concerts + LEFT JOIN venues ON concerts.venue_id = venues.id + ORDER BY concerts.start_datetime ASC + """ + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute(query) + upcoming, past = build_event_overview(cursor.fetchall()) + + term = search_query.strip().casefold() + if not term: + return upcoming, past + + def matches(card): + text = f"{card['artist']} {card['venue']} {card['event_type_label']}".casefold() + return term in text or any(matches(child) for child in card["children"]) + + return ( + [card for card in upcoming if matches(card)], + [card for card in past if matches(card)], + ) + + +def search_users(search_query: str): + term = search_query.strip() + if not term: + return [] + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + """ + SELECT username, COALESCE(display_name, username), avatar_path + FROM users + WHERE username ILIKE %s OR COALESCE(display_name, '') ILIKE %s + ORDER BY COALESCE(display_name, username), username + LIMIT 30 + """, + (f"%{term}%", f"%{term}%"), + ) + return [ + {"username": row[0], "display_name": row[1], "avatar_path": row[2]} + for row in cursor.fetchall() + ] + + +def normalize_instagram_url(value: str): + value = value.strip() + if not value: + return None + if value.startswith("@"): + value = value[1:] + if re.fullmatch(r"[A-Za-z0-9._]{1,30}", value): + return f"https://www.instagram.com/{value}/" + + candidate = value if "://" in value else f"https://{value}" + parsed = urlparse(candidate) + if (parsed.hostname or "").lower() not in {"instagram.com", "www.instagram.com"}: + raise ValueError("Bitte einen gültigen Instagram-Profillink eingeben.") + username = parsed.path.strip("/").split("/", 1)[0] + if not re.fullmatch(r"[A-Za-z0-9._]{1,30}", username): + raise ValueError("Bitte einen gültigen Instagram-Profillink eingeben.") + return f"https://www.instagram.com/{username}/" + + +def normalize_external_url(value: str, field_name: str): + value = value.strip() + if not value: + return None + parsed = urlparse(value) + if parsed.scheme not in {"http", "https"} or not parsed.hostname or parsed.username or parsed.password: + raise ValueError(f"Bitte für {field_name} eine vollständige HTTP- oder HTTPS-Adresse eingeben.") + return value + + def save_image(upload: UploadFile, destination_dir: str, url_prefix: str): if not upload or not upload.filename: return None, None @@ -503,8 +921,6 @@ def save_image(upload: UploadFile, destination_dir: str, url_prefix: str): status_code=400, ) - filename = str(uuid.uuid4()) + extension - destination = os.path.join(destination_dir, filename) contents = upload.file.read() if len(contents) > MAX_IMAGE_BYTES: @@ -513,12 +929,52 @@ def save_image(upload: UploadFile, destination_dir: str, url_prefix: str): status_code=400, ) + if Image is None: + return None, HTMLResponse( + "Die sichere Bildprüfung ist noch nicht installiert. Bitte den Web-Container neu bauen.", + status_code=503, + ) + + try: + Image.MAX_IMAGE_PIXELS = MAX_IMAGE_PIXELS + with Image.open(BytesIO(contents)) as candidate: + candidate.verify() + with Image.open(BytesIO(contents)) as candidate: + image = ImageOps.exif_transpose(candidate) + if image.width * image.height > MAX_IMAGE_PIXELS: + raise ValueError("Bildauflösung zu groß") + image.thumbnail((2400, 2400)) + if image.mode not in {"RGB", "RGBA"}: + image = image.convert("RGBA" if "transparency" in image.info else "RGB") + output = BytesIO() + image.save(output, format="WEBP", quality=88, method=6) + safe_contents = output.getvalue() + except (ValueError, OSError, UnidentifiedImageError, Image.DecompressionBombError): + return None, HTMLResponse( + "Die Datei ist kein gültiges oder unterstütztes Bild.", status_code=400 + ) + + filename = str(uuid.uuid4()) + ".webp" + destination = os.path.join(destination_dir, filename) with open(destination, "wb") as file: - file.write(contents) + file.write(safe_contents) return f"{url_prefix}{filename}", None +def remove_uploaded_file(path: str | None, destination_dir: str, url_prefix: str): + if not path or not path.startswith(url_prefix): + return False + relative_name = path.removeprefix(url_prefix) + if not relative_name or os.path.basename(relative_name) != relative_name: + return False + file_path = os.path.join(destination_dir, relative_name) + if not os.path.isfile(file_path): + return False + os.remove(file_path) + return True + + def attended_concert_count(user_id: int) -> int: with get_db_connection() as connection: with connection.cursor() as cursor: @@ -586,7 +1042,8 @@ def load_profile(username: str): with connection.cursor() as cursor: cursor.execute( """ - SELECT id, username, display_name, avatar_path, created_at + SELECT id, username, display_name, avatar_path, created_at, instagram_url, + profile_visibility, is_admin FROM users WHERE LOWER(username) = LOWER(%s) """, @@ -610,6 +1067,10 @@ def load_profile(username: str): "avatar_path": row[3], "created_at": row[4].strftime("%d.%m.%Y"), "registered_at": row[4], + "instagram_url": row[5], + "instagram_handle": row[5].rstrip("/").rsplit("/", 1)[-1] if row[5] else None, + "profile_visibility": row[6], + "is_admin": bool(row[7]), "earned_codes": earned_codes, } @@ -800,7 +1261,13 @@ def admin_users_page(request: Request): with connection.cursor() as cursor: cursor.execute( """ - SELECT id, username, email, display_name, is_admin, created_at + SELECT users.id, users.username, users.email, users.display_name, + users.is_admin, users.created_at, + EXISTS ( + SELECT 1 FROM user_badges + WHERE user_badges.user_id = users.id + AND user_badges.badge_code = 'founder' + ) FROM users ORDER BY is_admin DESC, username ASC """ @@ -815,6 +1282,7 @@ def admin_users_page(request: Request): "display_name": row[3] or row[1], "is_admin": bool(row[4]), "created_at": row[5].strftime("%d.%m.%Y"), + "has_founder_badge": bool(row[6]), } for row in rows ] @@ -889,7 +1357,13 @@ def create_invite(request: Request): with connection.cursor() as cursor: cursor.execute( """ - SELECT id, username, email, display_name, is_admin, created_at + SELECT users.id, users.username, users.email, users.display_name, + users.is_admin, users.created_at, + EXISTS ( + SELECT 1 FROM user_badges + WHERE user_badges.user_id = users.id + AND user_badges.badge_code = 'founder' + ) FROM users ORDER BY is_admin DESC, username ASC """ @@ -904,6 +1378,7 @@ def create_invite(request: Request): "display_name": row[3] or row[1], "is_admin": bool(row[4]), "created_at": row[5].strftime("%d.%m.%Y"), + "has_founder_badge": bool(row[6]), } for row in rows ] @@ -1026,12 +1501,7 @@ def delete_venue(request: Request, venue_id: int): def remove_patch_file(path: str | None): - if not path: - return - filename = os.path.basename(path) - file_path = os.path.join(PATCH_DIR, filename) - if os.path.isfile(file_path): - os.remove(file_path) + remove_uploaded_file(path, PATCH_DIR, "/static/uploads/patches/") @app.post("/admin/patches/{badge_code}") @@ -1097,6 +1567,7 @@ def update_user_role( request: Request, user_id: int, role: str = Form(...), + founder_badge: str = Form(""), ): user = require_admin(request) @@ -1116,6 +1587,20 @@ def update_user_role( "UPDATE users SET is_admin = %s WHERE id = %s", (role == "admin", user_id), ) + if founder_badge == "on": + cursor.execute( + """ + INSERT INTO user_badges (user_id, badge_code) + VALUES (%s, 'founder') + ON CONFLICT (user_id, badge_code) DO NOTHING + """, + (user_id,), + ) + else: + cursor.execute( + "DELETE FROM user_badges WHERE user_id = %s AND badge_code = 'founder'", + (user_id,), + ) connection.commit() return RedirectResponse("/admin/users", status_code=303) @@ -1135,11 +1620,87 @@ def delete_user(request: Request, user_id: int): with get_db_connection() as connection: with connection.cursor() as cursor: + cursor.execute("SELECT avatar_path FROM users WHERE id = %s", (user_id,)) + target_user = cursor.fetchone() + cursor.execute("SELECT path FROM concert_photos WHERE user_id = %s", (user_id,)) + photo_paths = [row[0] for row in cursor.fetchall()] cursor.execute("DELETE FROM users WHERE id = %s", (user_id,)) connection.commit() + if target_user: + remove_uploaded_file(target_user[0], AVATAR_DIR, "/static/uploads/avatars/") + for photo_path in photo_paths: + remove_uploaded_file(photo_path, PHOTO_DIR, "/static/uploads/photos/") + return RedirectResponse("/admin/users", status_code=303) + +@app.post("/admin/users/{user_id}/account-link", response_class=HTMLResponse) +def create_user_account_link(request: Request, user_id: int, purpose: str = Form(...)): + user = require_admin(request) + if not user: + return HTMLResponse("

Nicht erlaubt

", status_code=403) + if purpose != "password_reset": + return HTMLResponse("

Ungültiger Linktyp

", status_code=400) + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute("SELECT username, email FROM users WHERE id = %s", (user_id,)) + target = cursor.fetchone() + if not target: + return HTMLResponse("

Benutzer nicht gefunden

", status_code=404) + token = create_account_token(user_id, purpose, 2) + path = f"/password-reset/{token}" + template = templates.get_template("account_link.html") + return template.render( + user=user, target_username=target[0], target_email=target[1], + purpose=purpose, account_url=f"{str(request.base_url).rstrip('/')}{path}", + ) + + +@app.get("/password-reset/{token}", response_class=HTMLResponse) +def password_reset_page(token: str): + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + """ + SELECT 1 FROM account_tokens WHERE token_hash = %s + AND purpose = 'password_reset' AND used_at IS NULL + AND expires_at > CURRENT_TIMESTAMP + """, + (hash_token(token),), + ) + valid = cursor.fetchone() + if not valid: + return HTMLResponse("

Reset-Link ungültig oder abgelaufen.

", status_code=410) + return templates.get_template("password_reset.html").render(token=token, error=None) + + +@app.post("/password-reset/{token}", response_class=HTMLResponse) +def password_reset(token: str, password: str = Form(...), password_repeat: str = Form(...)): + if len(password) < 10 or password != password_repeat: + return templates.get_template("password_reset.html").render( + token=token, error="Passwörter müssen übereinstimmen und mindestens 10 Zeichen lang sein." + ) + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + """ + SELECT id, user_id FROM account_tokens WHERE token_hash = %s + AND purpose = 'password_reset' AND used_at IS NULL + AND expires_at > CURRENT_TIMESTAMP FOR UPDATE + """, + (hash_token(token),), + ) + account_token = cursor.fetchone() + if not account_token: + return HTMLResponse("

Reset-Link ungültig oder abgelaufen.

", status_code=410) + password_hash = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8") + cursor.execute("UPDATE users SET password_hash = %s WHERE id = %s", (password_hash, account_token[1])) + cursor.execute("UPDATE account_tokens SET used_at = CURRENT_TIMESTAMP WHERE id = %s", (account_token[0],)) + cursor.execute("DELETE FROM sessions WHERE user_id = %s", (account_token[1],)) + connection.commit() + return RedirectResponse("/login?reset=1", status_code=303) + @app.post("/register") def register_user( token: str = Form(...), @@ -1159,9 +1720,9 @@ def register_user( status_code=400 ) - if len(password) < 8: + if len(password) < 10: return HTMLResponse( - "

Fehler

Das Passwort muss mindestens 8 Zeichen lang sein.

", + "

Fehler

Das Passwort muss mindestens 10 Zeichen lang sein.

", status_code=400 ) @@ -1410,7 +1971,7 @@ def logout(request: Request): connection.commit() response = RedirectResponse("/", status_code=303) - response.delete_cookie(SESSION_COOKIE) + response.delete_cookie(SESSION_COOKIE, path="/", secure=COOKIE_SECURE, samesite="lax") return response @@ -1419,39 +1980,31 @@ def logout(request: Request): # ============================================================ @app.get("/", response_class=HTMLResponse) -def home(request: Request): - concert_query = """ - SELECT - concerts.id, - concerts.artist, - concerts.start_datetime, - venues.name, - venues.city - FROM concerts - LEFT JOIN venues - ON concerts.venue_id = venues.id - WHERE COALESCE(concerts.end_datetime, concerts.start_datetime) - {operator} CURRENT_TIMESTAMP - ORDER BY concerts.start_datetime {direction} - """ - - with get_db_connection() as connection: - with connection.cursor() as cursor: - cursor.execute( - concert_query.format(operator=">=", direction="ASC") - ) - upcoming_rows = cursor.fetchall() - - cursor.execute( - concert_query.format(operator="<", direction="DESC") - ) - past_rows = cursor.fetchall() +def home(request: Request, q: str = ""): + upcoming_concerts, _past_concerts = load_event_overview(q) template = templates.get_template("index.html") return template.render( user=get_current_user(request), - upcoming_concerts=[serialize_concert_card(row) for row in upcoming_rows], - past_concerts=[serialize_concert_card(row) for row in past_rows], + upcoming_concerts=upcoming_concerts, + past_concerts=[], + archive=False, + search_query=q.strip(), + user_results=search_users(q), + ) + + +@app.get("/events/past", response_class=HTMLResponse) +def past_events(request: Request, q: str = ""): + _upcoming_concerts, past_concerts = load_event_overview(q) + template = templates.get_template("index.html") + return template.render( + user=get_current_user(request), + upcoming_concerts=[], + past_concerts=past_concerts, + archive=True, + search_query=q.strip(), + user_results=search_users(q), ) @@ -1459,13 +2012,78 @@ def home(request: Request): # Profiles # ============================================================ -def render_profile(request: Request, username: str): +def render_profile( + request: Request, + username: str, + force_own: bool = False, + form_error: str | None = None, + form_success: str | None = None, + instagram_input: str | None = None, + status_code: int = 200, +): viewer = get_current_user(request) profile = load_profile(username) if not profile: return HTMLResponse("

Benutzer nicht gefunden

", status_code=404) + is_own_profile = bool(viewer and viewer["id"] == profile["id"]) + friendship = None + if viewer and not is_own_profile: + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + """ + SELECT id, requester_id, addressee_id, status + FROM friendships + WHERE (requester_id = %s AND addressee_id = %s) + OR (requester_id = %s AND addressee_id = %s) + """, + (viewer["id"], profile["id"], profile["id"], viewer["id"]), + ) + row = cursor.fetchone() + if row: + friendship = { + "id": row[0], "requester_id": row[1], + "addressee_id": row[2], "status": row[3], + } + can_view_details = ( + profile["profile_visibility"] == "public" + or is_own_profile + or bool(viewer and viewer["is_admin"]) + or bool(friendship and friendship["status"] == "accepted") + ) + connections = {"incoming": [], "outgoing": [], "friends": []} + if is_own_profile: + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + """ + SELECT f.id, f.requester_id, f.addressee_id, f.status, + other.username, COALESCE(other.display_name, other.username), + other.avatar_path + FROM friendships f + JOIN users other ON other.id = CASE + WHEN f.requester_id = %s THEN f.addressee_id + ELSE f.requester_id + END + WHERE f.requester_id = %s OR f.addressee_id = %s + ORDER BY f.updated_at DESC + """, + (viewer["id"], viewer["id"], viewer["id"]), + ) + for row in cursor.fetchall(): + item = { + "id": row[0], "requester_id": row[1], "addressee_id": row[2], + "status": row[3], "username": row[4], + "display_name": row[5], "avatar_path": row[6], + } + if row[3] == "accepted": + connections["friends"].append(item) + elif row[2] == viewer["id"]: + connections["incoming"].append(item) + else: + connections["outgoing"].append(item) attended_count = attended_concert_count(profile["id"]) grant_earned_badges( profile["id"], @@ -1489,19 +2107,41 @@ def render_profile(request: Request, username: str): ] template = templates.get_template("profile.html") - return template.render( - user=viewer, - profile=profile, - attended_count=attended_count, - badges=badges, - is_own_profile=viewer["id"] == profile["id"], + return HTMLResponse( + template.render( + user=viewer, + profile=profile, + attended_count=attended_count, + badges=badges, + is_own_profile=force_own or is_own_profile, + can_view_details=can_view_details, + friendship=friendship, + connections=connections, + form_error=form_error, + form_success=form_success, + instagram_input=instagram_input, + ), + status_code=status_code, ) @app.get("/profile", response_class=HTMLResponse) -def own_profile(request: Request): +def own_profile(request: Request, saved: str = ""): user = get_current_user(request) - return render_profile(request, user["username"]) + saved_items = set(saved.split(",")) + messages = [] + if "profile" in saved_items: + messages.append("Profil gespeichert") + if "avatar" in saved_items: + messages.append("Profilbild aktualisiert") + if "instagram" in saved_items: + messages.append("Instagram verknüpft") + return render_profile( + request, + user["username"], + force_own=True, + form_success=" · ".join(messages) if messages else None, + ) @app.get("/users/{username}", response_class=HTMLResponse) @@ -1513,9 +2153,24 @@ def user_profile(request: Request, username: str): async def update_profile( request: Request, display_name: str = Form(""), + instagram_url: str = Form(""), + profile_visibility: str = Form("friends"), avatar: UploadFile | None = File(None), ): user = get_current_user(request) + try: + normalized_instagram_url = normalize_instagram_url(instagram_url) + except ValueError as error: + return render_profile( + request, + user["username"], + force_own=True, + form_error=str(error), + instagram_input=instagram_url, + status_code=400, + ) + if profile_visibility not in {"public", "friends", "nobody"}: + return HTMLResponse("Ungültige Profilsichtbarkeit.", status_code=400) avatar_path, error = save_image( avatar, AVATAR_DIR, @@ -1527,19 +2182,223 @@ async def update_profile( with get_db_connection() as connection: with connection.cursor() as cursor: + cursor.execute("SELECT avatar_path FROM users WHERE id = %s", (user["id"],)) + previous_profile = cursor.fetchone() cursor.execute( """ UPDATE users SET display_name = COALESCE(NULLIF(%s, ''), display_name), - avatar_path = COALESCE(%s, avatar_path) + avatar_path = COALESCE(%s, avatar_path), + instagram_url = %s, + profile_visibility = %s WHERE id = %s + RETURNING avatar_path, instagram_url """, - (display_name.strip(), avatar_path, user["id"]), + (display_name.strip(), avatar_path, normalized_instagram_url, profile_visibility, user["id"]), ) + saved_profile = cursor.fetchone() connection.commit() - return RedirectResponse("/profile", status_code=303) + if not saved_profile: + remove_uploaded_file(avatar_path, AVATAR_DIR, "/static/uploads/avatars/") + return HTMLResponse("

Profil konnte nicht gespeichert werden.

", status_code=500) + if avatar_path and previous_profile and previous_profile[0] != avatar_path: + remove_uploaded_file(previous_profile[0], AVATAR_DIR, "/static/uploads/avatars/") + saved_parts = ["profile"] + if avatar_path and saved_profile[0] == avatar_path: + saved_parts.append("avatar") + if normalized_instagram_url and saved_profile[1] == normalized_instagram_url: + saved_parts.append("instagram") + return RedirectResponse( + f"/profile?saved={','.join(saved_parts)}", + status_code=303, + ) + + +@app.post("/users/{username}/friend-request") +def send_friend_request(request: Request, username: str): + user = get_current_user(request) + profile = load_profile(username) + if not profile: + return HTMLResponse("Benutzer nicht gefunden.", status_code=404) + if profile["id"] == user["id"]: + return HTMLResponse("Du kannst dir nicht selbst eine Anfrage schicken.", status_code=400) + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + """ + INSERT INTO friendships (requester_id, addressee_id) + VALUES (%s, %s) + ON CONFLICT DO NOTHING + """, + (user["id"], profile["id"]), + ) + connection.commit() + return RedirectResponse(f"/users/{profile['username']}", status_code=303) + + +@app.post("/friendships/{friendship_id}/{action}") +def manage_friendship(request: Request, friendship_id: int, action: str): + user = get_current_user(request) + if action not in {"accept", "decline", "remove"}: + return HTMLResponse("Ungültige Aktion.", status_code=400) + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + "SELECT requester_id, addressee_id, status FROM friendships WHERE id = %s", + (friendship_id,), + ) + friendship = cursor.fetchone() + if not friendship or user["id"] not in friendship[:2]: + return HTMLResponse("Freundschaft nicht gefunden.", status_code=404) + if action == "accept": + if friendship[1] != user["id"] or friendship[2] != "pending": + return HTMLResponse("Diese Anfrage kann nicht angenommen werden.", status_code=403) + cursor.execute( + "UPDATE friendships SET status = 'accepted', updated_at = CURRENT_TIMESTAMP WHERE id = %s", + (friendship_id,), + ) + else: + if action == "decline" and (friendship[1] != user["id"] or friendship[2] != "pending"): + return HTMLResponse("Diese Anfrage kann nicht abgelehnt werden.", status_code=403) + cursor.execute("DELETE FROM friendships WHERE id = %s", (friendship_id,)) + connection.commit() + other_id = friendship[1] if friendship[0] == user["id"] else friendship[0] + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute("SELECT username FROM users WHERE id = %s", (other_id,)) + other = cursor.fetchone() + return RedirectResponse(f"/users/{other[0]}" if other else "/", status_code=303) + + +# ============================================================ +# Direct messages +# ============================================================ + +def load_chat_partner(cursor, user, username: str): + cursor.execute( + """ + SELECT u.id, u.username, COALESCE(u.display_name, u.username), u.avatar_path, + u.is_admin + FROM users u + WHERE LOWER(u.username) = LOWER(%s) + AND u.id <> %s + AND (%s OR u.is_admin OR EXISTS ( + SELECT 1 FROM friendships f + WHERE f.status = 'accepted' + AND ((f.requester_id = %s AND f.addressee_id = u.id) + OR (f.addressee_id = %s AND f.requester_id = u.id)) + )) + """, + (username, user["id"], user["is_admin"], user["id"], user["id"]), + ) + row = cursor.fetchone() + if not row: + return None + return {"id": row[0], "username": row[1], "display_name": row[2], + "avatar_path": row[3], "is_admin": bool(row[4])} + + +@app.get("/messages", response_class=HTMLResponse) +def message_inbox(request: Request): + user = get_current_user(request) + conversations = [] + with get_db_connection() as connection: + with connection.cursor() as cursor: + cursor.execute( + """ + SELECT u.id, u.username, COALESCE(u.display_name, u.username), u.avatar_path + FROM users u + WHERE u.id <> %s + AND (%s OR u.is_admin OR EXISTS ( + SELECT 1 FROM friendships f + WHERE f.status = 'accepted' + AND ((f.requester_id = %s AND f.addressee_id = u.id) + OR (f.addressee_id = %s AND f.requester_id = u.id)) + )) + ORDER BY COALESCE(u.display_name, u.username) + """, + (user["id"], user["is_admin"], user["id"], user["id"]), + ) + for row in cursor.fetchall(): + cursor.execute( + """ + SELECT body, created_at, sender_id, + (SELECT COUNT(*) FROM direct_messages + WHERE sender_id = %s AND recipient_id = %s AND read_at IS NULL) + FROM direct_messages + WHERE (sender_id = %s AND recipient_id = %s) + OR (sender_id = %s AND recipient_id = %s) + ORDER BY created_at DESC LIMIT 1 + """, + (row[0], user["id"], user["id"], row[0], row[0], user["id"]), + ) + latest = cursor.fetchone() + conversations.append({ + "id": row[0], "username": row[1], "display_name": row[2], + "avatar_path": row[3], "last_message": latest[0] if latest else None, + "last_at": latest[1].strftime("%d.%m.%Y %H:%M") if latest else None, + "last_from_me": bool(latest and latest[2] == user["id"]), + "unread_count": latest[3] if latest else 0, + }) + template = templates.get_template("messages.html") + return template.render(user=user, conversations=conversations, partner=None, messages=[]) + + +@app.get("/messages/{username}", response_class=HTMLResponse) +def message_conversation(request: Request, username: str): + user = get_current_user(request) + with get_db_connection() as connection: + with connection.cursor() as cursor: + partner = load_chat_partner(cursor, user, username) + if not partner: + return HTMLResponse("Chat nicht erlaubt. Er ist für Freunde und Unterhaltungen mit Admins verfügbar.", status_code=403) + cursor.execute( + """ + UPDATE direct_messages SET read_at = CURRENT_TIMESTAMP + WHERE sender_id = %s AND recipient_id = %s AND read_at IS NULL + """, + (partner["id"], user["id"]), + ) + cursor.execute( + """ + SELECT sender_id, body, created_at + FROM direct_messages + WHERE (sender_id = %s AND recipient_id = %s) + OR (sender_id = %s AND recipient_id = %s) + ORDER BY created_at ASC, id ASC + LIMIT 500 + """, + (user["id"], partner["id"], partner["id"], user["id"]), + ) + messages = [ + {"from_me": row[0] == user["id"], "body": row[1], + "created_at": row[2].strftime("%d.%m.%Y %H:%M")} + for row in cursor.fetchall() + ] + connection.commit() + template = templates.get_template("messages.html") + return template.render(user=get_current_user(request), conversations=[], partner=partner, messages=messages) + + +@app.post("/messages/{username}") +def send_message(request: Request, username: str, body: str = Form(...)): + user = get_current_user(request) + body = body.strip() + if not body or len(body) > 2000: + return HTMLResponse("Eine Nachricht muss zwischen 1 und 2000 Zeichen lang sein.", status_code=400) + with get_db_connection() as connection: + with connection.cursor() as cursor: + partner = load_chat_partner(cursor, user, username) + if not partner: + return HTMLResponse("Chat nicht erlaubt. Er ist für Freunde und Unterhaltungen mit Admins verfügbar.", status_code=403) + cursor.execute( + "INSERT INTO direct_messages (sender_id, recipient_id, body) VALUES (%s, %s, %s)", + (user["id"], partner["id"], body), + ) + connection.commit() + return RedirectResponse(f"/messages/{partner['username']}#latest", status_code=303) # ============================================================ @@ -1557,7 +2416,7 @@ def new_concert(request: Request): return login_redirect("/concerts/new") template = templates.get_template("new_concert.html") - return template.render(user=user) + return template.render(user=user, linkable_events=get_linkable_events()) # ============================================================ @@ -1573,7 +2432,7 @@ def concert_detail(request: Request, concert_id: int): if not concert: return HTMLResponse( - "

Konzert nicht gefunden

", + "

Veranstaltung nicht gefunden

", status_code=404 ) @@ -1665,6 +2524,7 @@ def concert_detail(request: Request, concert_id: int): ] attending_users = [item for item in attendance if item["status"] == "attending"] ticket_seekers = [item for item in attendance if item["status"] == "ticket_search"] + ticket_offers = [item for item in attendance if item["status"] == "ticket_offer"] maybe_users = [item for item in attendance if item["status"] == "maybe"] current_attendance = next( (item["status"] for item in attendance if item["user_id"] == user["id"]), @@ -1684,6 +2544,8 @@ def concert_detail(request: Request, concert_id: int): attending_count=len(attending_users), ticket_seekers=ticket_seekers, ticket_seeker_count=len(ticket_seekers), + ticket_offers=ticket_offers, + ticket_offer_count=len(ticket_offers), maybe_users=maybe_users, maybe_count=len(maybe_users), ) @@ -1697,6 +2559,8 @@ def concert_detail(request: Request, concert_id: int): async def create_concert( request: Request, artist: str = Form(...), + event_type: str = Form("concert"), + parent_event_id: str = Form(""), venue_id: str = Form(""), venue_name: str = Form(""), city: str = Form(""), @@ -1710,6 +2574,7 @@ async def create_concert( description: str = Form(""), ticket_url: str = Form(""), ticket_price: str = Form(""), + flyer_url: str = Form(""), flyer: UploadFile | None = File(None) ): user = get_current_user(request) @@ -1717,6 +2582,19 @@ async def create_concert( if not user: return login_redirect("/concerts/new") + if event_type not in EVENT_TYPES: + return HTMLResponse("

Ungültige Veranstaltungskategorie.

", status_code=400) + if event_type == "festival" and not end_datetime: + return HTMLResponse("

Bei Festivals ist ein Enddatum erforderlich.

", status_code=400) + if event_type != "festival": + end_datetime = "" + if end_datetime and datetime.fromisoformat(end_datetime) < datetime.fromisoformat(start_datetime): + return HTMLResponse("

Das Enddatum darf nicht vor dem Beginn liegen.

", status_code=400) + try: + normalized_flyer_url = normalize_external_url(flyer_url, "den Flyer") + except ValueError as error: + return HTMLResponse(f"

{error}

", status_code=400) + flyer_path, error = save_image( flyer, UPLOAD_DIR, @@ -1728,6 +2606,13 @@ async def create_concert( with get_db_connection() as connection: with connection.cursor() as cursor: + try: + selected_parent_event_id = resolve_event_relationship( + cursor, event_type, parent_event_id + ) + except ValueError as error: + return HTMLResponse(f"

{error}

", status_code=400) + selected_venue_id = resolve_venue( cursor, venue_id, @@ -1744,6 +2629,8 @@ async def create_concert( """ INSERT INTO concerts ( artist, + event_type, + parent_event_id, venue_id, start_datetime, end_datetime, @@ -1751,15 +2638,18 @@ async def create_concert( ticket_url, ticket_price, flyer_path, + flyer_url, created_by ) VALUES ( - %s, %s, %s, %s, %s, %s, %s, %s, %s + %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s ) RETURNING id """, ( artist, + event_type, + selected_parent_event_id, selected_venue_id, start_datetime, end_datetime or None, @@ -1767,6 +2657,7 @@ async def create_concert( ticket_url or None, ticket_price or None, flyer_path, + normalized_flyer_url, user["id"], ), ) @@ -1801,7 +2692,7 @@ def edit_concert_page(request: Request, concert_id: int): if not concert: return HTMLResponse( - "

Konzert nicht gefunden

", + "

Veranstaltung nicht gefunden

", status_code=404 ) @@ -1815,6 +2706,7 @@ def edit_concert_page(request: Request, concert_id: int): return template.render( user=user, concert=concert, + linkable_events=get_linkable_events(exclude_id=concert_id), can_edit_title=can_edit_title(user, concert), can_edit_details=can_edit_details(user, concert), can_delete=can_delete_concert(user, concert), @@ -1826,6 +2718,8 @@ async def edit_concert( request: Request, concert_id: int, artist: str = Form(""), + event_type: str = Form("concert"), + parent_event_id: str = Form(""), venue_id: str = Form(""), venue_name: str = Form(""), city: str = Form(""), @@ -1839,6 +2733,7 @@ async def edit_concert( description: str = Form(""), ticket_url: str = Form(""), ticket_price: str = Form(""), + flyer_url: str = Form(""), flyer: UploadFile | None = File(None) ): user = get_current_user(request) @@ -1850,7 +2745,7 @@ async def edit_concert( if not concert: return HTMLResponse( - "

Konzert nicht gefunden

", + "

Veranstaltung nicht gefunden

", status_code=404 ) @@ -1870,9 +2765,26 @@ async def edit_concert( next_ticket_url = concert["ticket_url"] next_ticket_price = concert["ticket_price"] next_flyer = concert["flyer_path"] + next_flyer_url = concert["flyer_url"] next_venue_id = concert["venue"]["id"] + next_event_type = concert["event_type"] + next_parent_event_id = concert["parent_event"]["id"] if concert["parent_event"] else None if can_edit_details(user, concert): + if event_type not in EVENT_TYPES: + return HTMLResponse("

Ungültige Veranstaltungskategorie.

", status_code=400) + if event_type == "festival" and not end_datetime: + return HTMLResponse("

Bei Festivals ist ein Enddatum erforderlich.

", status_code=400) + if event_type != "festival": + end_datetime = "" + effective_start = start_datetime or concert["start_local"] + if end_datetime and datetime.fromisoformat(end_datetime) < datetime.fromisoformat(effective_start): + return HTMLResponse("

Das Enddatum darf nicht vor dem Beginn liegen.

", status_code=400) + try: + next_flyer_url = normalize_external_url(flyer_url, "den Flyer") + except ValueError as error: + return HTMLResponse(f"

{error}

", status_code=400) + flyer_path, error = save_image( flyer, UPLOAD_DIR, @@ -1883,10 +2795,19 @@ async def edit_concert( with get_db_connection() as connection: with connection.cursor() as cursor: + try: + next_parent_event_id = resolve_event_relationship( + cursor, event_type, parent_event_id, concert_id + ) + except ValueError as error: + return HTMLResponse(f"

{error}

", status_code=400) resolved_venue_id = resolve_venue( cursor, venue_id, - venue_name or concert["venue"]["name"], + venue_name or ( + concert["venue"]["name"] + if concert["venue"]["id"] else "" + ), city, street, postal_code, @@ -1898,6 +2819,7 @@ async def edit_concert( next_start = start_datetime or concert["start_datetime"] next_end = end_datetime or None + next_event_type = event_type next_description = description or None next_ticket_url = ticket_url or None next_ticket_price = ticket_price or None @@ -1911,17 +2833,22 @@ async def edit_concert( UPDATE concerts SET artist = %s, + event_type = %s, + parent_event_id = %s, venue_id = %s, start_datetime = %s, end_datetime = %s, description = %s, ticket_url = %s, ticket_price = %s, - flyer_path = %s + flyer_path = %s, + flyer_url = %s WHERE id = %s """, ( next_artist, + next_event_type, + next_parent_event_id, next_venue_id, next_start, next_end or None, @@ -1929,6 +2856,7 @@ async def edit_concert( next_ticket_url, next_ticket_price, next_flyer, + next_flyer_url, concert_id, ), ) @@ -1951,7 +2879,7 @@ def delete_concert(request: Request, concert_id: int): if not concert: return HTMLResponse( - "

Konzert nicht gefunden

", + "

Veranstaltung nicht gefunden

", status_code=404 ) @@ -1963,12 +2891,18 @@ def delete_concert(request: Request, concert_id: int): with get_db_connection() as connection: with connection.cursor() as cursor: + cursor.execute("SELECT path FROM concert_photos WHERE concert_id = %s", (concert_id,)) + photo_paths = [row[0] for row in cursor.fetchall()] cursor.execute( "DELETE FROM concerts WHERE id = %s", (concert_id,), ) connection.commit() + remove_uploaded_file(concert["flyer_path"], UPLOAD_DIR, "/static/uploads/flyers/") + for photo_path in photo_paths: + remove_uploaded_file(photo_path, PHOTO_DIR, "/static/uploads/photos/") + return RedirectResponse("/", status_code=303) @@ -1982,10 +2916,10 @@ def set_attendance( if not user: return login_redirect(f"/concerts/{concert_id}") - if status not in {"attending", "maybe", "ticket_search"}: + if status not in {"attending", "maybe", "ticket_search", "ticket_offer"}: return HTMLResponse("

Ungültige Auswahl

", status_code=400) if not load_concert(concert_id): - return HTMLResponse("

Konzert nicht gefunden

", status_code=404) + return HTMLResponse("

Veranstaltung nicht gefunden

", status_code=404) with get_db_connection() as connection: with connection.cursor() as cursor: @@ -2020,7 +2954,7 @@ def add_comment( if not concert: return HTMLResponse( - "

Konzert nicht gefunden

", + "

Veranstaltung nicht gefunden

", status_code=404 ) @@ -2074,7 +3008,7 @@ async def add_photo( if not concert: return HTMLResponse( - "

Konzert nicht gefunden

", + "

Veranstaltung nicht gefunden

", status_code=404 ) diff --git a/app/static/css/style.css b/app/static/css/style.css index 0824b01..73a853e 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -1,12 +1,12 @@ :root { - --bg: #0b0f19; - --surface: #151b29; - --surface-hover: #1b2333; - --border: #293449; - --text: #f3f4f6; - --muted: #9ca3af; - --accent: #8b5cf6; - --accent-hover: #7c3aed; + --bg: #050505; + --surface: #101010; + --surface-hover: #1a1111; + --border: #3a3030; + --text: #f5f5f4; + --muted: #a8a29e; + --accent: #b91c1c; + --accent-hover: #dc2626; } * { @@ -23,7 +23,7 @@ body { "Segoe UI", sans-serif; - background: var(--bg); + background: radial-gradient(circle at 50% -15%, #320909 0, transparent 32rem), var(--bg); color: var(--text); } @@ -33,7 +33,7 @@ a { } header { - background: rgba(21, 27, 41, 0.95); + background: rgba(8, 8, 8, 0.96); border-bottom: 1px solid var(--border); position: sticky; top: 0; @@ -54,12 +54,27 @@ header { .logo { font-size: 1.4rem; font-weight: 800; + font-family: Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif; + letter-spacing: .06em; + text-transform: uppercase; } .logo span { color: var(--accent); } +.user-menu { position: relative; margin-left: auto; } +.user-menu summary { padding: 9px 12px; border: 1px solid var(--border); border-radius: 9px; cursor: pointer; list-style: none; font-weight: 700; } +.user-menu summary::-webkit-details-marker { display: none; } +.user-menu[open] summary { border-color: var(--accent); background: var(--surface-hover); } +.user-menu-panel { position: absolute; top: calc(100% + 7px); right: 0; z-index: 100; min-width: 170px; padding: 7px; background: #090909; border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 14px 35px rgba(0,0,0,.6); } +.user-menu-panel a, .user-menu-panel button { display: block; width: 100%; padding: 10px 11px; color: var(--text); background: transparent; border: 0; border-radius: 7px; text-align: left; font: inherit; cursor: pointer; } +.user-menu-panel a:hover, .user-menu-panel button:hover { background: var(--surface-hover); color: #f87171; } +.user-menu-panel form { max-width: none; margin: 0; } +.metal-notification { position: relative; display: inline-block; margin-left: 5px; color: #ef4444; filter: saturate(1.5); } +.metal-notification b { position: absolute; top: -7px; right: -9px; min-width: 16px; padding: 1px 4px; color: #fff; background: #b91c1c; border-radius: 999px; font: 700 .65rem/1.3 system-ui, sans-serif; text-align: center; } +.menu-count { float: right; min-width: 22px; padding: 1px 6px; color: #fff; background: #b91c1c; border-radius: 999px; text-align: center; } + main { max-width: 1100px; margin: 0 auto; @@ -73,6 +88,8 @@ main { .page-title h1 { margin: 0; font-size: 2rem; + font-family: Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif; + letter-spacing: .04em; } .page-title p { diff --git a/app/static/images/black-denim-texture.webp b/app/static/images/black-denim-texture.webp new file mode 100644 index 0000000000000000000000000000000000000000..42f138cb43894e8e7e8d5dde47c51a1bbb2048e5 GIT binary patch literal 169970 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
  • 7*W?8K_icGn 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%0A0Pr5nV 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%0DCNY z`p;KmNUXX%aFsurx1Afg^blk`LFQg{mB;j+k6z|3JDA9pMazV-87+(VxnBlMykM$5 zqS$3gz#lsJC6~3=oc6|%FH7q#miFju#7~U@xGr7mce6(0KU*Ull52vO^}5KOq__{u zL*rcAa~jj}!t@kw_Xb5-is4P_(Hmn|O8CKIBMPJ@ z??^dy$Qq;WO@x2PB2J*6o4RdguHJIIL^vc`1VDLFXLwwv6p_5o5T{rSlzoyDz&Ftf zF$&YvWStS03e1*h<5FV{+b8$_QtV8W?^c2r+~^xQo{Y}tk|h9LVmQlOGEXHtq& zGJrk?$DpjmbnrotRFR^{=s>UAHV5=3XpkM=W1&sqYis5~9}`z}M)0>|dHvcC$*<|kkK|sF0;C=ub1e{=mRHvQ5XYV%6|5$|A@ZD#u4|cvox+m~9F+1{= zCy(~;Myw^|ID>K|;+pZh4&LVILakin1%!XBwEvC6E5)a_lk0e93a39H^$;0(Hl(3O zQNiy7r|`pC

    `wI9jfzKj;=k?V6IX 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≥UUy{zgzoww`-9FIeky-^Kf5Kq(_*)pCn*E^#q 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 qo=CotL782~X*O_z(2Yu^!N +

    ☠ {{ user.display_name }}{% if user.notification_count %} 🤘{{ user.notification_count }}{% endif %} +
    + diff --git a/app/templates/account_link.html b/app/templates/account_link.html new file mode 100644 index 0000000..5d2cb19 --- /dev/null +++ b/app/templates/account_link.html @@ -0,0 +1,4 @@ +Account-Link · Pingu Concerts +
    {% include '_user_menu.html' %}
    +

    Passwort zurücksetzen

    Reset-Link für @{{ target_username }} · {{ target_email }}

    +

    Diesen persönlichen Link sicher an den User senden. Er ist zwei Stunden gültig und nur einmal verwendbar.

    Zurück

    diff --git a/app/templates/admin_patches.html b/app/templates/admin_patches.html index 8cfe396..97680ed 100644 --- a/app/templates/admin_patches.html +++ b/app/templates/admin_patches.html @@ -15,7 +15,7 @@ -
    {{ user.display_name }}
    +
    {% include '_user_menu.html' %}

    🧵 Patch-Bilder

    Grafiken für die Patches auf der virtuellen Kutte verwalten.

    {% set admin_section = 'patches' %}{% include '_admin_nav.html' %} diff --git a/app/templates/admin_users.html b/app/templates/admin_users.html index 0b71314..35584f5 100644 --- a/app/templates/admin_users.html +++ b/app/templates/admin_users.html @@ -7,14 +7,16 @@ -
    {{ user.display_name }}
    +
    {% include '_user_menu.html' %}

    ⚙️ Verwaltung

    Benutzerkonten und Einladungen verwalten.

    {% set admin_section = 'users' %}{% include '_admin_nav.html' %} @@ -32,8 +34,12 @@
    {{ managed_user.display_name }}
    @{{ managed_user.username }} · {{ managed_user.email }} · seit {{ managed_user.created_at }}
    +
    +
    +
    +
    {% if managed_user.id != user.id %}
    {% endif %} {% endfor %} diff --git a/app/templates/admin_venues.html b/app/templates/admin_venues.html index cb3f5f2..f9af748 100644 --- a/app/templates/admin_venues.html +++ b/app/templates/admin_venues.html @@ -13,19 +13,37 @@ .venue-actions label { display: flex; align-items: center; gap: 6px; } .merge-form { display: grid; grid-template-columns: minmax(180px, 1fr) auto; gap: 8px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); } .delete-form { margin-top: 10px; text-align: right; } + .venue-card { padding: 0; overflow: hidden; } + .venue-summary { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 14px 16px; cursor: pointer; list-style: none; } + .venue-summary::-webkit-details-marker { display: none; } + .venue-summary::after { content: "▾"; color: var(--muted); transition: transform .15s ease; } + .venue-card[open] .venue-summary::after { transform: rotate(180deg); } + .venue-card[open] .venue-summary { border-bottom: 1px solid var(--border); background: var(--surface-hover); } + .venue-summary-title { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + .venue-summary-meta { display: block; margin-top: 3px; color: var(--muted); font-size: .83rem; } + .venue-verified { color: #86efac; } + .venue-unverified { color: #fca5a5; } + .venue-editor { padding: 16px; } @media (max-width: 900px) { .venue-fields { grid-template-columns: 1fr 1fr; } } @media (max-width: 560px) { .venue-fields, .merge-form { grid-template-columns: 1fr; } } -
    {{ user.display_name }}
    +
    {% include '_user_menu.html' %}

    📍 Veranstaltungsorte

    Orte korrigieren, bestätigen, zusammenführen oder entfernen.

    {% set admin_section = 'venues' %}{% include '_admin_nav.html' %}
    {% for venue in venues %} -
    +
    + + + {{ venue.name }}{% if venue.city %} · {{ venue.city }}{% endif %}{% if venue.country %} · {{ venue.country }}{% endif %} + {% if venue.is_verified %}✓ bestätigt{% else %}● unbestätigt{% endif %} · {{ venue.concert_count }} Veranstaltung(en) · ID {{ venue.id }} + + +
    @@ -50,7 +68,8 @@ -
    +
    + {% else %}

    Noch keine Veranstaltungsorte vorhanden.

    {% endfor %}
    diff --git a/app/templates/concert_detail.html b/app/templates/concert_detail.html index 1c1d0e5..773fc8a 100644 --- a/app/templates/concert_detail.html +++ b/app/templates/concert_detail.html @@ -17,28 +17,44 @@ href="/static/style.css" > + +
    - - ← Zurück zum Kalender - +
    + ← Zurück zum Kalender + {% include '_user_menu.html' %} +
    - {% if concert.flyer_path %} + {% if concert.flyer_url or concert.flyer_path %}
    Flyer {{ concert.artist }} + {% if concert.flyer_url %} +

    QuelleExtern eingebundener Flyer. Rechte liegen beim jeweiligen Veranstalter bzw. Rechteinhaber. Hinweise zur Entfernung bitte an die Administration.

    + {% endif %} +
    {% endif %} @@ -46,6 +62,8 @@
    + {{ concert.event_type_label }} +

    {{ concert.artist }}

    @@ -69,6 +87,11 @@ {{ concert.time }} Uhr + {% if concert.event_type == 'festival' and concert.end_date %} +
    + bis {{ concert.end_date }}{% if concert.end_time %}, {{ concert.end_time }} Uhr{% endif %} + {% endif %} +
    @@ -96,12 +119,19 @@ {% if concert.venue.postal_code - or concert.venue.city %} + or concert.venue.city + or (concert.venue.country + and concert.venue.country not in ('Deutschland', 'Germany')) %}
    {{ concert.venue.postal_code }} {{ concert.venue.city }} + {% if concert.venue.country + and concert.venue.country not in ('Deutschland', 'Germany') %} + {% if concert.venue.postal_code or concert.venue.city %} · {% endif %} + {{ concert.venue.country }} + {% endif %} {% endif %} @@ -136,13 +166,22 @@ + {% if concert.parent_event %} +

    + Gehört zu: + + {{ concert.parent_event.event_type_label }} · {{ concert.parent_event.title }} + +

    + {% endif %} + {% if concert.description %}

    - Über das Konzert + Über die Veranstaltung

    @@ -173,9 +212,9 @@ {% if can_edit %} -

    +
    - ✏️ Konzert bearbeiten + ✏️ Veranstaltung bearbeiten {% if user.is_admin and can_delete %} @@ -183,10 +222,10 @@
    @@ -234,7 +273,17 @@ type="submit" class="attendance-option {% if current_attendance == 'ticket_search' %}is-selected{% endif %}" > - 🎟️ Suche Ticket + 🔎 Suche Ticket + + + +
    + +
    @@ -245,6 +294,7 @@ {{ attending_count }} Zusage{% if attending_count != 1 %}n{% endif %} · {{ maybe_count }} Vielleicht · {{ ticket_seeker_count }} sucht Ticket + · {{ ticket_offer_count }} bietet Ticket
    @@ -278,7 +328,7 @@
    -

    🎟️ Sucht ein Ticket

    +

    🔎 Sucht ein Ticket

    {% if ticket_seekers %}
      @@ -291,6 +341,20 @@ {% endif %}
    +
    +

    🎟️ Bietet ein Ticket

    + + {% if ticket_offers %} + + {% else %} +

    Aktuell bietet niemand ein Ticket an.

    + {% endif %} +
    +
    diff --git a/app/templates/edit_concert.html b/app/templates/edit_concert.html index 40b463a..19108d8 100644 --- a/app/templates/edit_concert.html +++ b/app/templates/edit_concert.html @@ -10,17 +10,39 @@
    + {% include '_user_menu.html' %}
    -

    ✏️ Konzert bearbeiten

    -

    Änderungen werden direkt beim Konzert gespeichert.

    +

    ✏️ Veranstaltung bearbeiten

    +

    Änderungen werden direkt bei der Veranstaltung gespeichert.

    + {% if can_edit_details %} +

    + +

    +

    + +

    + {% endif %}

    -

    @@ -53,9 +75,9 @@

    -

    +

    @@ -73,14 +95,20 @@

    +

    + + Bitte möglichst die offizielle Quelle verwenden. Ein externer Link wird gegenüber einem Upload bevorzugt und unter dem Bild genannt. Feld leeren, um wieder den Upload zu verwenden. +

    Ohne neue Datei bleibt der bisherige Flyer erhalten.

    - {% if concert.flyer_path %} -

    Aktueller Flyer

    + {% if concert.flyer_url or concert.flyer_path %} +

    Aktueller Flyer

    {% endif %} {% endif %}
    @@ -90,5 +118,26 @@
    +{% if can_edit_details %} + +{% endif %} diff --git a/app/templates/index.html b/app/templates/index.html index de5e403..b9db149 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -78,6 +78,33 @@ gap: 15px; } + .event-group { display: grid; gap: 8px; } + + .linked-events { + display: grid; + gap: 7px; + margin-left: 30px; + } + + .concert-card.linked-event { + padding: 14px 18px; + border-left: 3px solid #a78bfa; + background: #121720; + } + + .linked-event .concert-artist { font-size: 1.05rem; margin-bottom: 5px; } + .linked-event .concert-meta { font-size: .9rem; } + + .event-category { + display: inline-block; + margin-bottom: 7px; + color: #aab4c3; + font-size: .78rem; + font-weight: 700; + letter-spacing: .04em; + text-transform: uppercase; + } + .past-concerts-title { margin: 28px 0 0; } @@ -127,6 +154,33 @@ color: #8b949e; } + .search-panel { margin-bottom: 26px; padding: 16px; background: rgba(16,16,16,.92); border: 1px solid #3a3030; border-radius: 14px; } + .search-form { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; } + .search-form input { margin: 0; } + .search-results-title { margin: 24px 0 12px; font-size: 1.15rem; } + .user-results { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; margin-bottom: 24px; } + .user-result { display: flex; align-items: center; gap: 11px; padding: 12px; background: #101010; border: 1px solid #3a3030; border-radius: 11px; } + .user-result:hover { border-color: #dc2626; } + .user-result-avatar { width: 44px; height: 44px; flex: 0 0 44px; object-fit: cover; border-radius: 50%; background: #292524; display: grid; place-items: center; font-weight: 800; } + .user-result-name { min-width: 0; } + .user-result-name strong, .user-result-name span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + .user-result-name span { color: #a8a29e; font-size: .86rem; } + + body { + background: radial-gradient(circle at 50% -20%, #3a0909 0, transparent 34rem), #050505; + min-height: 100vh; + } + + .page-header { padding-bottom: 22px; border-bottom: 1px solid #3f2424; } + .page-header h1 { font-family: Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif; letter-spacing: .05em; text-transform: uppercase; text-shadow: 0 2px 18px rgba(185, 28, 28, .45); } + .new-concert-button { background: #991b1b; border: 1px solid #dc2626; } + .new-concert-button:hover { background: #b91c1c; } + .admin-button:hover { border-color: #dc2626; } + .concert-card { background: linear-gradient(145deg, #101010, #181313); border-color: #3a3030; } + .concert-card:hover { border-color: #dc2626; background: #1c1212; } + .concert-date { color: #ef4444; } + .concert-card.linked-event { border-left-color: #dc2626; background: #0d0d0d; } + @media (max-width: 600px) { .page-header { @@ -139,12 +193,31 @@ text-align: center; } + .linked-events { margin-left: 16px; } + .search-form { grid-template-columns: 1fr; } + } +{% macro event_card(concert, linked=false) %} + + {{ concert.event_type_label }} +
    + {% if concert.event_type == 'festival' %}🎪{% elif concert.event_type == 'other' %}🥂{% else %}🎸{% endif %} + {{ concert.artist }} +
    +
    +
    + 📅 {{ concert.date }}{% if concert.end_date %} – {{ concert.end_date }}{% else %} um {{ concert.time }} Uhr{% endif %} +
    +
    📍 {{ concert.venue }}
    +
    +
    +{% endmacro %} + @@ -155,11 +228,11 @@

    - 🐧 Pingu Concerts + {% if archive %}☠ Vergangene Veranstaltungen{% else %}🐧 Pingu Concerts{% endif %}

    - Unser Konzertkalender + {% if archive %}Das Archiv vergangener Nächte{% else %}Konzerte, Festivals und alles davor{% endif %}
    @@ -167,8 +240,8 @@
    - - 👤 Mein Profil + + {% if archive %}⚡ Bevorstehend{% else %}☠ Vergangene{% endif %} {% if user.is_admin %} @@ -183,79 +256,69 @@ href="/concerts/new" class="new-concert-button" > - + Konzert hinzufügen + + Veranstaltung hinzufügen + {% include '_user_menu.html' %} +
    +
    +
    + + +
    +
    + + {% if search_query %} +

    User zu „{{ search_query }}“

    + {% if user_results %} + + {% else %}

    Keine passenden User gefunden.

    {% endif %} +

    Veranstaltungen zu „{{ search_query }}“

    + {% endif %} + {% if upcoming_concerts or past_concerts %}
    {% for concert in upcoming_concerts %} - - - -
    - 🎸 {{ concert.artist }} -
    - - -
    - - {% endfor %} - {% if past_concerts %} + {% if archive and past_concerts %}

    - Vergangene Konzerte + Archiv

    {% for concert in past_concerts %} - - - -
    - 🎸 {{ concert.artist }} -
    - -
    - - {% endfor %} @@ -268,11 +331,11 @@

    - Noch keine Konzerte 🎸 + {% if archive %}Noch keine vergangenen Veranstaltungen ☠{% else %}Noch keine Veranstaltungen 🎸{% endif %}

    - Leg das erste Konzert an! + {% if archive %}Hier erscheinen abgeschlossene Veranstaltungen.{% else %}Leg die erste Veranstaltung an!{% endif %}

    diff --git a/app/templates/login.html b/app/templates/login.html index 0b8e3f7..560a1d1 100644 --- a/app/templates/login.html +++ b/app/templates/login.html @@ -32,6 +32,7 @@

    +

    Passwort vergessen? Bitte einen Admin um einen zeitlich begrenzten Reset-Link.

    Abbrechen
    diff --git a/app/templates/messages.html b/app/templates/messages.html new file mode 100644 index 0000000..48cdb05 --- /dev/null +++ b/app/templates/messages.html @@ -0,0 +1,60 @@ + + + + + + Nachrichten · Pingu Concerts + + + + +
    {% include '_user_menu.html' %}
    +
    + {% if partner %} +
    + {% if partner.avatar_path %}{% else %}{{ partner.display_name[:1] }}{% endif %} +

    {{ partner.display_name }}

    @{{ partner.username }}
    +
    +
    + {% for message in messages %}
    {{ message.body }}{{ message.created_at }}
    + {% else %}

    Noch keine Nachrichten. Schreib die erste!

    {% endfor %} +
    +
    + + +
    +

    ← Alle Nachrichten

    + {% else %} +

    🤘 Nachrichten

    Private Chats mit deinen Freunden.

    + + {% endif %} +
    + + diff --git a/app/templates/new_concert.html b/app/templates/new_concert.html index dcb20e4..42dcc83 100644 --- a/app/templates/new_concert.html +++ b/app/templates/new_concert.html @@ -10,7 +10,7 @@ content="width=device-width, initial-scale=1.0" > - Konzert hinzufügen · Pingu Concerts + Veranstaltung hinzufügen · Pingu Concerts Concerts + {% include '_user_menu.html' %} + @@ -87,7 +89,7 @@
    -

    🎤 Konzert hinzufügen

    +

    🎤 Veranstaltung hinzufügen

    Trag ein, worauf wir uns freuen. @@ -104,6 +106,26 @@ enctype="multipart/form-data" > +

    +
    + +

    + + + @@ -111,7 +133,7 @@

    + + @@ -221,7 +249,7 @@ @@ -277,9 +305,13 @@
    + + +
    Bitte möglichst den offiziellen Flyer des Veranstalters oder der Band verlinken. Das Bild wird nicht auf Pingu Concerts kopiert; der Link wird als Quelle ausgewiesen.
    + @@ -294,7 +326,7 @@
    - JPG, PNG oder WEBP · maximal 10 MB + Alternative, falls kein offizieller externer Link verfügbar ist: JPG, PNG oder WEBP · maximal 10 MB. Ist ein Link angegeben, wird er bevorzugt dargestellt.
    @@ -330,7 +362,7 @@ type="submit" class="button" > - 💾 Konzert speichern + 💾 Veranstaltung speichern @@ -352,6 +384,25 @@ diff --git a/app/templates/register.html b/app/templates/register.html index 47274cf..0f025fc 100644 --- a/app/templates/register.html +++ b/app/templates/register.html @@ -75,6 +75,8 @@ type="password" name="password" required + minlength="10" + autocomplete="new-password" >