Apply the community-rating floor to rated titles as well
The audience tag admitted any title whose official rating sat at or below the ceiling, with no quality condition at all. The community-rating floor was only consulted when a title had no usable rating. On a real library that let 21 poorly reviewed but mildly rated titles through - Norbit, Cats, Super Mario Bros., Rocky V, Cool as Ice among them - none of which belong in a library whose entire purpose is to be smaller than the one it was carved out of. A ceiling answers whether a title is suitable; it says nothing about whether it is worth offering. MinCommunityRating now applies to rated titles, alongside the existing MinCommunityRatingWhenUnrated for titles with no rating to judge. The two are separate settings because an unrated title carries more uncertainty and may warrant a higher bar. A rated title with no community rating at all now fails, which is deliberate: with neither a score to check nor a reputation to weigh, there is nothing to decide on. Verified against the live library: a full pass over 2778 titles settles at 561 tagged, and the 21 are not re-added.
This commit is contained in:
+9
-4
@@ -23,10 +23,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
map, and left alone.
|
||||
|
||||
- Audience tagging. Applies a configurable tag (default `grandma`) to titles
|
||||
that pass a genre and rating rule, so a user account can be narrowed with
|
||||
Allowed Tags. Because Allowed Tags fails closed, new content is invisible to
|
||||
that account until tagged, which is why this runs on a schedule rather than
|
||||
once.
|
||||
that clear a genre rule, a rating ceiling and a community-rating floor, so a
|
||||
user account can be narrowed with Allowed Tags. The floor applies to rated and
|
||||
unrated titles alike, through separate settings, because a ceiling on its own
|
||||
admits poorly reviewed titles that happen to carry a mild rating, and the
|
||||
point of the tag is to make an overwhelming library smaller rather than to
|
||||
reproduce it. Unrated titles are judged on reputation alone, which is what
|
||||
keeps the older classics TMDB holds no US certification for. Because Allowed
|
||||
Tags fails closed, new content is invisible to that account until tagged,
|
||||
which is why this runs on a schedule rather than once.
|
||||
|
||||
- A curation ledger at `tagged-ids.txt` in the plugin data folder. An item whose
|
||||
id is in the ledger but which no longer carries the tag was untagged by a
|
||||
|
||||
@@ -130,15 +130,22 @@ public static class AudienceRules
|
||||
return false;
|
||||
}
|
||||
|
||||
// A usable rating is judged on the rating. Anything at or below the ceiling is in.
|
||||
// A usable rating must clear the ceiling AND the quality floor. The floor matters
|
||||
// as much as the ceiling: the point of this tag is to make an overwhelming library
|
||||
// smaller, and a poorly reviewed film that happens to be rated PG adds noise rather
|
||||
// than removing it. An item with no community rating at all fails here, which is
|
||||
// deliberate - without a rating and without a score there is nothing to judge on.
|
||||
if (ratingScore.HasValue)
|
||||
{
|
||||
return ratingScore.Value <= config.MaxRatingScore;
|
||||
return ratingScore.Value <= config.MaxRatingScore
|
||||
&& item.CommunityRating.HasValue
|
||||
&& item.CommunityRating.Value >= config.MinCommunityRating;
|
||||
}
|
||||
|
||||
// No usable rating: fall back to reputation. This is what keeps the older
|
||||
// classics, which are exactly what this audience wants and which TMDB
|
||||
// frequently has no US certification for.
|
||||
// No usable rating: fall back to reputation alone, against its own floor. This is
|
||||
// what keeps the older classics, which are exactly what this audience wants and
|
||||
// which TMDB frequently has no US certification for. The floor is separate because
|
||||
// an unrated item is carrying more risk, so it may warrant a higher bar.
|
||||
return item.CommunityRating.HasValue
|
||||
&& item.CommunityRating.Value >= config.MinCommunityRatingWhenUnrated;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,15 @@ public class PluginConfiguration : BasePluginConfiguration
|
||||
/// </remarks>
|
||||
public int MaxRatingScore { get; set; } = 14;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the community rating an item must reach to be tagged when it DOES have a
|
||||
/// usable official rating. The ceiling alone is not enough: this tag exists to make an
|
||||
/// overwhelming library smaller, and a poorly reviewed film that happens to be rated PG
|
||||
/// adds noise rather than removing it. An item carrying no community rating at all fails
|
||||
/// this check, which is deliberate.
|
||||
/// </summary>
|
||||
public double MinCommunityRating { get; set; } = 6.0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum community rating for an item with no usable parental rating.
|
||||
/// </summary>
|
||||
|
||||
@@ -84,6 +84,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="MinCommunityRating">Community rating floor for rated items</label>
|
||||
<input is="emby-input" type="number" id="MinCommunityRating" min="0" max="10" step="0.1" />
|
||||
<div class="fieldDescription">
|
||||
A rated item must clear this as well as the ceiling. The point of the tag
|
||||
is to make an overwhelming library smaller, and a poorly reviewed film
|
||||
that happens to be rated PG adds noise rather than removing it. An item
|
||||
with no community rating at all fails this check.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="MinCommunityRatingWhenUnrated">Community rating floor for unrated items</label>
|
||||
<input is="emby-input" type="number" id="MinCommunityRatingWhenUnrated" min="0" max="10" step="0.1" />
|
||||
@@ -129,6 +140,7 @@
|
||||
document.querySelector('#ApplyTags').checked = config.ApplyTags;
|
||||
document.querySelector('#TagName').value = config.TagName;
|
||||
document.querySelector('#MaxRatingScore').value = config.MaxRatingScore;
|
||||
document.querySelector('#MinCommunityRating').value = config.MinCommunityRating;
|
||||
document.querySelector('#MinCommunityRatingWhenUnrated').value = config.MinCommunityRatingWhenUnrated;
|
||||
document.querySelector('#RespectManualUntag').checked = config.RespectManualUntag;
|
||||
Dashboard.hideLoadingMsg();
|
||||
@@ -145,6 +157,7 @@
|
||||
config.ApplyTags = document.querySelector('#ApplyTags').checked;
|
||||
config.TagName = document.querySelector('#TagName').value;
|
||||
config.MaxRatingScore = parseInt(document.querySelector('#MaxRatingScore').value, 10);
|
||||
config.MinCommunityRating = parseFloat(document.querySelector('#MinCommunityRating').value);
|
||||
config.MinCommunityRatingWhenUnrated = parseFloat(document.querySelector('#MinCommunityRatingWhenUnrated').value);
|
||||
config.RespectManualUntag = document.querySelector('#RespectManualUntag').checked;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user