Library Cleanup Report

Dynamic rating decay model — {% if series_candidates is defined and series_candidates %}movies & series{% else %}movies{% endif %} nobody watches, filtered through {{ protection_stats.total_analyzed | default(0) - protection_stats.final_candidates | default(0) }} protection checks

Summary

Analysis

{{ protection_stats.total_analyzed }}
Movies Analyzed
{{ protection_stats.final_candidates }}
Cleanup Candidates
{{ total_size_human }}
Space to Free

Protection Layers

{{ protection_stats.age_filtered }}
Too Recent
{{ protection_stats.play_protected }}
Someone Watched
{{ protection_stats.rating_protected }}
Good Rating

Config

{{ config.min_age_years }}yr
Min Age
{{ config.base_rating }}→{{ config.max_rating }}
Rating Range
{{ protection_stats.actor_protected }}
Actors Protected
{% if series_stats is defined and series_stats %}

Series Analysis

{{ series_stats.total_analyzed }}
Series Analyzed
{{ series_stats.final_candidates }}
Series Candidates
{{ series_total_size_human }}
Series Space to Free
{% endif %}

Filter Funnel {{ protection_stats.total_analyzed }} in → {{ protection_stats.final_candidates }} out

{{ protection_stats.age_filtered }}
Too recent (< {{ config.min_age_years }}yr)
{{ protection_stats.excluded_filtered }}
Excluded by ID
{{ protection_stats.play_protected }}
Played by someone
{{ protection_stats.interest_protected }}
Favorited / started
{{ protection_stats.actor_protected }}
Favorite actor
{{ protection_stats.franchise_protected }}
Franchise
{{ protection_stats.path_protected }}
Protected path
{{ protection_stats.rating_protected }}
Rating high enough
{% if series_stats is defined and series_stats %}

Series Filter Funnel {{ series_stats.total_analyzed }} in → {{ series_stats.final_candidates }} out

{{ series_stats.stale_filtered }}
Too recent (stale < {{ config.min_age_years }}yr)
{{ series_stats.excluded_filtered }}
Excluded by ID
{{ series_stats.play_protected }}
Someone watched
{{ series_stats.favorite_protected }}
Favorited
{{ series_stats.path_protected }}
Protected path
{{ series_stats.rating_protected }}
Rating high enough
{% endif %}

Rating Decay Rules

Age on ServerMin Required RatingNote
{{ config.min_age_years }} yr{{ config.base_rating }}base threshold
{{ config.min_age_years + 1 }} yr{{ "%.1f" | format(config.base_rating + config.decay_step) }}+{{ config.decay_step }} per year
{{ config.min_age_years + 2 }} yr{{ "%.1f" | format(config.base_rating + config.decay_step * 2) }}
{{ config.min_age_years + 3 }} yr{{ "%.1f" | format([config.base_rating + config.decay_step * 3, config.max_rating] | min) }}
{{ config.min_age_years + 4 }} yr+{{ config.max_rating }}cap

Cleanup Candidates {{ candidates | length }} movies · {{ total_size_human }}

{% if not candidates %}

No cleanup candidates found — your library is clean!

{% endif %}
{% for c in candidates %}
{{ loop.index }}
{% if c.image_url %} {{ c.name }} {% else %}
No poster
{% endif %}
{% if c.year %}
{{ c.year }}
{% endif %}
{% if c.rating is none or c.rating_str == "unrated" %} ★ Unrated {% else %} ★ {{ c.rating_str }} {% endif %} {% if c.critic_rating_str %} 🍕 {{ c.critic_rating_str }} {% endif %} Required: {{ c.threshold_str }} {{ c.age_years }} yr on server {{ c.size_human }} {{ c.library }} {% if doit and c.deletion_result %} {% if c.deletion_result.status == "success" %} ✓ Deleted {% elif c.deletion_result.status == "failed" %} ✗ Failed {% else %} Skipped {% endif %} {% elif not doit %} Dry-run {% endif %}
{{ c.path }}
{% endfor %} {% if series_candidates is defined and series_candidates %}

Series Cleanup Candidates {{ series_candidates | length }} series · {{ series_total_size_human }}

{% for c in series_candidates %}
{{ loop.index }}
{% if c.image_url %} {{ c.name }} {% else %}
No poster
{% endif %}
{% if c.year %}
{{ c.year }}
{% endif %}
{% if c.rating is none or c.rating_str == "unrated" %} ★ Unrated {% else %} ★ {{ c.rating_str }} {% endif %} {% if c.critic_rating_str %} 🍕 {{ c.critic_rating_str }} {% endif %} Required: {{ c.threshold_str }} {{ c.stale_years }} yr stale {{ c.episode_count }} episodes {{ c.size_human }} {{ c.library }} {% if doit and c.deletion_result %} {% if c.deletion_result.status == "success" %} ✓ Deleted {% elif c.deletion_result.status == "failed" %} ✗ Failed {% else %} Skipped {% endif %} {% elif not doit %} Dry-run {% endif %}
{% if c.last_episode_added %}
Last episode added: {{ c.last_episode_added }}
{% else %}
No episodes
{% endif %}
{{ c.path }}
{% endfor %} {% endif %} {% if movie_near_miss is defined and movie_near_miss %}

Next {{ movie_near_miss | length }} Movies to Be Removed {{ movie_near_miss_size_human }}

Protected only by rating — sorted by soonest removal.

{% for c in movie_near_miss %}
{{ loop.index }}
{% if c.image_url %} {{ c.name }} {% else %}
No poster
{% endif %}
{% if c.year %}
{{ c.year }}
{% endif %}
{% if c.rating is none or c.rating_str == "unrated" %} ★ Unrated {% else %} ★ {{ c.rating_str }} {% endif %} {% if c.critic_rating_str %} 🍕 {{ c.critic_rating_str }} {% endif %} Required: {{ c.threshold_str }} {{ c.days_left_str }} left {{ c.age_years }} yr on server {{ c.size_human }} {{ c.library }}
{{ c.path }}
{% endfor %} {% endif %} {% if series_near_miss is defined and series_near_miss %}

Next {{ series_near_miss | length }} Series to Be Removed {{ series_near_miss_size_human }}

Protected only by rating — sorted by soonest removal.

{% for c in series_near_miss %}
{{ loop.index }}
{% if c.image_url %} {{ c.name }} {% else %}
No poster
{% endif %}
{% if c.year %}
{{ c.year }}
{% endif %}
{% if c.rating is none or c.rating_str == "unrated" %} ★ Unrated {% else %} ★ {{ c.rating_str }} {% endif %} {% if c.critic_rating_str %} 🍕 {{ c.critic_rating_str }} {% endif %} Required: {{ c.threshold_str }} {{ c.days_left_str }} left {{ c.stale_years }} yr stale {{ c.episode_count }} episodes {{ c.size_human }} {{ c.library }}
{% if c.last_episode_added %}
Last episode added: {{ c.last_episode_added }}
{% else %}
No episodes
{% endif %}
{{ c.path }}
{% endfor %} {% endif %}