aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJPVenson <github@jpb.email>2025-02-19 18:25:00 +0000
committerJPVenson <github@jpb.email>2025-02-19 18:25:00 +0000
commitd8030147ffea8bd6b2753ac52e56b92fb15a1b47 (patch)
tree834693b6ccc31280a1a8bf28ac781e18a28ea1dc /src
parentddc20b74bf2eddd686c14c084260ca457011f8be (diff)
parent712908d53c7ca38d13e03ea7809e0c40e862a5fb (diff)
Merge remote-tracking branch 'jellyfinorigin/master' into feature/DatabaseRefactor
Diffstat (limited to 'src')
-rw-r--r--src/Jellyfin.Drawing/ImageProcessor.cs2
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedCollectionConverter.cs (renamed from src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedArrayConverter.cs)8
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedCollectionConverterFactory.cs (renamed from src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedArrayConverterFactory.cs)11
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonDelimitedCollectionConverter.cs (renamed from src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs)38
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedCollectionConverter.cs (renamed from src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedArrayConverter.cs)6
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedCollectionConverterFactory.cs (renamed from src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedArrayConverterFactory.cs)11
-rw-r--r--src/Jellyfin.LiveTv/Guide/GuideManager.cs108
7 files changed, 80 insertions, 104 deletions
diff --git a/src/Jellyfin.Drawing/ImageProcessor.cs b/src/Jellyfin.Drawing/ImageProcessor.cs
index 0bd3b8920..fcb315b3a 100644
--- a/src/Jellyfin.Drawing/ImageProcessor.cs
+++ b/src/Jellyfin.Drawing/ImageProcessor.cs
@@ -68,7 +68,7 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
var semaphoreCount = config.Configuration.ParallelImageEncodingLimit;
if (semaphoreCount < 1)
{
- semaphoreCount = 2 * Environment.ProcessorCount;
+ semaphoreCount = Environment.ProcessorCount;
}
_parallelEncodingLimit = new(semaphoreCount);
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedArrayConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedCollectionConverter.cs
index ccbc296fd..b1946143d 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedArrayConverter.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedCollectionConverter.cs
@@ -1,15 +1,15 @@
namespace Jellyfin.Extensions.Json.Converters
{
/// <summary>
- /// Convert comma delimited string to array of type.
+ /// Convert comma delimited string to collection of type.
/// </summary>
/// <typeparam name="T">Type to convert to.</typeparam>
- public sealed class JsonCommaDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
+ public sealed class JsonCommaDelimitedCollectionConverter<T> : JsonDelimitedCollectionConverter<T>
{
/// <summary>
- /// Initializes a new instance of the <see cref="JsonCommaDelimitedArrayConverter{T}"/> class.
+ /// Initializes a new instance of the <see cref="JsonCommaDelimitedCollectionConverter{T}"/> class.
/// </summary>
- public JsonCommaDelimitedArrayConverter() : base()
+ public JsonCommaDelimitedCollectionConverter() : base()
{
}
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedArrayConverterFactory.cs b/src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedCollectionConverterFactory.cs
index a95e493db..daa79b2b5 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedArrayConverterFactory.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonCommaDelimitedCollectionConverterFactory.cs
@@ -1,28 +1,31 @@
using System;
+using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Jellyfin.Extensions.Json.Converters
{
/// <summary>
- /// Json comma delimited array converter factory.
+ /// Json comma delimited collection converter factory.
/// </summary>
/// <remarks>
/// This must be applied as an attribute, adding to the JsonConverter list causes stack overflow.
/// </remarks>
- public class JsonCommaDelimitedArrayConverterFactory : JsonConverterFactory
+ public class JsonCommaDelimitedCollectionConverterFactory : JsonConverterFactory
{
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert)
{
- return true;
+ return typeToConvert.IsArray
+ || (typeToConvert.IsGenericType
+ && (typeToConvert.GetGenericTypeDefinition().IsAssignableFrom(typeof(IReadOnlyCollection<>)) || typeToConvert.GetGenericTypeDefinition().IsAssignableFrom(typeof(IReadOnlyList<>))));
}
/// <inheritdoc />
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
- return (JsonConverter?)Activator.CreateInstance(typeof(JsonCommaDelimitedArrayConverter<>).MakeGenericType(structType));
+ return (JsonConverter?)Activator.CreateInstance(typeof(JsonCommaDelimitedCollectionConverter<>).MakeGenericType(structType));
}
}
}
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedCollectionConverter.cs
index 7472f9c66..fe85d7f73 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedCollectionConverter.cs
@@ -10,14 +10,14 @@ namespace Jellyfin.Extensions.Json.Converters
/// Convert delimited string to array of type.
/// </summary>
/// <typeparam name="T">Type to convert to.</typeparam>
- public abstract class JsonDelimitedArrayConverter<T> : JsonConverter<T[]>
+ public abstract class JsonDelimitedCollectionConverter<T> : JsonConverter<IReadOnlyCollection<T>>
{
private readonly TypeConverter _typeConverter;
/// <summary>
- /// Initializes a new instance of the <see cref="JsonDelimitedArrayConverter{T}"/> class.
+ /// Initializes a new instance of the <see cref="JsonDelimitedCollectionConverter{T}"/> class.
/// </summary>
- protected JsonDelimitedArrayConverter()
+ protected JsonDelimitedCollectionConverter()
{
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
}
@@ -28,7 +28,7 @@ namespace Jellyfin.Extensions.Json.Converters
protected virtual char Delimiter { get; }
/// <inheritdoc />
- public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override IReadOnlyCollection<T>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
@@ -56,35 +56,21 @@ namespace Jellyfin.Extensions.Json.Converters
}
}
- return typedValues.ToArray();
+ if (typeToConvert.IsArray)
+ {
+ return typedValues.ToArray();
+ }
+
+ return typedValues;
}
return JsonSerializer.Deserialize<T[]>(ref reader, options);
}
/// <inheritdoc />
- public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, IReadOnlyCollection<T>? value, JsonSerializerOptions options)
{
- if (value is not null)
- {
- writer.WriteStartArray();
- if (value.Length > 0)
- {
- foreach (var it in value)
- {
- if (it is not null)
- {
- writer.WriteStringValue(it.ToString());
- }
- }
- }
-
- writer.WriteEndArray();
- }
- else
- {
- writer.WriteNullValue();
- }
+ JsonSerializer.Serialize(writer, value, options);
}
}
}
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedArrayConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedCollectionConverter.cs
index 55720ee4f..57378a360 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedArrayConverter.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedCollectionConverter.cs
@@ -4,12 +4,12 @@ namespace Jellyfin.Extensions.Json.Converters
/// Convert Pipe delimited string to array of type.
/// </summary>
/// <typeparam name="T">Type to convert to.</typeparam>
- public sealed class JsonPipeDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
+ public sealed class JsonPipeDelimitedCollectionConverter<T> : JsonDelimitedCollectionConverter<T>
{
/// <summary>
- /// Initializes a new instance of the <see cref="JsonPipeDelimitedArrayConverter{T}"/> class.
+ /// Initializes a new instance of the <see cref="JsonPipeDelimitedCollectionConverter{T}"/> class.
/// </summary>
- public JsonPipeDelimitedArrayConverter() : base()
+ public JsonPipeDelimitedCollectionConverter() : base()
{
}
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedArrayConverterFactory.cs b/src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedCollectionConverterFactory.cs
index ae9e1f67a..f487fcaca 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedArrayConverterFactory.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonPipeDelimitedCollectionConverterFactory.cs
@@ -1,28 +1,31 @@
using System;
+using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Jellyfin.Extensions.Json.Converters
{
/// <summary>
- /// Json Pipe delimited array converter factory.
+ /// Json Pipe delimited collection converter factory.
/// </summary>
/// <remarks>
/// This must be applied as an attribute, adding to the JsonConverter list causes stack overflow.
/// </remarks>
- public class JsonPipeDelimitedArrayConverterFactory : JsonConverterFactory
+ public class JsonPipeDelimitedCollectionConverterFactory : JsonConverterFactory
{
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert)
{
- return true;
+ return typeToConvert.IsArray
+ || (typeToConvert.IsGenericType
+ && (typeToConvert.GetGenericTypeDefinition().IsAssignableFrom(typeof(IReadOnlyCollection<>)) || typeToConvert.GetGenericTypeDefinition().IsAssignableFrom(typeof(IReadOnlyList<>))));
}
/// <inheritdoc />
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
- return (JsonConverter?)Activator.CreateInstance(typeof(JsonPipeDelimitedArrayConverter<>).MakeGenericType(structType));
+ return (JsonConverter?)Activator.CreateInstance(typeof(JsonPipeDelimitedCollectionConverter<>).MakeGenericType(structType));
}
}
}
diff --git a/src/Jellyfin.LiveTv/Guide/GuideManager.cs b/src/Jellyfin.LiveTv/Guide/GuideManager.cs
index b75cc0fb2..ac59a6d12 100644
--- a/src/Jellyfin.LiveTv/Guide/GuideManager.cs
+++ b/src/Jellyfin.LiveTv/Guide/GuideManager.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using Jellyfin.Data.Entities.Libraries;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using Jellyfin.LiveTv.Configuration;
@@ -210,7 +209,7 @@ public class GuideManager : IGuideManager
progress.Report(15);
numComplete = 0;
- var programs = new List<LiveTvProgram>();
+ var programIds = new List<Guid>();
var channels = new List<Guid>();
var guideDays = GetGuideDays();
@@ -243,8 +242,8 @@ public class GuideManager : IGuideManager
DtoOptions = new DtoOptions(true)
}).Cast<LiveTvProgram>().ToDictionary(i => i.Id);
- var newPrograms = new List<Guid>();
- var updatedPrograms = new List<Guid>();
+ var newPrograms = new List<LiveTvProgram>();
+ var updatedPrograms = new List<LiveTvProgram>();
foreach (var program in channelPrograms)
{
@@ -252,14 +251,14 @@ public class GuideManager : IGuideManager
var id = programItem.Id;
if (isNew)
{
- newPrograms.Add(id);
+ newPrograms.Add(programItem);
}
else if (isUpdated)
{
- updatedPrograms.Add(id);
+ updatedPrograms.Add(programItem);
}
- programs.Add(programItem);
+ programIds.Add(programItem.Id);
isMovie |= program.IsMovie;
isSeries |= program.IsSeries;
@@ -276,21 +275,21 @@ public class GuideManager : IGuideManager
if (newPrograms.Count > 0)
{
- var newProgramDtos = programs.Where(b => newPrograms.Contains(b.Id)).ToList();
- _libraryManager.CreateOrUpdateItems(newProgramDtos, null, cancellationToken);
+ _libraryManager.CreateItems(newPrograms, currentChannel, cancellationToken);
+
+ await PreCacheImages(newPrograms, maxCacheDate).ConfigureAwait(false);
}
if (updatedPrograms.Count > 0)
{
- var updatedProgramDtos = programs.Where(b => updatedPrograms.Contains(b.Id)).ToList();
await _libraryManager.UpdateItemsAsync(
- updatedProgramDtos,
+ updatedPrograms,
currentChannel,
ItemUpdateType.MetadataImport,
cancellationToken).ConfigureAwait(false);
- }
- await PreCacheImages(programs, maxCacheDate).ConfigureAwait(false);
+ await PreCacheImages(updatedPrograms, maxCacheDate).ConfigureAwait(false);
+ }
currentChannel.IsMovie = isMovie;
currentChannel.IsNews = isNews;
@@ -326,7 +325,6 @@ public class GuideManager : IGuideManager
}
progress.Report(100);
- var programIds = programs.Select(p => p.Id).ToList();
return new Tuple<List<Guid>, List<Guid>>(channels, programIds);
}
@@ -502,35 +500,27 @@ public class GuideManager : IGuideManager
forceUpdate = true;
}
- var seriesId = info.SeriesId;
-
- if (!item.ParentId.Equals(channel.Id))
+ var channelId = channel.Id;
+ if (!item.ParentId.Equals(channelId))
{
+ item.ParentId = channel.Id;
forceUpdate = true;
}
- item.ParentId = channel.Id;
-
item.Audio = info.Audio;
- item.ChannelId = channel.Id;
- item.CommunityRating ??= info.CommunityRating;
- if ((item.CommunityRating ?? 0).Equals(0))
- {
- item.CommunityRating = null;
- }
-
+ item.ChannelId = channelId;
+ item.CommunityRating = info.CommunityRating;
item.EpisodeTitle = info.EpisodeTitle;
item.ExternalId = info.Id;
- if (!string.IsNullOrWhiteSpace(seriesId) && !string.Equals(item.ExternalSeriesId, seriesId, StringComparison.Ordinal))
+ var seriesId = info.SeriesId;
+ if (!string.IsNullOrWhiteSpace(seriesId) && !string.Equals(item.ExternalSeriesId, seriesId, StringComparison.OrdinalIgnoreCase))
{
+ item.ExternalSeriesId = seriesId;
forceUpdate = true;
}
- item.ExternalSeriesId = seriesId;
-
var isSeries = info.IsSeries || !string.IsNullOrEmpty(info.EpisodeTitle);
-
if (isSeries || !string.IsNullOrEmpty(info.EpisodeTitle))
{
item.SeriesName = info.Name;
@@ -578,7 +568,6 @@ public class GuideManager : IGuideManager
}
item.Tags = tags.ToArray();
-
item.Genres = info.Genres.ToArray();
if (info.IsHD ?? false)
@@ -589,41 +578,35 @@ public class GuideManager : IGuideManager
item.IsMovie = info.IsMovie;
item.IsRepeat = info.IsRepeat;
-
if (item.IsSeries != isSeries)
{
+ item.IsSeries = isSeries;
forceUpdate = true;
}
- item.IsSeries = isSeries;
-
item.Name = info.Name;
- item.OfficialRating ??= info.OfficialRating;
- item.Overview ??= info.Overview;
+ item.OfficialRating = info.OfficialRating;
+ item.Overview = info.Overview;
item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks;
- item.ProviderIds = info.ProviderIds;
-
foreach (var providerId in info.SeriesProviderIds)
{
info.ProviderIds["Series" + providerId.Key] = providerId.Value;
}
+ item.ProviderIds = info.ProviderIds;
if (item.StartDate != info.StartDate)
{
+ item.StartDate = info.StartDate;
forceUpdate = true;
}
- item.StartDate = info.StartDate;
-
if (item.EndDate != info.EndDate)
{
+ item.EndDate = info.EndDate;
forceUpdate = true;
}
- item.EndDate = info.EndDate;
-
item.ProductionYear = info.ProductionYear;
-
if (!isSeries || info.IsRepeat)
{
item.PremiereDate = info.OriginalAirDate;
@@ -632,37 +615,35 @@ public class GuideManager : IGuideManager
item.IndexNumber = info.EpisodeNumber;
item.ParentIndexNumber = info.SeasonNumber;
- forceUpdate = forceUpdate || UpdateImages(item, info);
+ forceUpdate |= UpdateImages(item, info);
if (isNew)
{
item.OnMetadataChanged();
- return (item, isNew, false);
+ return (item, true, false);
}
- var isUpdated = false;
- if (forceUpdate || string.IsNullOrWhiteSpace(info.Etag))
+ var isUpdated = forceUpdate;
+ var etag = info.Etag;
+ if (string.IsNullOrWhiteSpace(etag))
{
isUpdated = true;
}
- else
+ else if (!string.Equals(etag, item.GetProviderId(EtagKey), StringComparison.OrdinalIgnoreCase))
{
- var etag = info.Etag;
-
- if (!string.Equals(etag, item.GetProviderId(EtagKey), StringComparison.OrdinalIgnoreCase))
- {
- item.SetProviderId(EtagKey, etag);
- isUpdated = true;
- }
+ item.SetProviderId(EtagKey, etag);
+ isUpdated = true;
}
if (isUpdated)
{
item.OnMetadataChanged();
+
+ return (item, false, true);
}
- return (item, isNew, isUpdated);
+ return (item, false, false);
}
private static bool UpdateImages(BaseItem item, ProgramInfo info)
@@ -679,7 +660,9 @@ public class GuideManager : IGuideManager
updated |= UpdateImage(ImageType.Logo, item, info);
// Backdrop
- return updated || UpdateImage(ImageType.Backdrop, item, info);
+ updated |= UpdateImage(ImageType.Backdrop, item, info);
+
+ return updated;
}
private static bool UpdateImage(ImageType imageType, BaseItem item, ProgramInfo info)
@@ -689,7 +672,7 @@ public class GuideManager : IGuideManager
var newImagePath = imageType switch
{
ImageType.Primary => info.ImagePath,
- _ => string.Empty
+ _ => null
};
var newImageUrl = imageType switch
{
@@ -697,12 +680,12 @@ public class GuideManager : IGuideManager
ImageType.Logo => info.LogoImageUrl,
ImageType.Primary => info.ImageUrl,
ImageType.Thumb => info.ThumbImageUrl,
- _ => string.Empty
+ _ => null
};
- var differentImage = newImageUrl?.Equals(currentImagePath, StringComparison.OrdinalIgnoreCase) == false
- || newImagePath?.Equals(currentImagePath, StringComparison.OrdinalIgnoreCase) == false;
- if (!differentImage)
+ var sameImage = (currentImagePath?.Equals(newImageUrl, StringComparison.OrdinalIgnoreCase) ?? false)
+ || (currentImagePath?.Equals(newImagePath, StringComparison.OrdinalIgnoreCase) ?? false);
+ if (sameImage)
{
return false;
}
@@ -757,6 +740,7 @@ public class GuideManager : IGuideManager
var imageInfo = program.ImageInfos[i];
if (!imageInfo.IsLocalFile)
{
+ _logger.LogDebug("Caching image locally: {Url}", imageInfo.Path);
try
{
program.ImageInfos[i] = await _libraryManager.ConvertImageToLocal(