Plugin neuheiten: Web-Quellen-Crawler (4 Adapter, Rate-Limit, Dedup-Gate, Sync-UI)
This commit is contained in:
@@ -23,8 +23,12 @@
|
||||
<tr class="hover:bg-slate-50">
|
||||
<td class="px-4 py-3 font-medium">
|
||||
{{ eintrag.titel }}
|
||||
{% if eintrag.bgg_id %}
|
||||
<a href="https://boardgamegeek.com/boardgame/{{ eintrag.bgg_id }}" target="_blank" rel="noopener"
|
||||
class="ml-1 text-[10px] text-slate-400 hover:text-emerald-700 align-super">BGG {{ eintrag.bgg_id }}</a>
|
||||
{% elif eintrag.quelle and eintrag.quelle != 'boardgamegeek' %}
|
||||
<span class="ml-1 text-[10px] uppercase tracking-wide text-sky-600/70 align-super">{{ eintrag.quelle }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-4 py-3">{{ eintrag.verlag or '—' }}</td>
|
||||
<td class="px-4 py-3">{{ eintrag.autor or '—' }}</td>
|
||||
|
||||
@@ -41,6 +41,68 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-6 bg-white rounded-xl border border-slate-200 shadow-sm p-4">
|
||||
<div class="flex flex-wrap items-center gap-2 mb-3">
|
||||
<h2 class="text-sm font-semibold uppercase tracking-wide text-slate-500 mr-auto">Web-Quellen</h2>
|
||||
{% if ist_redaktion %}
|
||||
<form method="post" action="/neuheiten/quellen-sync">
|
||||
<button type="submit"
|
||||
class="bg-sky-600 hover:bg-sky-700 text-white font-medium px-3 py-1.5 rounded-lg text-xs whitespace-nowrap">
|
||||
↻ Web-Quellen synchronisieren
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-xs">
|
||||
<thead class="text-left text-slate-400">
|
||||
<tr>
|
||||
<th class="px-2 py-1.5 font-medium">Quelle</th>
|
||||
<th class="px-2 py-1.5 font-medium">Status</th>
|
||||
<th class="px-2 py-1.5 font-medium">Letzter Lauf</th>
|
||||
<th class="px-2 py-1.5 font-medium text-right">Neu</th>
|
||||
<th class="px-2 py-1.5 font-medium text-right">Aktualisiert</th>
|
||||
<th class="px-2 py-1.5 font-medium text-right">Gefiltert</th>
|
||||
<th class="px-2 py-1.5 font-medium">Hinweis</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100">
|
||||
{% for quelle in quellen_zeilen %}
|
||||
<tr>
|
||||
<td class="px-2 py-1.5">
|
||||
<a href="{{ quelle.url }}" target="_blank" rel="noopener noreferrer"
|
||||
class="font-medium text-slate-700 hover:text-emerald-700">{{ quelle.anzeigename }}</a>
|
||||
<span class="ml-1 text-[10px] text-slate-300">{{ quelle.name }}</span>
|
||||
</td>
|
||||
<td class="px-2 py-1.5">
|
||||
{% if quelle.aktiv %}<span class="inline-block px-2 py-0.5 rounded-full bg-emerald-50 text-emerald-700">an</span>
|
||||
{% else %}<span class="inline-block px-2 py-0.5 rounded-full bg-slate-100 text-slate-400">aus</span>{% endif %}
|
||||
</td>
|
||||
<td class="px-2 py-1.5 whitespace-nowrap text-slate-500">
|
||||
{{ quelle.letzte_laufzeit.strftime('%d.%m.%Y %H:%M') if quelle.letzte_laufzeit else '—' }}
|
||||
{% if quelle.dauer_sekunden %}<span class="text-slate-300">({{ '%.1f' | format(quelle.dauer_sekunden) }} s)</span>{% endif %}
|
||||
</td>
|
||||
<td class="px-2 py-1.5 text-right">{{ quelle.neu }}</td>
|
||||
<td class="px-2 py-1.5 text-right">{{ quelle.aktualisiert }}</td>
|
||||
<td class="px-2 py-1.5 text-right">{{ quelle.gefiltert }}</td>
|
||||
<td class="px-2 py-1.5">
|
||||
{% if quelle.fehlermeldung %}<span class="text-red-600">{{ quelle.fehlermeldung }}</span>
|
||||
{% elif quelle.unveraendert %}<span class="text-slate-400">unverändert (304) — übersprungen</span>
|
||||
{% elif not quelle.aktiv %}<span class="text-slate-300">abgeschaltet</span>
|
||||
{% else %}—{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="mt-2 text-[11px] text-slate-400">
|
||||
Quellen-Sync:
|
||||
{% if quellen_sync_aktiv %}<span class="text-emerald-700 font-medium">täglich aktiv</span>{% else %}<span class="text-slate-500">ausgeschaltet</span>{% endif %}
|
||||
· max. 1 Anfrage/Sekunde je Quelle · Duplikate gegen BGG werden per Titel-Match gefiltert
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form method="get" action="/neuheiten"
|
||||
hx-get="/neuheiten" hx-target="#neuheiten-liste" hx-swap="outerHTML"
|
||||
hx-trigger="input changed delay:300ms from:find input[name='q'], change from:find select[name='status']"
|
||||
|
||||
Reference in New Issue
Block a user