mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-29 05:16:30 +01:00
Merge branch 'master' into network-rewrite
This commit is contained in:
@@ -401,7 +401,7 @@ namespace Emby.Server.Implementations.Channels
|
||||
}
|
||||
else
|
||||
{
|
||||
results = new List<MediaSourceInfo>();
|
||||
results = Enumerable.Empty<MediaSourceInfo>();
|
||||
}
|
||||
|
||||
return results
|
||||
|
||||
@@ -206,8 +206,7 @@ namespace Emby.Server.Implementations.Collections
|
||||
throw new ArgumentException("No collection exists with the supplied Id");
|
||||
}
|
||||
|
||||
var list = new List<LinkedChild>();
|
||||
var itemList = new List<BaseItem>();
|
||||
List<BaseItem>? itemList = null;
|
||||
|
||||
var linkedChildrenList = collection.GetLinkedChildren();
|
||||
var currentLinkedChildrenIds = linkedChildrenList.Select(i => i.Id).ToList();
|
||||
@@ -223,18 +222,23 @@ namespace Emby.Server.Implementations.Collections
|
||||
|
||||
if (!currentLinkedChildrenIds.Contains(id))
|
||||
{
|
||||
itemList.Add(item);
|
||||
(itemList ??= new()).Add(item);
|
||||
|
||||
list.Add(LinkedChild.Create(item));
|
||||
linkedChildrenList.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (list.Count > 0)
|
||||
if (itemList is not null)
|
||||
{
|
||||
LinkedChild[] newChildren = new LinkedChild[collection.LinkedChildren.Length + list.Count];
|
||||
var originalLen = collection.LinkedChildren.Length;
|
||||
var newItemCount = itemList.Count;
|
||||
LinkedChild[] newChildren = new LinkedChild[originalLen + newItemCount];
|
||||
collection.LinkedChildren.CopyTo(newChildren, 0);
|
||||
list.CopyTo(newChildren, collection.LinkedChildren.Length);
|
||||
for (int i = 0; i < newItemCount; i++)
|
||||
{
|
||||
newChildren[originalLen + i] = LinkedChild.Create(itemList[i]);
|
||||
}
|
||||
|
||||
collection.LinkedChildren = newChildren;
|
||||
collection.UpdateRatingToItems(linkedChildrenList);
|
||||
|
||||
|
||||
@@ -586,7 +586,7 @@ namespace Emby.Server.Implementations.Data
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="items"/> or <paramref name="cancellationToken"/> is <c>null</c>.
|
||||
/// </exception>
|
||||
public void SaveItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken)
|
||||
public void SaveItems(IReadOnlyList<BaseItem> items, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(items);
|
||||
|
||||
@@ -594,9 +594,11 @@ namespace Emby.Server.Implementations.Data
|
||||
|
||||
CheckDisposed();
|
||||
|
||||
var tuples = new List<(BaseItem, List<Guid>, BaseItem, string, List<string>)>();
|
||||
foreach (var item in items)
|
||||
var itemsLen = items.Count;
|
||||
var tuples = new ValueTuple<BaseItem, List<Guid>, BaseItem, string, List<string>>[itemsLen];
|
||||
for (int i = 0; i < itemsLen; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
var ancestorIds = item.SupportsAncestors ?
|
||||
item.GetAncestorIds().Distinct().ToList() :
|
||||
null;
|
||||
@@ -606,7 +608,7 @@ namespace Emby.Server.Implementations.Data
|
||||
var userdataKey = item.GetUserDataKeys().FirstOrDefault();
|
||||
var inheritedTags = item.GetInheritedTags();
|
||||
|
||||
tuples.Add((item, ancestorIds, topParent, userdataKey, inheritedTags));
|
||||
tuples[i] = (item, ancestorIds, topParent, userdataKey, inheritedTags);
|
||||
}
|
||||
|
||||
using (var connection = GetConnection())
|
||||
@@ -3202,7 +3204,8 @@ namespace Emby.Server.Implementations.Data
|
||||
return IsAlphaNumeric(value);
|
||||
}
|
||||
|
||||
private List<string> GetWhereClauses(InternalItemsQuery query, IStatement statement)
|
||||
#nullable enable
|
||||
private List<string> GetWhereClauses(InternalItemsQuery query, IStatement? statement)
|
||||
{
|
||||
if (query.IsResumable ?? false)
|
||||
{
|
||||
@@ -3677,7 +3680,6 @@ namespace Emby.Server.Implementations.Data
|
||||
if (statement is not null)
|
||||
{
|
||||
nameContains = FixUnicodeChars(nameContains);
|
||||
|
||||
statement.TryBind("@NameContains", "%" + GetCleanValue(nameContains) + "%");
|
||||
}
|
||||
}
|
||||
@@ -3803,13 +3805,8 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var artistId in query.ArtistIds)
|
||||
{
|
||||
var paramName = "@ArtistIds" + index;
|
||||
|
||||
clauses.Add("(guid in (select itemid from ItemValues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type<=1))");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, artistId);
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, artistId);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3824,13 +3821,8 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var artistId in query.AlbumArtistIds)
|
||||
{
|
||||
var paramName = "@ArtistIds" + index;
|
||||
|
||||
clauses.Add("(guid in (select itemid from ItemValues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type=1))");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, artistId);
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, artistId);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3845,13 +3837,8 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var artistId in query.ContributingArtistIds)
|
||||
{
|
||||
var paramName = "@ArtistIds" + index;
|
||||
|
||||
clauses.Add("((select CleanName from TypedBaseItems where guid=" + paramName + ") in (select CleanValue from ItemValues where ItemId=Guid and Type=0) AND (select CleanName from TypedBaseItems where guid=" + paramName + ") not in (select CleanValue from ItemValues where ItemId=Guid and Type=1))");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, artistId);
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, artistId);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3866,13 +3853,8 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var albumId in query.AlbumIds)
|
||||
{
|
||||
var paramName = "@AlbumIds" + index;
|
||||
|
||||
clauses.Add("Album in (select Name from typedbaseitems where guid=" + paramName + ")");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, albumId);
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, albumId);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3887,13 +3869,8 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var artistId in query.ExcludeArtistIds)
|
||||
{
|
||||
var paramName = "@ExcludeArtistId" + index;
|
||||
|
||||
clauses.Add("(guid not in (select itemid from ItemValues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type<=1))");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, artistId);
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, artistId);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3908,13 +3885,8 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var genreId in query.GenreIds)
|
||||
{
|
||||
var paramName = "@GenreId" + index;
|
||||
|
||||
clauses.Add("(guid in (select itemid from ItemValues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type=2))");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, genreId);
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, genreId);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3929,11 +3901,7 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var item in query.Genres)
|
||||
{
|
||||
clauses.Add("@Genre" + index + " in (select CleanValue from ItemValues where ItemId=Guid and Type=2)");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@Genre" + index, GetCleanValue(item));
|
||||
}
|
||||
|
||||
statement?.TryBind("@Genre" + index, GetCleanValue(item));
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3948,11 +3916,7 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var item in tags)
|
||||
{
|
||||
clauses.Add("@Tag" + index + " in (select CleanValue from ItemValues where ItemId=Guid and Type=4)");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@Tag" + index, GetCleanValue(item));
|
||||
}
|
||||
|
||||
statement?.TryBind("@Tag" + index, GetCleanValue(item));
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3967,11 +3931,7 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var item in excludeTags)
|
||||
{
|
||||
clauses.Add("@ExcludeTag" + index + " not in (select CleanValue from ItemValues where ItemId=Guid and Type=4)");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@ExcludeTag" + index, GetCleanValue(item));
|
||||
}
|
||||
|
||||
statement?.TryBind("@ExcludeTag" + index, GetCleanValue(item));
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -3986,14 +3946,8 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var studioId in query.StudioIds)
|
||||
{
|
||||
var paramName = "@StudioId" + index;
|
||||
|
||||
clauses.Add("(guid in (select itemid from ItemValues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type=3))");
|
||||
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, studioId);
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, studioId);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -4008,11 +3962,7 @@ namespace Emby.Server.Implementations.Data
|
||||
foreach (var item in query.OfficialRatings)
|
||||
{
|
||||
clauses.Add("OfficialRating=@OfficialRating" + index);
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@OfficialRating" + index, item);
|
||||
}
|
||||
|
||||
statement?.TryBind("@OfficialRating" + index, item);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -4020,34 +3970,96 @@ namespace Emby.Server.Implementations.Data
|
||||
whereClauses.Add(clause);
|
||||
}
|
||||
|
||||
if (query.MinParentalRating.HasValue)
|
||||
var ratingClauseBuilder = new StringBuilder("(");
|
||||
if (query.HasParentalRating ?? false)
|
||||
{
|
||||
whereClauses.Add("InheritedParentalRatingValue>=@MinParentalRating");
|
||||
if (statement is not null)
|
||||
ratingClauseBuilder.Append("InheritedParentalRatingValue not null");
|
||||
if (query.MinParentalRating.HasValue)
|
||||
{
|
||||
statement.TryBind("@MinParentalRating", query.MinParentalRating.Value);
|
||||
ratingClauseBuilder.Append(" AND InheritedParentalRatingValue >= @MinParentalRating");
|
||||
statement?.TryBind("@MinParentalRating", query.MinParentalRating.Value);
|
||||
}
|
||||
|
||||
if (query.MaxParentalRating.HasValue)
|
||||
{
|
||||
ratingClauseBuilder.Append(" AND InheritedParentalRatingValue <= @MaxParentalRating");
|
||||
statement?.TryBind("@MaxParentalRating", query.MaxParentalRating.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (query.MaxParentalRating.HasValue)
|
||||
else if (query.BlockUnratedItems.Length > 0)
|
||||
{
|
||||
whereClauses.Add("InheritedParentalRatingValue<=@MaxParentalRating");
|
||||
var paramName = "@UnratedType";
|
||||
var index = 0;
|
||||
string blockedUnratedItems = string.Join(',', query.BlockUnratedItems.Select(_ => paramName + index++));
|
||||
ratingClauseBuilder.Append("(InheritedParentalRatingValue is null AND UnratedType not in (" + blockedUnratedItems + "))");
|
||||
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@MaxParentalRating", query.MaxParentalRating.Value);
|
||||
for (var ind = 0; ind < query.BlockUnratedItems.Length; ind++)
|
||||
{
|
||||
statement.TryBind(paramName + ind, query.BlockUnratedItems[ind].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (query.MinParentalRating.HasValue || query.MaxParentalRating.HasValue)
|
||||
{
|
||||
ratingClauseBuilder.Append(" OR (");
|
||||
}
|
||||
|
||||
if (query.MinParentalRating.HasValue)
|
||||
{
|
||||
ratingClauseBuilder.Append("InheritedParentalRatingValue >= @MinParentalRating");
|
||||
statement?.TryBind("@MinParentalRating", query.MinParentalRating.Value);
|
||||
}
|
||||
|
||||
if (query.MaxParentalRating.HasValue)
|
||||
{
|
||||
if (query.MinParentalRating.HasValue)
|
||||
{
|
||||
ratingClauseBuilder.Append(" AND ");
|
||||
}
|
||||
|
||||
ratingClauseBuilder.Append("InheritedParentalRatingValue <= @MaxParentalRating");
|
||||
statement?.TryBind("@MaxParentalRating", query.MaxParentalRating.Value);
|
||||
}
|
||||
|
||||
if (query.MinParentalRating.HasValue || query.MaxParentalRating.HasValue)
|
||||
{
|
||||
ratingClauseBuilder.Append(")");
|
||||
}
|
||||
|
||||
if (!(query.MinParentalRating.HasValue || query.MaxParentalRating.HasValue))
|
||||
{
|
||||
ratingClauseBuilder.Append(" OR InheritedParentalRatingValue not null");
|
||||
}
|
||||
}
|
||||
|
||||
if (query.HasParentalRating.HasValue)
|
||||
else if (query.MinParentalRating.HasValue)
|
||||
{
|
||||
if (query.HasParentalRating.Value)
|
||||
ratingClauseBuilder.Append("InheritedParentalRatingValue is null OR (InheritedParentalRatingValue >= @MinParentalRating");
|
||||
statement?.TryBind("@MinParentalRating", query.MinParentalRating.Value);
|
||||
|
||||
if (query.MaxParentalRating.HasValue)
|
||||
{
|
||||
whereClauses.Add("InheritedParentalRatingValue > 0");
|
||||
}
|
||||
else
|
||||
{
|
||||
whereClauses.Add("InheritedParentalRatingValue = 0");
|
||||
ratingClauseBuilder.Append(" AND InheritedParentalRatingValue <= @MaxParentalRating");
|
||||
statement?.TryBind("@MaxParentalRating", query.MaxParentalRating.Value);
|
||||
}
|
||||
|
||||
ratingClauseBuilder.Append(")");
|
||||
}
|
||||
else if (query.MaxParentalRating.HasValue)
|
||||
{
|
||||
ratingClauseBuilder.Append("InheritedParentalRatingValue is null OR InheritedParentalRatingValue <= @MaxParentalRating");
|
||||
statement?.TryBind("@MaxParentalRating", query.MaxParentalRating.Value);
|
||||
}
|
||||
else if (!query.HasParentalRating ?? false)
|
||||
{
|
||||
ratingClauseBuilder.Append("InheritedParentalRatingValue is null");
|
||||
}
|
||||
|
||||
var ratingClauseString = ratingClauseBuilder.ToString();
|
||||
if (!string.Equals(ratingClauseString, "(", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
whereClauses.Add(ratingClauseString + ")");
|
||||
}
|
||||
|
||||
if (query.HasOfficialRating.HasValue)
|
||||
@@ -4089,37 +4101,25 @@ namespace Emby.Server.Implementations.Data
|
||||
if (!string.IsNullOrWhiteSpace(query.HasNoAudioTrackWithLanguage))
|
||||
{
|
||||
whereClauses.Add("((select language from MediaStreams where MediaStreams.ItemId=A.Guid and MediaStreams.StreamType='Audio' and MediaStreams.Language=@HasNoAudioTrackWithLanguage limit 1) is null)");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@HasNoAudioTrackWithLanguage", query.HasNoAudioTrackWithLanguage);
|
||||
}
|
||||
statement?.TryBind("@HasNoAudioTrackWithLanguage", query.HasNoAudioTrackWithLanguage);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.HasNoInternalSubtitleTrackWithLanguage))
|
||||
{
|
||||
whereClauses.Add("((select language from MediaStreams where MediaStreams.ItemId=A.Guid and MediaStreams.StreamType='Subtitle' and MediaStreams.IsExternal=0 and MediaStreams.Language=@HasNoInternalSubtitleTrackWithLanguage limit 1) is null)");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@HasNoInternalSubtitleTrackWithLanguage", query.HasNoInternalSubtitleTrackWithLanguage);
|
||||
}
|
||||
statement?.TryBind("@HasNoInternalSubtitleTrackWithLanguage", query.HasNoInternalSubtitleTrackWithLanguage);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.HasNoExternalSubtitleTrackWithLanguage))
|
||||
{
|
||||
whereClauses.Add("((select language from MediaStreams where MediaStreams.ItemId=A.Guid and MediaStreams.StreamType='Subtitle' and MediaStreams.IsExternal=1 and MediaStreams.Language=@HasNoExternalSubtitleTrackWithLanguage limit 1) is null)");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@HasNoExternalSubtitleTrackWithLanguage", query.HasNoExternalSubtitleTrackWithLanguage);
|
||||
}
|
||||
statement?.TryBind("@HasNoExternalSubtitleTrackWithLanguage", query.HasNoExternalSubtitleTrackWithLanguage);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.HasNoSubtitleTrackWithLanguage))
|
||||
{
|
||||
whereClauses.Add("((select language from MediaStreams where MediaStreams.ItemId=A.Guid and MediaStreams.StreamType='Subtitle' and MediaStreams.Language=@HasNoSubtitleTrackWithLanguage limit 1) is null)");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@HasNoSubtitleTrackWithLanguage", query.HasNoSubtitleTrackWithLanguage);
|
||||
}
|
||||
statement?.TryBind("@HasNoSubtitleTrackWithLanguage", query.HasNoSubtitleTrackWithLanguage);
|
||||
}
|
||||
|
||||
if (query.HasSubtitles.HasValue)
|
||||
@@ -4169,15 +4169,11 @@ namespace Emby.Server.Implementations.Data
|
||||
if (query.Years.Length == 1)
|
||||
{
|
||||
whereClauses.Add("ProductionYear=@Years");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@Years", query.Years[0].ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
statement?.TryBind("@Years", query.Years[0].ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
else if (query.Years.Length > 1)
|
||||
{
|
||||
var val = string.Join(',', query.Years);
|
||||
|
||||
whereClauses.Add("ProductionYear in (" + val + ")");
|
||||
}
|
||||
|
||||
@@ -4185,10 +4181,7 @@ namespace Emby.Server.Implementations.Data
|
||||
if (isVirtualItem.HasValue)
|
||||
{
|
||||
whereClauses.Add("IsVirtualItem=@IsVirtualItem");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@IsVirtualItem", isVirtualItem.Value);
|
||||
}
|
||||
statement?.TryBind("@IsVirtualItem", isVirtualItem.Value);
|
||||
}
|
||||
|
||||
if (query.IsSpecialSeason.HasValue)
|
||||
@@ -4219,31 +4212,22 @@ namespace Emby.Server.Implementations.Data
|
||||
if (queryMediaTypes.Length == 1)
|
||||
{
|
||||
whereClauses.Add("MediaType=@MediaTypes");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@MediaTypes", queryMediaTypes[0]);
|
||||
}
|
||||
statement?.TryBind("@MediaTypes", queryMediaTypes[0]);
|
||||
}
|
||||
else if (queryMediaTypes.Length > 1)
|
||||
{
|
||||
var val = string.Join(',', queryMediaTypes.Select(i => "'" + i + "'"));
|
||||
|
||||
whereClauses.Add("MediaType in (" + val + ")");
|
||||
}
|
||||
|
||||
if (query.ItemIds.Length > 0)
|
||||
{
|
||||
var includeIds = new List<string>();
|
||||
|
||||
var index = 0;
|
||||
foreach (var id in query.ItemIds)
|
||||
{
|
||||
includeIds.Add("Guid = @IncludeId" + index);
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@IncludeId" + index, id);
|
||||
}
|
||||
|
||||
statement?.TryBind("@IncludeId" + index, id);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -4253,16 +4237,11 @@ namespace Emby.Server.Implementations.Data
|
||||
if (query.ExcludeItemIds.Length > 0)
|
||||
{
|
||||
var excludeIds = new List<string>();
|
||||
|
||||
var index = 0;
|
||||
foreach (var id in query.ExcludeItemIds)
|
||||
{
|
||||
excludeIds.Add("Guid <> @ExcludeId" + index);
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@ExcludeId" + index, id);
|
||||
}
|
||||
|
||||
statement?.TryBind("@ExcludeId" + index, id);
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -4283,11 +4262,7 @@ namespace Emby.Server.Implementations.Data
|
||||
|
||||
var paramName = "@ExcludeProviderId" + index;
|
||||
excludeIds.Add("(ProviderIds is null or ProviderIds not like " + paramName + ")");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
|
||||
index++;
|
||||
|
||||
break;
|
||||
@@ -4312,7 +4287,7 @@ namespace Emby.Server.Implementations.Data
|
||||
}
|
||||
|
||||
// TODO this seems to be an idea for a better schema where ProviderIds are their own table
|
||||
// buut this is not implemented
|
||||
// but this is not implemented
|
||||
// hasProviderIds.Add("(COALESCE((select value from ProviderIds where ItemId=Guid and Name = '" + pair.Key + "'), '') <> " + paramName + ")");
|
||||
|
||||
// TODO this is a really BAD way to do it since the pair:
|
||||
@@ -4326,11 +4301,7 @@ namespace Emby.Server.Implementations.Data
|
||||
hasProviderIds.Add("ProviderIds like " + paramName);
|
||||
|
||||
// this replaces the placeholder with a value, here: %key=val%
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
|
||||
}
|
||||
|
||||
statement?.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
|
||||
index++;
|
||||
|
||||
break;
|
||||
@@ -4407,11 +4378,7 @@ namespace Emby.Server.Implementations.Data
|
||||
if (query.AncestorIds.Length == 1)
|
||||
{
|
||||
whereClauses.Add("Guid in (select itemId from AncestorIds where AncestorId=@AncestorId)");
|
||||
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@AncestorId", query.AncestorIds[0]);
|
||||
}
|
||||
statement?.TryBind("@AncestorId", query.AncestorIds[0]);
|
||||
}
|
||||
|
||||
if (query.AncestorIds.Length > 1)
|
||||
@@ -4424,39 +4391,13 @@ namespace Emby.Server.Implementations.Data
|
||||
{
|
||||
var inClause = "select guid from TypedBaseItems where PresentationUniqueKey=@AncestorWithPresentationUniqueKey";
|
||||
whereClauses.Add(string.Format(CultureInfo.InvariantCulture, "Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause));
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@AncestorWithPresentationUniqueKey", query.AncestorWithPresentationUniqueKey);
|
||||
}
|
||||
statement?.TryBind("@AncestorWithPresentationUniqueKey", query.AncestorWithPresentationUniqueKey);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.SeriesPresentationUniqueKey))
|
||||
{
|
||||
whereClauses.Add("SeriesPresentationUniqueKey=@SeriesPresentationUniqueKey");
|
||||
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@SeriesPresentationUniqueKey", query.SeriesPresentationUniqueKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (query.BlockUnratedItems.Length == 1)
|
||||
{
|
||||
whereClauses.Add("(InheritedParentalRatingValue > 0 or UnratedType <> @UnratedType)");
|
||||
if (statement is not null)
|
||||
{
|
||||
statement.TryBind("@UnratedType", query.BlockUnratedItems[0].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (query.BlockUnratedItems.Length > 1)
|
||||
{
|
||||
var inClause = string.Join(',', query.BlockUnratedItems.Select(i => "'" + i.ToString() + "'"));
|
||||
whereClauses.Add(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))",
|
||||
inClause));
|
||||
statement?.TryBind("@SeriesPresentationUniqueKey", query.SeriesPresentationUniqueKey);
|
||||
}
|
||||
|
||||
if (query.ExcludeInheritedTags.Length > 0)
|
||||
@@ -4605,6 +4546,7 @@ namespace Emby.Server.Implementations.Data
|
||||
|
||||
return whereClauses;
|
||||
}
|
||||
#nullable disable
|
||||
|
||||
/// <summary>
|
||||
/// Formats a where clause for the specified provider.
|
||||
|
||||
@@ -83,22 +83,23 @@ namespace Emby.Server.Implementations.Dto
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<BaseItemDto> GetBaseItemDtos(IReadOnlyList<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
|
||||
{
|
||||
var returnItems = new BaseItemDto[items.Count];
|
||||
var programTuples = new List<(BaseItem, BaseItemDto)>();
|
||||
var channelTuples = new List<(BaseItemDto, LiveTvChannel)>();
|
||||
var accessibleItems = user is null ? items : items.Where(x => x.IsVisible(user)).ToList();
|
||||
var returnItems = new BaseItemDto[accessibleItems.Count];
|
||||
List<(BaseItem, BaseItemDto)> programTuples = null;
|
||||
List<(BaseItemDto, LiveTvChannel)> channelTuples = null;
|
||||
|
||||
for (int index = 0; index < items.Count; index++)
|
||||
for (int index = 0; index < accessibleItems.Count; index++)
|
||||
{
|
||||
var item = items[index];
|
||||
var item = accessibleItems[index];
|
||||
var dto = GetBaseItemDtoInternal(item, options, user, owner);
|
||||
|
||||
if (item is LiveTvChannel tvChannel)
|
||||
{
|
||||
channelTuples.Add((dto, tvChannel));
|
||||
(channelTuples ??= new()).Add((dto, tvChannel));
|
||||
}
|
||||
else if (item is LiveTvProgram)
|
||||
{
|
||||
programTuples.Add((item, dto));
|
||||
(programTuples ??= new()).Add((item, dto));
|
||||
}
|
||||
|
||||
if (item is IItemByName byName)
|
||||
@@ -121,12 +122,12 @@ namespace Emby.Server.Implementations.Dto
|
||||
returnItems[index] = dto;
|
||||
}
|
||||
|
||||
if (programTuples.Count > 0)
|
||||
if (programTuples is not null)
|
||||
{
|
||||
LivetvManager.AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
if (channelTuples.Count > 0)
|
||||
if (channelTuples is not null)
|
||||
{
|
||||
LivetvManager.AddChannelInfo(channelTuples, options, user);
|
||||
}
|
||||
|
||||
@@ -356,8 +356,8 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
var children = item.IsFolder
|
||||
? ((Folder)item).GetRecursiveChildren(false).ToList()
|
||||
: new List<BaseItem>();
|
||||
? ((Folder)item).GetRecursiveChildren(false)
|
||||
: Enumerable.Empty<BaseItem>();
|
||||
|
||||
foreach (var metadataPath in GetMetadataPaths(item, children))
|
||||
{
|
||||
@@ -1253,7 +1253,7 @@ namespace Emby.Server.Implementations.Library
|
||||
var parent = GetItemById(query.ParentId);
|
||||
if (parent is not null)
|
||||
{
|
||||
SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent });
|
||||
SetTopParentIdsOrAncestors(query, new[] { parent });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1277,7 +1277,7 @@ namespace Emby.Server.Implementations.Library
|
||||
var parent = GetItemById(query.ParentId);
|
||||
if (parent is not null)
|
||||
{
|
||||
SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent });
|
||||
SetTopParentIdsOrAncestors(query, new[] { parent });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1435,7 +1435,7 @@ namespace Emby.Server.Implementations.Library
|
||||
var parent = GetItemById(query.ParentId);
|
||||
if (parent is not null)
|
||||
{
|
||||
SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent });
|
||||
SetTopParentIdsOrAncestors(query, new[] { parent });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1455,7 +1455,7 @@ namespace Emby.Server.Implementations.Library
|
||||
_itemRepository.GetItemList(query));
|
||||
}
|
||||
|
||||
private void SetTopParentIdsOrAncestors(InternalItemsQuery query, List<BaseItem> parents)
|
||||
private void SetTopParentIdsOrAncestors(InternalItemsQuery query, IReadOnlyCollection<BaseItem> parents)
|
||||
{
|
||||
if (parents.All(i => i is ICollectionFolder || i is UserView))
|
||||
{
|
||||
@@ -1602,7 +1602,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
_logger.LogError(ex, "Error getting intros");
|
||||
|
||||
return new List<IntroInfo>();
|
||||
return Enumerable.Empty<IntroInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2876,7 +2876,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
private async Task SavePeopleMetadataAsync(IEnumerable<PersonInfo> people, CancellationToken cancellationToken)
|
||||
{
|
||||
var personsToSave = new List<BaseItem>();
|
||||
List<BaseItem> personsToSave = null;
|
||||
|
||||
foreach (var person in people)
|
||||
{
|
||||
@@ -2918,12 +2918,12 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (saveEntity)
|
||||
{
|
||||
personsToSave.Add(personEntity);
|
||||
(personsToSave ??= new()).Add(personEntity);
|
||||
await RunMetadataSavers(personEntity, itemUpdateType).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (personsToSave.Count > 0)
|
||||
if (personsToSave is not null)
|
||||
{
|
||||
CreateItems(personsToSave, null, CancellationToken.None);
|
||||
}
|
||||
@@ -3085,22 +3085,19 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
}
|
||||
|
||||
var removeList = new List<NameValuePair>();
|
||||
List<NameValuePair> removeList = null;
|
||||
|
||||
foreach (var contentType in _configurationManager.Configuration.ContentTypes)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contentType.Name))
|
||||
{
|
||||
removeList.Add(contentType);
|
||||
}
|
||||
else if (_fileSystem.AreEqual(path, contentType.Name)
|
||||
if (string.IsNullOrWhiteSpace(contentType.Name)
|
||||
|| _fileSystem.AreEqual(path, contentType.Name)
|
||||
|| _fileSystem.ContainsSubPath(path, contentType.Name))
|
||||
{
|
||||
removeList.Add(contentType);
|
||||
(removeList ??= new()).Add(contentType);
|
||||
}
|
||||
}
|
||||
|
||||
if (removeList.Count > 0)
|
||||
if (removeList is not null)
|
||||
{
|
||||
_configurationManager.Configuration.ContentTypes = _configurationManager.Configuration.ContentTypes
|
||||
.Except(removeList)
|
||||
|
||||
@@ -158,7 +158,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||
private MultiItemResolverResult ResolveMultipleAudio(Folder parent, IEnumerable<FileSystemMetadata> fileSystemEntries, bool parseName)
|
||||
{
|
||||
var files = new List<FileSystemMetadata>();
|
||||
var items = new List<BaseItem>();
|
||||
var leftOver = new List<FileSystemMetadata>();
|
||||
|
||||
// Loop through each child file/folder and see if we find a video
|
||||
@@ -180,7 +179,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||
var result = new MultiItemResolverResult
|
||||
{
|
||||
ExtraFiles = leftOver,
|
||||
Items = items
|
||||
Items = new List<BaseItem>()
|
||||
};
|
||||
|
||||
var isInMixedFolder = resolverResult.Count > 1 || (parent is not null && parent.IsTopParent);
|
||||
|
||||
@@ -286,7 +286,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (parents.Count == 0)
|
||||
{
|
||||
return new List<BaseItem>();
|
||||
return Array.Empty<BaseItem>();
|
||||
}
|
||||
|
||||
if (includeItemTypes.Length == 0)
|
||||
|
||||
@@ -13,8 +13,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
public LegacyHdHomerunChannelCommands(string url)
|
||||
{
|
||||
// parse url for channel and program
|
||||
var regExp = new Regex(@"\/ch([0-9]+)-?([0-9]*)");
|
||||
var match = regExp.Match(url);
|
||||
var match = Regex.Match(url, @"\/ch([0-9]+)-?([0-9]*)");
|
||||
if (match.Success)
|
||||
{
|
||||
_channel = match.Groups[1].Value;
|
||||
|
||||
@@ -308,8 +308,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||
{
|
||||
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase);
|
||||
var matches = reg.Matches(line);
|
||||
var matches = Regex.Matches(line, @"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase);
|
||||
|
||||
remaining = line;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"ItemRemovedWithName": "{0} ha sido eliminado de la biblioteca",
|
||||
"LabelIpAddressValue": "Dirección IP: {0}",
|
||||
"LabelRunningTimeValue": "Tiempo de funcionamiento: {0}",
|
||||
"Latest": "Últimos",
|
||||
"Latest": "Último contenido en",
|
||||
"MessageApplicationUpdated": "Se ha actualizado el servidor Jellyfin",
|
||||
"MessageApplicationUpdatedTo": "Se ha actualizado el servidor Jellyfin a la versión {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "La sección {0} de configuración del servidor ha sido actualizada",
|
||||
|
||||
@@ -67,5 +67,11 @@
|
||||
"Plugin": "प्लग-इन",
|
||||
"Playlists": "प्लेलिस्ट",
|
||||
"Photos": "तस्वीरें",
|
||||
"External": "बाहरी"
|
||||
"External": "बाहरी",
|
||||
"PluginUpdatedWithName": "{0} अपडेट हुए",
|
||||
"ScheduledTaskStartedWithName": "{0} शुरू हुए",
|
||||
"Songs": "गाने",
|
||||
"UserStartedPlayingItemWithValues": "{0} {2} पर {1} खेल रहे हैं",
|
||||
"UserStoppedPlayingItemWithValues": "{0} ने {2} पर {1} खेलना खत्म किया",
|
||||
"StartupEmbyServerIsLoading": "जेलीफ़िन सर्वर लोड हो रहा है। कृपया शीघ्र ही पुन: प्रयास करें।"
|
||||
}
|
||||
|
||||
@@ -95,13 +95,13 @@
|
||||
"TaskDownloadMissingSubtitlesDescription": "Zoekt op het internet naar ontbrekende ondertiteling gebaseerd op metadataconfiguratie.",
|
||||
"TaskDownloadMissingSubtitles": "Ontbrekende ondertiteling downloaden",
|
||||
"TaskRefreshChannelsDescription": "Vernieuwt informatie van internet kanalen.",
|
||||
"TaskRefreshChannels": "Vernieuw kanalen",
|
||||
"TaskRefreshChannels": "Kanalen vernieuwen",
|
||||
"TaskCleanTranscodeDescription": "Verwijdert transcode bestanden ouder dan 1 dag.",
|
||||
"TaskCleanLogs": "Logboekmap opschonen",
|
||||
"TaskCleanTranscode": "Transcoderingsmap opschonen",
|
||||
"TaskUpdatePluginsDescription": "Downloadt en installeert updates van plug-ins waarvoor automatisch bijwerken is ingeschakeld.",
|
||||
"TaskUpdatePlugins": "Plug-ins bijwerken",
|
||||
"TaskRefreshPeopleDescription": "Update metadata voor acteurs en regisseurs in de media bibliotheek.",
|
||||
"TaskRefreshPeopleDescription": "Updatet metadata voor acteurs en regisseurs in je mediabibliotheek.",
|
||||
"TaskRefreshPeople": "Personen vernieuwen",
|
||||
"TaskCleanLogsDescription": "Verwijdert log bestanden ouder dan {0} dagen.",
|
||||
"TaskRefreshLibraryDescription": "Scant de mediabibliotheek op nieuwe bestanden en vernieuwt de metadata.",
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
"Shows": "Шоу",
|
||||
"ServerNameNeedsToBeRestarted": "{0} потрібно перезапустити",
|
||||
"ScheduledTaskStartedWithName": "{0} розпочато",
|
||||
"ScheduledTaskFailedWithName": "Помилка {0}",
|
||||
"ScheduledTaskFailedWithName": "{0} незавершено, збій",
|
||||
"ProviderValue": "Постачальник: {0}",
|
||||
"PluginUpdatedWithName": "{0} оновлено",
|
||||
"PluginUninstalledWithName": "{0} видалено",
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
@@ -25,7 +26,7 @@ namespace Emby.Server.Implementations.Localization
|
||||
private const string CulturesPath = "Emby.Server.Implementations.Localization.iso6392.txt";
|
||||
private const string CountriesPath = "Emby.Server.Implementations.Localization.countries.json";
|
||||
private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
|
||||
private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
|
||||
private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated", "nr" };
|
||||
|
||||
private readonly IServerConfigurationManager _configurationManager;
|
||||
private readonly ILogger<LocalizationManager> _logger;
|
||||
@@ -86,12 +87,10 @@ namespace Emby.Server.Implementations.Localization
|
||||
var name = parts[0];
|
||||
dict.Add(name, new ParentalRating(name, value));
|
||||
}
|
||||
#if DEBUG
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Malformed line in ratings file for country {CountryCode}", countryCode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
_allParentalRatings[countryCode] = dict;
|
||||
@@ -184,7 +183,56 @@ namespace Emby.Server.Implementations.Localization
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<ParentalRating> GetParentalRatings()
|
||||
=> GetParentalRatingsDictionary().Values;
|
||||
{
|
||||
var ratings = GetParentalRatingsDictionary().Values.ToList();
|
||||
|
||||
// Add common ratings to ensure them being available for selection.
|
||||
// Based on the US rating system due to it being the main source of rating in the metadata providers
|
||||
// Minimum rating possible
|
||||
if (!ratings.Any(x => x.Value == 0))
|
||||
{
|
||||
ratings.Add(new ParentalRating("Approved", 0));
|
||||
}
|
||||
|
||||
// Matches PG (this has different age restrictions depending on country)
|
||||
if (!ratings.Any(x => x.Value == 10))
|
||||
{
|
||||
ratings.Add(new ParentalRating("10", 10));
|
||||
}
|
||||
|
||||
// Matches PG-13
|
||||
if (!ratings.Any(x => x.Value == 13))
|
||||
{
|
||||
ratings.Add(new ParentalRating("13", 13));
|
||||
}
|
||||
|
||||
// Matches TV-14
|
||||
if (!ratings.Any(x => x.Value == 14))
|
||||
{
|
||||
ratings.Add(new ParentalRating("14", 14));
|
||||
}
|
||||
|
||||
// Catchall if max rating of country is less than 21
|
||||
// Using 21 instead of 18 to be sure to allow access to all rated content except adult and banned
|
||||
if (!ratings.Any(x => x.Value >= 21))
|
||||
{
|
||||
ratings.Add(new ParentalRating("21", 21));
|
||||
}
|
||||
|
||||
// A lot of countries don't excplicitly have a seperate rating for adult content
|
||||
if (!ratings.Any(x => x.Value == 1000))
|
||||
{
|
||||
ratings.Add(new ParentalRating("XXX", 1000));
|
||||
}
|
||||
|
||||
// A lot of countries don't excplicitly have a seperate rating for banned content
|
||||
if (!ratings.Any(x => x.Value == 1001))
|
||||
{
|
||||
ratings.Add(new ParentalRating("Banned", 1001));
|
||||
}
|
||||
|
||||
return ratings.OrderBy(r => r.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parental ratings dictionary.
|
||||
@@ -194,6 +242,7 @@ namespace Emby.Server.Implementations.Localization
|
||||
{
|
||||
var countryCode = _configurationManager.Configuration.MetadataCountryCode;
|
||||
|
||||
// Fall back to US ratings if no country code is specified or country code does not exist.
|
||||
if (string.IsNullOrEmpty(countryCode))
|
||||
{
|
||||
countryCode = "us";
|
||||
@@ -205,15 +254,15 @@ namespace Emby.Server.Implementations.Localization
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ratings.
|
||||
/// Gets the ratings for a country.
|
||||
/// </summary>
|
||||
/// <param name="countryCode">The country code.</param>
|
||||
/// <returns>The ratings.</returns>
|
||||
private Dictionary<string, ParentalRating>? GetRatings(string countryCode)
|
||||
{
|
||||
_allParentalRatings.TryGetValue(countryCode, out var value);
|
||||
_allParentalRatings.TryGetValue(countryCode, out var countryValue);
|
||||
|
||||
return value;
|
||||
return countryValue;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -221,12 +270,14 @@ namespace Emby.Server.Implementations.Localization
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(rating);
|
||||
|
||||
// Handle unrated content
|
||||
if (_unratedValues.Contains(rating.AsSpan(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fairly common for some users to have "Rated R" in their rating field
|
||||
rating = rating.Replace("Rated :", string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||
rating = rating.Replace("Rated ", string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
var ratingsDictionary = GetParentalRatingsDictionary();
|
||||
@@ -246,18 +297,17 @@ namespace Emby.Server.Implementations.Localization
|
||||
}
|
||||
|
||||
// Try splitting by : to handle "Germany: FSK 18"
|
||||
var index = rating.IndexOf(':', StringComparison.Ordinal);
|
||||
if (index != -1)
|
||||
if (rating.Contains(':', StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var trimmedRating = rating.AsSpan(index).TrimStart(':').Trim();
|
||||
|
||||
if (!trimmedRating.IsEmpty)
|
||||
{
|
||||
return GetRatingLevel(trimmedRating.ToString());
|
||||
}
|
||||
return GetRatingLevel(rating.AsSpan().RightPart(':').ToString());
|
||||
}
|
||||
|
||||
// Remove prefix country code to handle "DE-18"
|
||||
if (rating.Contains('-', StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return GetRatingLevel(rating.AsSpan().RightPart('-').ToString());
|
||||
}
|
||||
|
||||
// TODO: Further improve by normalizing out all spaces and dashes
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
E,0
|
||||
EC,0
|
||||
T,7
|
||||
M,18
|
||||
AO,18
|
||||
UR,18
|
||||
RP,18
|
||||
X,1000
|
||||
XX,1000
|
||||
XXX,1000
|
||||
XXXX,1000
|
||||
|
@@ -1,7 +1,13 @@
|
||||
AU-G,1
|
||||
AU-PG,5
|
||||
AU-M,6
|
||||
AU-MA15+,7
|
||||
AU-R18+,9
|
||||
AU-X18+,10
|
||||
AU-RC,11
|
||||
Exempt,0
|
||||
G,0
|
||||
7+,7
|
||||
M,15
|
||||
MA,15
|
||||
MA15+,15
|
||||
PG,16
|
||||
16+,16
|
||||
R,18
|
||||
R18+,18
|
||||
X18+,18
|
||||
18+,18
|
||||
X,1000
|
||||
|
||||
|
@@ -1,6 +1,11 @@
|
||||
BE-AL,1
|
||||
BE-MG6,2
|
||||
BE-6,3
|
||||
BE-9,5
|
||||
BE-12,6
|
||||
BE-16,8
|
||||
AL,0
|
||||
KT,0
|
||||
TOUS,0
|
||||
MG6,6
|
||||
6,6
|
||||
9,9
|
||||
KNT,12
|
||||
12,12
|
||||
14,14
|
||||
16,16
|
||||
18,18
|
||||
|
||||
|
@@ -1,6 +1,8 @@
|
||||
BR-L,1
|
||||
BR-10,5
|
||||
BR-12,7
|
||||
BR-14,8
|
||||
BR-16,8
|
||||
BR-18,9
|
||||
Livre,0
|
||||
L,0
|
||||
ER,9
|
||||
10,10
|
||||
12,12
|
||||
14,14
|
||||
16,16
|
||||
18,18
|
||||
|
||||
|
@@ -1,6 +1,20 @@
|
||||
CA-G,1
|
||||
CA-PG,5
|
||||
CA-14A,7
|
||||
CA-A,8
|
||||
CA-18A,9
|
||||
CA-R,10
|
||||
E,0
|
||||
G,0
|
||||
TV-Y,0
|
||||
TV-G,0
|
||||
TV-Y7,7
|
||||
TV-Y7-FV,7
|
||||
PG,9
|
||||
TV-PG,9
|
||||
PG-13,13
|
||||
13+,13
|
||||
TV-14,14
|
||||
14A,14
|
||||
16+,16
|
||||
NC-17,17
|
||||
R,18
|
||||
TV-MA,18
|
||||
18A,18
|
||||
18+,18
|
||||
A,1000
|
||||
Prohibited,1001
|
||||
|
||||
|
@@ -1,8 +1,7 @@
|
||||
CO-T,1
|
||||
CO-7,5
|
||||
CO-12,7
|
||||
CO-15,8
|
||||
CO-18,10
|
||||
CO-X,100
|
||||
CO-BANNED,15
|
||||
CO-E,15
|
||||
T,0
|
||||
7,7
|
||||
12,12
|
||||
15,15
|
||||
18,18
|
||||
X,1000
|
||||
Prohibited,1001
|
||||
|
||||
|
@@ -1,10 +1,12 @@
|
||||
DE-0,1
|
||||
FSK-0,1
|
||||
DE-6,5
|
||||
FSK-6,5
|
||||
DE-12,7
|
||||
FSK-12,7
|
||||
DE-16,8
|
||||
FSK-16,8
|
||||
DE-18,9
|
||||
FSK-18,9
|
||||
Educational,0
|
||||
Infoprogramm,0
|
||||
FSK-0,0
|
||||
0,0
|
||||
FSK-6,6
|
||||
6,6
|
||||
FSK-12,12
|
||||
12,12
|
||||
FSK-16,16
|
||||
16,16
|
||||
FSK-18,18
|
||||
18,18
|
||||
|
||||
|
@@ -1,4 +1,7 @@
|
||||
DA-A,1
|
||||
DA-7,5
|
||||
DA-11,6
|
||||
DA-15,8
|
||||
F,0
|
||||
A,0
|
||||
7,7
|
||||
11,11
|
||||
12,12
|
||||
15,15
|
||||
16,16
|
||||
|
||||
|
@@ -1,6 +1,24 @@
|
||||
ES-A,1
|
||||
ES-APTA,1
|
||||
ES-7,3
|
||||
ES-12,6
|
||||
ES-16,8
|
||||
ES-18,11
|
||||
A,0
|
||||
A/fig,0
|
||||
A/i,0
|
||||
A/fig/i,0
|
||||
APTA,0
|
||||
TP,0
|
||||
0+,0
|
||||
6+,6
|
||||
7/fig,7
|
||||
7/i,7
|
||||
7/i/fig,7
|
||||
7,7
|
||||
9+,9
|
||||
10,10
|
||||
12,12
|
||||
12/fig,12
|
||||
13,13
|
||||
14,14
|
||||
16,16
|
||||
16/fig,16
|
||||
18,18
|
||||
18/fig,18
|
||||
X,1000
|
||||
Banned,1001
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
FI-S,1
|
||||
FI-T,1
|
||||
FI-7,4
|
||||
FI-12,5
|
||||
FI-16,8
|
||||
FI-18,9
|
||||
FI-K7,4
|
||||
FI-K12,5
|
||||
FI-K16,8
|
||||
FI-K18,9
|
||||
S,0
|
||||
T,0
|
||||
K7,7
|
||||
7,7
|
||||
K12,12
|
||||
12,12
|
||||
K16,16
|
||||
16,16
|
||||
K18,18
|
||||
18,18
|
||||
|
||||
|
@@ -1,5 +1,12 @@
|
||||
FR-U,1
|
||||
FR-10,5
|
||||
FR-12,7
|
||||
FR-16,9
|
||||
FR-18,10
|
||||
Public Averti,0
|
||||
Tous Publics,0
|
||||
U,0
|
||||
0+,0
|
||||
6+,6
|
||||
9+,9
|
||||
10,10
|
||||
12,12
|
||||
14+,14
|
||||
16,16
|
||||
18,18
|
||||
X,1000
|
||||
|
||||
|
@@ -1,7 +1,22 @@
|
||||
GB-U,1
|
||||
GB-PG,5
|
||||
GB-12,6
|
||||
GB-12A,7
|
||||
GB-15,8
|
||||
GB-18,9
|
||||
GB-R18,15
|
||||
All,0
|
||||
E,0
|
||||
G,0
|
||||
U,0
|
||||
0+,0
|
||||
6+,6
|
||||
7+,7
|
||||
PG,8
|
||||
9+,9
|
||||
12,12
|
||||
12+,12
|
||||
12A,12
|
||||
Teen,13
|
||||
13+,13
|
||||
14+,14
|
||||
15,15
|
||||
16,16
|
||||
Caution,18
|
||||
18,18
|
||||
Mature,1000
|
||||
Adult,1000
|
||||
R18,1000
|
||||
|
||||
|
@@ -1,6 +1,9 @@
|
||||
IE-G,1
|
||||
IE-PG,5
|
||||
IE-12A,7
|
||||
IE-15A,8
|
||||
IE-16,9
|
||||
IE-18,10
|
||||
G,4
|
||||
PG,12
|
||||
12,12
|
||||
12A,12
|
||||
12PG,12
|
||||
15,15
|
||||
15A,15
|
||||
16,16
|
||||
18,18
|
||||
|
||||
|
@@ -1,4 +1,11 @@
|
||||
JP-G,1
|
||||
JP-PG12,7
|
||||
JP-15+,8
|
||||
JP-18+,10
|
||||
A,0
|
||||
G,0
|
||||
B,12
|
||||
PG12,12
|
||||
C,15
|
||||
15+,15
|
||||
R15+,15
|
||||
16+,16
|
||||
D,17
|
||||
Z,18
|
||||
18+,18
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
KZ-6-,0
|
||||
KZ-6+,6
|
||||
KZ-12+,12
|
||||
KZ-14+,14
|
||||
KZ-16+,16
|
||||
KZ-18+,18
|
||||
KZ-21+,21
|
||||
K,0
|
||||
БА,12
|
||||
Б14,14
|
||||
E16,16
|
||||
E18,18
|
||||
HA,18
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
MX-AA,1
|
||||
MX-A,5
|
||||
MX-B,7
|
||||
MX-B-15,8
|
||||
MX-C,9
|
||||
MX-D,10
|
||||
A,0
|
||||
AA,0
|
||||
B,12
|
||||
B-15,15
|
||||
C,18
|
||||
D,1000
|
||||
|
||||
|
@@ -1,6 +1,8 @@
|
||||
NL-AL,1
|
||||
NL-MG6,2
|
||||
NL-6,3
|
||||
NL-9,5
|
||||
NL-12,6
|
||||
NL-16,8
|
||||
AL,0
|
||||
MG6,6
|
||||
6,6
|
||||
9,9
|
||||
12,12
|
||||
14,14
|
||||
16,16
|
||||
18,18
|
||||
|
||||
|
@@ -1,6 +1,9 @@
|
||||
NO-A,1
|
||||
NO-6,3
|
||||
NO-9,4
|
||||
NO-12,5
|
||||
NO-15,8
|
||||
NO-18,9
|
||||
A,0
|
||||
6,6
|
||||
7,7
|
||||
9,9
|
||||
11,11
|
||||
12,12
|
||||
15,15
|
||||
18,18
|
||||
Not approved,1001
|
||||
|
||||
|
@@ -1,11 +1,15 @@
|
||||
NZ-G,1
|
||||
NZ-PG,5
|
||||
NZ-M,6
|
||||
NZ-R13,7
|
||||
NZ-RP13,7
|
||||
NZ-R15,8
|
||||
NZ-RP16,9
|
||||
NZ-R16,9
|
||||
NZ-R18,10
|
||||
NZ-R,10
|
||||
NZ-MA,10
|
||||
Exempt,0
|
||||
G,0
|
||||
GY,13
|
||||
PG,13
|
||||
R13,13
|
||||
RP13,13
|
||||
R15,15
|
||||
M,16
|
||||
R16,16
|
||||
RP16,16
|
||||
GA,18
|
||||
R18,18
|
||||
MA,1000
|
||||
R,1001
|
||||
Objectionable,1001
|
||||
|
||||
|
@@ -1 +1,6 @@
|
||||
RO-AG,1
|
||||
AG,0
|
||||
AP-12,12
|
||||
N-15,15
|
||||
IM-18,18
|
||||
IM-18-XXX,1000
|
||||
IC,1001
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
RU-0+,1
|
||||
RU-6+,3
|
||||
RU-12+,7
|
||||
RU-16+,9
|
||||
RU-18+,10
|
||||
0+,0
|
||||
6+,6
|
||||
12+,12
|
||||
16+,16
|
||||
18+,18
|
||||
Refused classification,1001
|
||||
|
||||
|
@@ -1,5 +1,10 @@
|
||||
SE-Btl,1
|
||||
SE-Barntillåten,1
|
||||
SE-7,3
|
||||
SE-11,5
|
||||
SE-15,8
|
||||
Alla,0
|
||||
Barntillåten,0
|
||||
Btl,0
|
||||
0+,0
|
||||
7,7
|
||||
9+,9
|
||||
10+,10
|
||||
11,11
|
||||
14,14
|
||||
15,15
|
||||
|
||||
|
@@ -1,7 +1,22 @@
|
||||
UK-U,1
|
||||
UK-PG,5
|
||||
UK-12,7
|
||||
UK-12A,7
|
||||
UK-15,9
|
||||
UK-18,10
|
||||
UK-R18,15
|
||||
All,0
|
||||
E,0
|
||||
G,0
|
||||
U,0
|
||||
0+,0
|
||||
6+,6
|
||||
7+,7
|
||||
PG,8
|
||||
9+,9
|
||||
12,12
|
||||
12+,12
|
||||
12A,12
|
||||
Teen,13
|
||||
13+,13
|
||||
14+,14
|
||||
15,15
|
||||
16,16
|
||||
Caution,18
|
||||
18,18
|
||||
Mature,1000
|
||||
Adult,1000
|
||||
R18,1000
|
||||
|
||||
|
@@ -1,23 +1,50 @@
|
||||
TV-Y,1
|
||||
APPROVED,1
|
||||
G,1
|
||||
E,1
|
||||
EC,1
|
||||
TV-G,1
|
||||
TV-Y7,3
|
||||
TV-Y7-FV,4
|
||||
PG,5
|
||||
TV-PG,5
|
||||
PG-13,7
|
||||
T,7
|
||||
TV-14,8
|
||||
R,9
|
||||
M,9
|
||||
TV-MA,9
|
||||
NC-17,10
|
||||
AO,15
|
||||
RP,15
|
||||
UR,15
|
||||
NR,15
|
||||
X,15
|
||||
XXX,100
|
||||
Approved,0
|
||||
G,0
|
||||
TV-G,0
|
||||
TV-Y,0
|
||||
TV-Y7,7
|
||||
TV-Y7-FV,7
|
||||
PG,10
|
||||
PG-13,13
|
||||
TV-PG,13
|
||||
TV-PG-D,13
|
||||
TV-PG-L,13
|
||||
TV-PG-S,13
|
||||
TV-PG-V,13
|
||||
TV-PG-DL,13
|
||||
TV-PG-DS,13
|
||||
TV-PG-DV,13
|
||||
TV-PG-LS,13
|
||||
TV-PG-LV,13
|
||||
TV-PG-SV,13
|
||||
TV-PG-DLS,13
|
||||
TV-PG-DLV,13
|
||||
TV-PG-DSV,13
|
||||
TV-PG-LSV,13
|
||||
TV-PG-DLSV,13
|
||||
TV-14,14
|
||||
TV-14-D,14
|
||||
TV-14-L,14
|
||||
TV-14-S,14
|
||||
TV-14-V,14
|
||||
TV-14-DL,14
|
||||
TV-14-DS,14
|
||||
TV-14-DV,14
|
||||
TV-14-LS,14
|
||||
TV-14-LV,14
|
||||
TV-14-SV,14
|
||||
TV-14-DLS,14
|
||||
TV-14-DLV,14
|
||||
TV-14-DSV,14
|
||||
TV-14-LSV,14
|
||||
TV-14-DLSV,14
|
||||
NC-17,17
|
||||
R,17
|
||||
TV-MA,17
|
||||
TV-MA-L,17
|
||||
TV-MA-S,17
|
||||
TV-MA-V,17
|
||||
TV-MA-LS,17
|
||||
TV-MA-LV,17
|
||||
TV-MA-SV,17
|
||||
TV-MA-LSV,17
|
||||
|
||||
|
@@ -93,11 +93,8 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, ILogger logger)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(scheduledTask);
|
||||
|
||||
ArgumentNullException.ThrowIfNull(applicationPaths);
|
||||
|
||||
ArgumentNullException.ThrowIfNull(taskManager);
|
||||
|
||||
ArgumentNullException.ThrowIfNull(logger);
|
||||
|
||||
ScheduledTask = scheduledTask;
|
||||
@@ -332,7 +329,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation("{0} fired for task: {1}", trigger.GetType().Name, Name);
|
||||
_logger.LogDebug("{0} fired for task: {1}", trigger.GetType().Name, Name);
|
||||
|
||||
trigger.Stop();
|
||||
|
||||
@@ -378,7 +375,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
|
||||
CurrentCancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
_logger.LogInformation("Executing {0}", Name);
|
||||
_logger.LogDebug("Executing {0}", Name);
|
||||
|
||||
((TaskManager)_taskManager).OnTaskExecuting(this);
|
||||
|
||||
@@ -406,7 +403,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error");
|
||||
_logger.LogError(ex, "Error executing Scheduled Task");
|
||||
|
||||
failureException = ex;
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
{
|
||||
var type = scheduledTask.ScheduledTask.GetType();
|
||||
|
||||
_logger.LogInformation("Queuing task {0}", type.Name);
|
||||
_logger.LogDebug("Queuing task {0}", type.Name);
|
||||
|
||||
lock (_taskQueue)
|
||||
{
|
||||
@@ -172,7 +172,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
{
|
||||
var type = task.ScheduledTask.GetType();
|
||||
|
||||
_logger.LogInformation("Queuing task {0}", type.Name);
|
||||
_logger.LogDebug("Queuing task {0}", type.Name);
|
||||
|
||||
lock (_taskQueue)
|
||||
{
|
||||
@@ -254,9 +254,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
/// </summary>
|
||||
private void ExecuteQueuedTasks()
|
||||
{
|
||||
_logger.LogInformation("ExecuteQueuedTasks");
|
||||
|
||||
// Execute queued tasks
|
||||
lock (_taskQueue)
|
||||
{
|
||||
var list = new List<Tuple<Type, TaskOptions>>();
|
||||
|
||||
Reference in New Issue
Block a user