From ca6d94938c4a26aadfc429c5516e331912699378 Mon Sep 17 00:00:00 2001 From: Flo Hartmann Date: Tue, 25 Aug 2026 12:11:06 +0000 Subject: [PATCH] BGG: Powered-by-Logo im Footer (Lizenzpflicht) + Erscheinungsjahr-Filter (Standard aktuelles Jahr+) --- .env | 1 + plugins/neuheiten/__init__.py | 24 +++++++++++++++++ .../neuheiten/templates/neuheiten/index.html | 9 ++++++- src/redaktionskern/app.py | 5 ++++ src/redaktionskern/static/powered-by-bgg.png | Bin 0 -> 1741 bytes src/redaktionskern/templates/base.html | 6 +++++ tests/test_covers.py | 3 ++- tests/test_neuheiten_ui.py | 25 ++++++++++++++++-- 8 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/redaktionskern/static/powered-by-bgg.png diff --git a/.env b/.env index 3502fb9..748a898 100644 --- a/.env +++ b/.env @@ -1,2 +1,3 @@ SPIELE_SESSION_SECRET=48ebf7ddae261a931652b5a55cff708aa21cf4936a8bdeb287eeac7cec4ee3e2 SPIELE_INITIAL_ADMIN_PASSWORD=3fb93f84014ff45406b36ec3 +SPIELE_BGG_TOKEN=6fa6f9f6-32fd-443d-a5c3-ac2527f6a6fc diff --git a/plugins/neuheiten/__init__.py b/plugins/neuheiten/__init__.py index 6c7e8df..14c4f4e 100644 --- a/plugins/neuheiten/__init__.py +++ b/plugins/neuheiten/__init__.py @@ -94,6 +94,7 @@ class NeuheitenPlugin(BasePlugin): user: User = Depends(require_user), q: str = "", status: str = "", + jahr: int | None = None, sort: str = STANDARD_SORTIERUNG[0], richtung: str = STANDARD_SORTIERUNG[1], meldung: str = "", @@ -118,6 +119,26 @@ class NeuheitenPlugin(BasePlugin): ) if status.strip(): abfrage = abfrage.where(Neuheit.status == status.strip()) + # Erscheinungsjahr-Filter: Standard „aktuelles Jahr und neuer“. + jahr_standard = datetime.now(timezone.utc).year + if jahr is None: + jahr_filter = jahr_standard + abfrage = abfrage.where( + or_( + Neuheit.erscheinungsjahr >= jahr_standard, + Neuheit.erscheinungsjahr.is_(None), # ohne Jahr nicht wegfiltern + ) + ) + else: + jahr_filter = jahr + abfrage = abfrage.where(Neuheit.erscheinungsjahr >= jahr) + jahr_optionen = [ + j for j in db.scalars( + select(Neuheit.erscheinungsjahr).distinct().order_by( + Neuheit.erscheinungsjahr.desc() + ) + ) if j is not None + ] gesamt = db.scalar(select(func.count()).select_from(abfrage.subquery())) or 0 eintraege = db.scalars( abfrage.order_by(spalte_sortiert, Neuheit.id.asc()) @@ -138,6 +159,9 @@ class NeuheitenPlugin(BasePlugin): "eintraege": eintraege, "q": q, "status_filter": status, + "jahr_filter": jahr_filter, + "jahr_standard": jahr_standard, + "jahr_optionen": jahr_optionen, "sort": sort if sort in SORTIERBAR else STANDARD_SORTIERUNG[0], "richtung": "ab" if abwaerts else "auf", "status_optionen": status_optionen, diff --git a/plugins/neuheiten/templates/neuheiten/index.html b/plugins/neuheiten/templates/neuheiten/index.html index 749cd52..261e29f 100644 --- a/plugins/neuheiten/templates/neuheiten/index.html +++ b/plugins/neuheiten/templates/neuheiten/index.html @@ -121,7 +121,7 @@
@@ -131,6 +131,13 @@ {% endfor %} + diff --git a/src/redaktionskern/app.py b/src/redaktionskern/app.py index 810d06a..dae878b 100644 --- a/src/redaktionskern/app.py +++ b/src/redaktionskern/app.py @@ -16,6 +16,7 @@ from pathlib import Path from fastapi import FastAPI, Request from fastapi.responses import RedirectResponse +from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from jinja2 import ChoiceLoader, Environment, FileSystemLoader, select_autoescape from sqlalchemy import func, select @@ -109,6 +110,10 @@ def create_app(settings: Settings | None = None) -> FastAPI: redoc_url=None, openapi_url=None, ) + # Statische Kern-Dateien (z. B. „Powered by BGG“-Logo, Pflicht für + # öffentliche BGG-XML-API-Anwendungen). + statisch = Path(__file__).parent / "static" + app.mount("/static", StaticFiles(directory=statisch), name="statisch") app.state.settings = settings app.state.engine = engine app.state.session_factory = session_factory diff --git a/src/redaktionskern/static/powered-by-bgg.png b/src/redaktionskern/static/powered-by-bgg.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa7e30fd5532cf07e33cabe649e427ad2a68e10 GIT binary patch literal 1741 zcmV;;1~U1HP)l0001NP)t-sM{rDK zJWV}0Up_fsK004MIbU!-OKLDnK004LI$=FIUp+Zq{7?WrIbJPyj(aWdBwJ|Nj2`L;yuWYW}#E{+w|AenS7)$N%x` zm@b_}0000PbW%=J00+^-^WhN!{u*yE_(WNev7xnpDNWsMhyu$22><{E_en%SRA}Dq zTI-IZIt)%A#DqIcFGH9z-P!kl$F-dVLOWfJj?RyzYNS@VInL)hv_ibvtG(K*Jy(M# zfdS8f0%1t`3@F6mebBqs3SVBIhiZD?v6ncLIwFc`JndE?!K6-zqS~)Q9E$TW5{z*i ztHT}@;vB=76rmWaX%G^2X;MdLQloFvVV4Q~a7Gjnj1d*0kB41(32aQtp+M6baBf#X zK%6%wHIA3-L|~?=()$APK1C=H$LHt8x%&xrrjZSh%k^XO-Qgx8aEk{^q}X(~i#J4W z>t_C81d6sqv^RqY$Z^`@a0=l74Bv(Z_}}V%_}Lct2@QzD7RPUoYm?f+_$F!2_qChH z8d)0y+~=-q5s?<#fs7CP{#G&R!qDi5yI+cfRu$t23PB*}zz2j;z9j}^@B3LJWTsRj zbfz*R8l^fRQoq>YWdc!FMkl-psKa56hzw1vmbdQCYMg4rsKq4RM+a?zz{%@iy8Qb1 z`1o}RLHM`=scoKHOJB7pLw{}sB-S>f!9ginYYRkXY0=KTh&C2D$aA-V{eliMG);24FfmCI?Bl&fO1JOv@})?uGAK%1 zOtCc)5n^R3nom(Xt<6=MDn1R7lm#^{n!-R)NSZ=Y)wiu;9?XzwYlsKm0I3!nt3t*# zjR46olYG3PzS2S~zF&txK#`_QZc`w^Bc_0!6a3j=QYMb*E zk>b{jc{IFn6{(UB%0-_@rjHGf=_FSmXf}z2H@+EuCjkC_c&CQ7-89y|Iq8*JYY8lP z+{iP6s50#rP>sF2EIUOz7bcx+P)e3I3H(yQ!YYLq2oV!%I@AsBkc33?NkG1WKBi%@ zUm(GEeCsrP`}>h&v@@9*Ub|%JzHJ zzdY-@6qPJJDuZDq(crlA;5O#TC6P?O2}y`rRL3uyP=;Muk|ep`3vXs9AloLk%WR+6 zOtQdoXDAXk=2@C%2mttM?4+d=bRnE@=++6%w(=QTQ6q;f?*A+l0?S z?mW125j~8NvoFR~RUv92GmJ&ll%+tG<2Rd%GiDs4Kr@95B>OQ&f`kR{0$4t$d|O^f zQ8|XKk^){!mL;>iuJN#%w-+=;{F1ICPRrb@YV> z$hBN2*>4%fLt%zjOb)�m;+ zM3I4UaK&hZ;!><@Ngja)lonp_j0|L;;#5#@BFa2OFq}pVA;d%ifnQq`NZY$qnlZy7 z9yE{A$l@dc$9M|WrjsE^E+pzGUrQEy%Q4LQVIFcYS)FkvxKP=-b^(liCy{Gn4_3V7 zU)+mZd_)gb#b$5=1lH=86>`0+wNQpjv_m6F*0Kwz%u;CAC5}m^WhjKm!m(1)qIN4y zSU`&j)lz3RrB--(;P|aP7KWYN4sO$kJjEr-^_$GjCGA2GYF7wls;^IJw_K}aPqfy@ z3zc5$;|IlWR6>jOP~I-%l?RWA6tor`4`0y1UGKj>j=;|zM>f_6j~`1`cgL8u>LaQd zo%ZjZ-C%Pf+&$QB?8Q~-o9D*AL-dvX-TuE2hw>K{65;s%`S2fqKj++iTB;Matm6)W z$W!$8B*b31zgNG`-KT2=BYMu=6%cawX@jHM<&Pum?o~j7%9&2*UH&){z1t!b)o_&i z{E^4IJDJop4(Ef|?QiTpyQ4|HAJ&>@mp~4|q;`zLyZdm~V*mel0DjQ`Pw}^n=Rol^ je+7EAS9`Tr`{&yqHNB-T;qzko00000NkvXXu0mjfw{I=n literal 0 HcmV?d00001 diff --git a/src/redaktionskern/templates/base.html b/src/redaktionskern/templates/base.html index e2849c3..f806e3a 100644 --- a/src/redaktionskern/templates/base.html +++ b/src/redaktionskern/templates/base.html @@ -73,6 +73,12 @@
{{ app_name }} · Plugin-Anzahl: {{ geladene_plugins|length }} +
+ + Powered by BoardGameGeek + +
diff --git a/tests/test_covers.py b/tests/test_covers.py index 887abf2..1d0e391 100644 --- a/tests/test_covers.py +++ b/tests/test_covers.py @@ -435,7 +435,8 @@ def test_neuheitenliste_rendert_platzhalter_ohne_bild(app, client): melde_an(client) antwort = client.get("/neuheiten") assert antwort.status_code == 200 - assert "")[0] + assert "Alt<" not in antwort.text + + def test_unbekannte_sortierung_faellt_auf_standard_zurueck(client): melde_an(client) antwort = client.get("/neuheiten?sort=hack&richtung=auf")