{% macro search_form(q='') %}
{% for key, value in query_pairs|default([]) %}{% endfor %}
{% endmacro %} {% macro grid(hits, csrf=none, q="", topic_id=none) %}
{% for hit in hits %}{% set image = hit.image %}{% set occurrence = hit.occurrence %}{% set origin_source = occurrence.source if occurrence else image.source %}{% set origin_page = occurrence.page if occurrence else image.page %}
{{ occurrence.alt_text if occurrence and occurrence.alt_text else image.alt_text or origin_page.title or 'Indexiertes Bild' }}
{{ origin_source.domain }}{% if hit.score is not none %}Rang {{ '%.3f'|format(hit.score) }}{% endif %}
{{ occurrence.alt_text if occurrence and occurrence.alt_text else image.alt_text or origin_page.title or 'Ohne Titel' }}

{{ image.width }} × {{ image.height }}{% if hit.version_count > 1 %} · {{ hit.version_count }} Versionen{% endif %}{% if hit.occurrence_count > 1 %} · {{ hit.occurrence_count }} Fundstellen{% endif %}

Mehr davon → {% if compare_to and image.id != compare_to %}Diese beiden Bilder vergleichen →{% endif %} {% if occurrence and not occurrence.available %}

Diese Fundstelle war zuletzt nicht erreichbar.

{% elif not image.original_available %}

Die ursprüngliche Bilddatei war zuletzt nicht erreichbar; Vorschau bleibt erhalten.

{% endif %} {% if hit.components %}
Warum dieser Treffer?

Rang ist die gewichtete Kombination der folgenden Beiträge, keine Wahrscheinlichkeit. Die Mindestähnlichkeit filtert ausschließlich die Bildähnlichkeit.

{% for name, value in hit.components.items() %}
{{ {'image_similarity':'Bildähnlichkeit','text_similarity':'Kontextähnlichkeit','topic_score':'Themenrelevanz','source_quality':'Qualität der primären Quelle','user_feedback_score':'Nutzerfeedback','availability':'Bildverfügbarkeit'}.get(name, name) }}
{{ 'Kein Thema gewählt' if name == 'topic_score' and not hit.topic_applied else '%.3f'|format(value) }} · Gewicht {{ '%.1f'|format(hit.weights[name]*100) }} % · Rangbeitrag {{ '%.3f'|format(hit.contributions[name]) }}
{% endfor %}
{% endif %} {% if csrf %}{% include 'partials/feedback.html' %}{% endif %}
{% endfor %}
{% endmacro %} {% macro jobs_table(jobs, empty_message="Keine Seitenjobs in dieser Auswahl.") %} {% if jobs %}

Weitere Spalten durch seitliches Scrollen.

{% for job in jobs %}{% set shown_url = current_request_url(job.source, job.url) if job.status in ["pending", "running"] else job.url %}{% endfor %}
Seitenjobs
SeiteStatusBilderVersuchZuletzt gestartet
{% if job.status not in ["pending", "running"] %}Historischer Auftrag · {{ timestamp(job.completed_at) }}
{% endif %}{{ shown_url }}{% if job.error %}
Protokoll

{{ state_label(job.error_type) }}

Aufgabe und Wiederholungszustand →
{{ job.error }}
{% endif %}
{{ status_badge(job.status) }}{{ job.images_indexed }} / {{ job.images_found }}{{ job.attempts }}{{ timestamp(job.started_at, 'noch nicht gestartet') }}
{% else %}
{{ empty_message }} Quellen öffnen →
{% endif %} {% endmacro %} {% macro crawl_fields(source=none) %}

Forum: Übersicht → Threads → Threadseiten. Bilderportal: Übersicht → Galerie → Bildseiten. Shop: Kategorie → Produkte. „Automatisch“ erkennt bekannte Strukturen; unbekannte Seiten werden allgemein erfasst.

{{ scope_description(source.crawl_scope if source else 'domain', source.start_url if source else '') }}

Für Galerien in verschiedenen Bereichen derselben Website wähle „Gesamte Domain“. „URL-Pfad“ bei einer Startseite wie /index erfasst keine Galerie unter /galerie. Normale Galerie-Links und Sitemaps ergänzen automatisch das gespeicherte Seitenverzeichnis; Bilder werden währenddessen verarbeitet. JavaScript-Klicks werden nicht ausgeführt.

Crawl-Verhalten

Die Erfassung läuft ohne Limits für Dauer, Anfragen, Datenmenge, Seiten, Bilder oder Tiefe. Offene URLs bleiben bei Pausen und Neustarts gespeichert. Bekannte Seiten werden im eingestellten Intervall erneut geprüft.

{% endmacro %}