feat: add genre, rating, and avoid-repeats trailer filters
All checks were successful
Publish Release / release (push) Successful in 23s

Trailer selection now supports three optional filters:
- Genre match: prefer trailers whose fake-movie genre overlaps with the
  feature being played (requires TMDB genres in NFO)
- Age rating ceiling: exclude trailers rated higher than the feature
  (requires TMDB certification in NFO)
- Avoid repeats: cycle through all trailers before replaying any;
  resets per-user once the pool is exhausted

Genre and certification are fetched from TMDB at download time via a
single /movie/{id}?append_to_response=release_dates call and written
into the fake-movie NFO as <genre> and <mpaa> tags. All filters fall
back to the full unfiltered pool when no match is found.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin
2026-06-09 17:15:11 -04:00
parent 6772bde3b4
commit 83966f40ea
8 changed files with 231 additions and 24 deletions

View File

@@ -235,6 +235,39 @@
Default: 1.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="filter-genre" />
<span>Match genre to the movie being played</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Only pick trailers whose genre overlaps with the movie you are watching.
Falls back to any trailer if no match is found.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="filter-rating" />
<span>Limit to same age rating or lower</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Never show a trailer rated higher than the movie being played.
Falls back to any trailer if no match is found.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="avoid-repeats" />
<span>Avoid repeating trailers</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Cycle through all available trailers before playing any again.
Resets automatically once every trailer has been shown. Default: on.
</div>
</div>
</fieldset>
<!-- Advanced -->
@@ -285,6 +318,9 @@
});
document.getElementById('max-total-trailers').value = config.MaxTotalTrailers ?? 50;
document.getElementById('trailers-per-movie').value = config.TrailersPerMovie ?? 1;
document.getElementById('filter-genre').checked = !!config.FilterByGenre;
document.getElementById('filter-rating').checked = !!config.FilterByRating;
document.getElementById('avoid-repeats').checked = config.AvoidRepeats !== false;
Dashboard.hideLoadingMsg();
});
});
@@ -313,6 +349,9 @@
config.AllowedLanguages = checkedLangs.length === allLangCodes.length ? '' : checkedLangs.join(',');
config.MaxTotalTrailers = parseInt(document.getElementById('max-total-trailers').value, 10) || 50;
config.TrailersPerMovie = parseInt(document.getElementById('trailers-per-movie').value, 10) || 0;
config.FilterByGenre = document.getElementById('filter-genre').checked;
config.FilterByRating = document.getElementById('filter-rating').checked;
config.AvoidRepeats = document.getElementById('avoid-repeats').checked;
ApiClient.updatePluginConfiguration(pluginId, config)
.then(Dashboard.processPluginConfigurationUpdateResult);
});