From 35cee77a983c8448cdae0e26e530699820e2f022 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Mon, 5 Oct 2026 19:19:08 -0400 Subject: Backport pull request #18280 from jellyfin/release-12.z Only propagate a changed rating to children that follow it Original-merge: 1d5590d02ac04d857e73a4e4406b0801589d3368 Merged-by: crobibero Backported-by: Cody Robibero --- Jellyfin.Api/Controllers/ItemUpdateController.cs | 37 +++++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'Jellyfin.Api/Controllers/ItemUpdateController.cs') diff --git a/Jellyfin.Api/Controllers/ItemUpdateController.cs b/Jellyfin.Api/Controllers/ItemUpdateController.cs index 4859cb89c0..288efebc4f 100644 --- a/Jellyfin.Api/Controllers/ItemUpdateController.cs +++ b/Jellyfin.Api/Controllers/ItemUpdateController.cs @@ -292,6 +292,8 @@ public class ItemUpdateController : BaseJellyfinApiController item.PremiereDate = request.PremiereDate.HasValue ? NormalizeDateTime(request.PremiereDate.Value) : null; item.ProductionYear = request.ProductionYear; + var previousOfficialRating = item.OfficialRating; + var previousCustomRating = item.CustomRating; request.OfficialRating = string.IsNullOrWhiteSpace(request.OfficialRating) ? null : request.OfficialRating; item.OfficialRating = request.OfficialRating; item.CustomRating = request.CustomRating; @@ -318,12 +320,14 @@ public class ItemUpdateController : BaseJellyfinApiController { season.SeriesName = rseries.Name; + var previousSeasonOfficialRating = season.OfficialRating; + var previousSeasonCustomRating = season.CustomRating; if (!season.LockedFields.Contains(MetadataField.OfficialRating)) { - season.OfficialRating = request.OfficialRating; + season.OfficialRating = GetPropagatedRating(season.OfficialRating, previousOfficialRating, request.OfficialRating); } - season.CustomRating = request.CustomRating; + season.CustomRating = GetPropagatedRating(season.CustomRating, previousCustomRating, request.CustomRating); if (!season.LockedFields.Contains(MetadataField.Tags)) { @@ -339,10 +343,10 @@ public class ItemUpdateController : BaseJellyfinApiController if (!ep.LockedFields.Contains(MetadataField.OfficialRating)) { - ep.OfficialRating = request.OfficialRating; + ep.OfficialRating = GetPropagatedRating(ep.OfficialRating, previousSeasonOfficialRating, season.OfficialRating); } - ep.CustomRating = request.CustomRating; + ep.CustomRating = GetPropagatedRating(ep.CustomRating, previousSeasonCustomRating, season.CustomRating); if (!ep.LockedFields.Contains(MetadataField.Tags)) { @@ -362,10 +366,10 @@ public class ItemUpdateController : BaseJellyfinApiController if (!ep.LockedFields.Contains(MetadataField.OfficialRating)) { - ep.OfficialRating = request.OfficialRating; + ep.OfficialRating = GetPropagatedRating(ep.OfficialRating, previousOfficialRating, request.OfficialRating); } - ep.CustomRating = request.CustomRating; + ep.CustomRating = GetPropagatedRating(ep.CustomRating, previousCustomRating, request.CustomRating); if (!ep.LockedFields.Contains(MetadataField.Tags)) { @@ -382,10 +386,10 @@ public class ItemUpdateController : BaseJellyfinApiController { if (!track.LockedFields.Contains(MetadataField.OfficialRating)) { - track.OfficialRating = request.OfficialRating; + track.OfficialRating = GetPropagatedRating(track.OfficialRating, previousOfficialRating, request.OfficialRating); } - track.CustomRating = request.CustomRating; + track.CustomRating = GetPropagatedRating(track.CustomRating, previousCustomRating, request.CustomRating); if (!track.LockedFields.Contains(MetadataField.Tags)) { @@ -477,6 +481,23 @@ public class ItemUpdateController : BaseJellyfinApiController } } + /// + /// Gets the rating a child should carry after its parent's rating changed from + /// to : a child with no rating, or the parent's previous one, follows the parent. + /// A child with a rating of its own, or any child when the parent's rating did not change, keeps its rating. + /// + private static string? GetPropagatedRating(string? childRating, string? previousRating, string? newRating) + { + if (string.Equals(previousRating ?? string.Empty, newRating ?? string.Empty, StringComparison.OrdinalIgnoreCase)) + { + return childRating; + } + + return string.IsNullOrEmpty(childRating) || string.Equals(childRating, previousRating, StringComparison.OrdinalIgnoreCase) + ? newRating + : childRating; + } + private SeriesStatus? GetSeriesStatus(BaseItemDto item) { if (string.IsNullOrEmpty(item.Status)) -- cgit v1.2.3