{# The stylesheet is embedded (reports/html._read_report_css): the report is one file. #} {% if poster_css %}{% endif %} {#- Every row and file carries data-outcome / data-reason / data-flags / data-item-id, and the same facts sit in the #report-data JSON island, for scripted reviews. -#} {% set deleting = ["removed", "would_remove", "failed"] %} {% set pill_text = {"removed": "Removed", "would_remove": "Would remove", "failed": "Failed", "blocked": "Blocked", "would_block": "Would block", "other": "Unknown"} %} {% set out_titles = {"other": "Unknown status", "failed": "Failed", "removed": "Removed", "would_remove": "Would be removed", "blocked": "Blocked by the safety guard", "would_block": "Would be blocked by the safety guard"} %} {% set out_css = {"other": "seg-other", "failed": "seg-failed", "removed": "seg-removed", "would_remove": "seg-would", "blocked": "seg-blocked", "would_block": "seg-blocked"} %} {% macro ids(list) -%} {% for pid in list %}{{ pid }}{% if not loop.last %},{% endif %}{% endfor %} {%- endmacro %} {% macro path(side) -%} {% if side.dir %}{{ side.dir }}/{% endif %}{{ side.base or side.path or "unknown" }} {%- endmacro %} {% macro cell(f, side, role, name, r) -%} {{ side.short }}{% if role == "other" and not f.episode %}{% if f.status_text and r.per_file_status %}{{ f.status_text }}{% endif %}{% if r.per_file_reason and f.reason %}{{ f.reason }}{% endif %}{% endif %}{% for k, v in side.vary.items() %}{{ v }}{% endfor %}{% if role == "other" and side.image_class and side.image_class != f.keep.image_class %}{% endif %} {{ side.runtime or "—" }} {{ side.size_text }} {{ side.score_text or "—" }} {%- endmacro %} {% macro row(r, name) -%}
{% if r.image_class %}{% else %}{% endif %} {{ r.name }}{{ r.sub }} · {{ r.size_text }}{% if r.blocked_runs > 1 %} · blocked in {{ r.blocked_runs }} runs{% endif %} {{ pill_text[name] }} {% for p in r.diff_parts %}{{ p.text }}{% if not loop.last %} · {% endif %}{% endfor %} {% if r.chips or r.file_only %} {% for c in r.chips %}{{ c.text }}{% endfor %} {% if r.file_only %}{{ r.file_only }} file only (SSH){% endif %} {% endif %}
{% if r.shared %}
{% for line in r.shared %}
{{ line.label }}
{% for p in line.parts %}{{ p.text }}{% if not loop.last %} · {% endif %}{% endfor %}
{% endfor %}
{% endif %}
{% if r.is_episode %}{% endif %} {% for f in r.files %} {% if r.is_episode %}{% endif %} {{ cell(f, f.keep, "keep", name, r) }} {{ cell(f, f.delete, "other", name, r) }} {% endfor %}
EpisodeKeptRuntimeSizeScore{{ "Removed" if name in deleting else "Other" }}RuntimeSizeScoreEmby
{{ f.episode or f.title }}{% if r.per_file_status %}{{ f.status_text }}{% endif %}{% if r.per_file_reason and f.reason %}{{ f.reason }}{% endif %}
{% set notes = r.files|map(attribute="keep_note")|reject("equalto", "")|unique|list %} {% for note in notes %}

Why this copy: {{ note }}.

{% endfor %} {% if r.exclude_ids and name in ["would_remove", "blocked", "would_block"] %}

{% if name == "would_remove" %}Don't want this removed? Add to --exclude-ids before --doit:{% else %}Keep both copies for good? Add to --exclude-ids:{% endif %} {{ ids(r.exclude_ids) }}{% if r.exclude_numeric %} (a bare number matches TMDB and TVDB alike; this title has no IMDb id){% endif %}

{% endif %}
{%- endmacro %}

Emby Curator · dedupe report

{{ run.mode_short }} · {{ run.generated_human }}{% if run.libraries %} · librar{{ "y" if run.libraries|length == 1 else "ies" }} {{ run.libraries|join(", ") }}{% endif %}

{{ run.mode }}

{{ run_summary.headline }}

{% if run_summary.subline %}

{{ run_summary.subline }}

{% endif %} {% if run_summary.warning %}

Warning: {{ run_summary.warning }}

{% endif %} {% if run_summary.has_files %} {% endif %} {% if run_summary.has_files %}
{% for t in run_summary.stats_tiles %}
{{ t.value }}
{{ t.label }}
{% endfor %}
{% endif %} {% if run_summary.decide %}
Next steps: copy-paste values
{% for a in run_summary.decide %}
{{ a.label }}
{{ a.command }}
{% endfor %}
{% endif %}
{# ---- Outcomes: one row per title and outcome (reports/clusters.build_clusters) ---- Risky deletions come first in their own section; rows never merge across season folders, guard reasons or risk flags. Opening a row shows every file's evidence. #}
{% if clusters.check %}

{{ "Check first" if run_summary.dry else "Removed, worth a second look" }} · {{ clusters.check_files }} file{{ "" if clusters.check_files == 1 else "s" }} · {{ clusters.check|length }} row{{ "" if clusters.check|length == 1 else "s" }}

{% if run_summary.dry %}One signal says the wrong copy may go. Open the row and verify on disk before --doit.{% else %}Already removed. One signal says the wrong copy may have gone: open the row and verify the kept copy on disk.{% endif %}

{% for r in clusters.check %}{{ row(r, r.outcome) }}{% endfor %}
{% endif %} {% for name in ["other", "failed", "removed", "would_remove", "blocked", "would_block"] %} {% set rows = clusters.sections[name]|rejectattr("risk")|list %} {% set risky_here = clusters.sections[name]|selectattr("risk")|list|length %} {% if clusters.totals[name] or (name == "failed" and not run_summary.dry) %}

{{ out_titles[name] }} · {{ clusters.totals[name] }} file{{ "" if clusters.totals[name] == 1 else "s" }}{% if clusters.sizes[name] and name in deleting %} · {{ run_summary.sizes_text[name] }}{% endif %}{% if risky_here %} · {{ risky_here }} row{{ "" if risky_here == 1 else "s" }} {{ "in Check first" if run_summary.dry else "above, worth a second look" }}{% endif %}

{% if not clusters.totals[name] %}

Nothing failed.

{% endif %} {% if name in ["blocked", "would_block"] and rows %}

Both copies stay. Protective, not an error: fix the files, or add the pair ids to --exclude-ids to stop seeing a pair.

{% endif %} {% for r in rows %}{{ row(r, name) }}{% endfor %}
{% endif %} {% endfor %} {# One line per duplicate group an excluded ID actually skipped this run, folded; ids that matched nothing are counted, not listed one by one. #}

Skipped by --exclude-ids · {{ excluded_groups_count }} group{{ "" if excluded_groups_count == 1 else "s" }}

{% if not has_excluded_ids %}

No ids excluded.

{% endif %} {% if excluded_titles %}
ShowHide the {{ excluded_titles|length }} skipped group{{ "" if excluded_titles|length == 1 else "s" }}
    {% for id, item in excluded_titles.items() %}
  • {% if item.image_class %}{% else %}{% endif %}{{ item.title }}{% if item.year %} ({{ item.year }}){% endif %} · {{ id }}{% if id.startswith('tt') %} · IMDb{% elif id.isdigit() %} · TMDB{% endif %}
  • {% endfor %}
{% endif %} {% if has_excluded_ids %}
ShowHide all {{ excluded_ids|length }} configured id{{ "" if excluded_ids|length == 1 else "s" }} {{ ids(excluded_ids) }}
{% endif %}