Compare commits

..

1 Commits

Author SHA1 Message Date
renovate[bot]
25cd24811c Update dependency SharpCompress to 0.49.1 2026-06-11 23:57:25 +00:00
9 changed files with 38 additions and 145 deletions

View File

@@ -90,7 +90,6 @@
- [mark-monteiro](https://github.com/mark-monteiro)
- [MarkCiliaVincenti](https://github.com/MarkCiliaVincenti)
- [Martin Reuter](https://github.com/reuterma24)
- [Matt Teahan](https://github.com/matt-teahan)
- [Matt07211](https://github.com/Matt07211)
- [Matthew Jones](https://github.com/matthew-jones-uk)
- [Maxr1998](https://github.com/Maxr1998)

View File

@@ -26,27 +26,27 @@
<PackageVersion Include="libse" Version="4.0.12" />
<PackageVersion Include="LrcParser" Version="2025.623.0" />
<PackageVersion Include="MetaBrainz.MusicBrainz" Version="8.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.8" />
<PackageVersion Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="4.14.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="5.3.0" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.9" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.9" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.9" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.9" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.9" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.8" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.6.0" />
<PackageVersion Include="MimeTypes" Version="2.5.2" />
<PackageVersion Include="Morestachio" Version="5.0.1.670" />
@@ -57,17 +57,17 @@
<PackageVersion Include="prometheus-net.AspNetCore" Version="8.2.1" />
<PackageVersion Include="prometheus-net.DotNetRuntime" Version="4.4.1" />
<PackageVersion Include="prometheus-net" Version="8.2.1" />
<PackageVersion Include="Polly" Version="8.7.0" />
<PackageVersion Include="Polly" Version="8.6.6" />
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="Serilog.Enrichers.Thread" Version="4.0.0" />
<PackageVersion Include="Serilog.Expressions" Version="5.0.0" />
<PackageVersion Include="Serilog.Settings.Configuration" Version="10.0.1" />
<PackageVersion Include="Serilog.Settings.Configuration" Version="10.0.0" />
<PackageVersion Include="Serilog.Sinks.Async" Version="2.1.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageVersion Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageVersion Include="Serilog.Sinks.Graylog" Version="3.1.1" />
<PackageVersion Include="SerilogAnalyzer" Version="0.15.0" />
<PackageVersion Include="SharpCompress" Version="0.38.0" />
<PackageVersion Include="SharpCompress" Version="0.49.1" />
<PackageVersion Include="SharpFuzz" Version="2.2.0" />
<PackageVersion Include="SkiaSharp" Version="3.119.4" />
<PackageVersion Include="SkiaSharp.HarfBuzz" Version="3.119.4" />
@@ -75,9 +75,9 @@
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<PackageVersion Include="Svg.Skia" Version="3.7.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="10.2.1" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.2.1" />
<PackageVersion Include="System.Text.Json" Version="10.0.9" />
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="10.2.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.2.0" />
<PackageVersion Include="System.Text.Json" Version="10.0.8" />
<PackageVersion Include="TagLibSharp" Version="2.3.0" />
<PackageVersion Include="z440.atl.core" Version="7.15.3" />
<PackageVersion Include="TMDbLib" Version="3.0.0" />

View File

@@ -106,7 +106,5 @@
"TaskMoveTrickplayImagesDescription": "Mueve archivos existentes de trickplay de acuerdo a la configuración de la biblioteca.",
"TaskMoveTrickplayImages": "Migrar Ubicación de Imagen de Trickplay",
"CleanupUserDataTaskDescription": "Limpia todos los datos del usuario (estado de visualización, estado de los favoritos, etc.) que no están presentes en la biblioteca por al menos 90 días.",
"CleanupUserDataTask": "Tarea de limpieza de datos de usuarios",
"LyricDownloadFailureFromForItem": "No se pudo descargar la letra desde {0} para {1}",
"Original": "Original"
"CleanupUserDataTask": "Tarea de limpieza de datos de usuarios"
}

View File

@@ -586,7 +586,8 @@ public sealed partial class BaseItemRepository
if (filter.AlbumIds.Length > 0)
{
baseQuery = baseQuery.Where(e => e.ParentId.HasValue && filter.AlbumIds.Contains(e.ParentId.Value));
var subQuery = context.BaseItems.WhereOneOrMany(filter.AlbumIds, f => f.Id);
baseQuery = baseQuery.Where(e => subQuery.Any(f => f.Name == e.Album));
}
if (filter.ExcludeArtistIds.Length > 0)

View File

@@ -12,22 +12,22 @@ using Microsoft.Extensions.Logging;
namespace Jellyfin.Server.Migrations.Routines;
/// <summary>
/// Migration to refresh CleanName values for all library items and CleanValue values for all item values.
/// Migration to refresh CleanName values for all library items.
/// </summary>
[JellyfinMigration("2026-06-10T12:00:00", nameof(RefreshCleanNamesAndValues))]
[JellyfinMigration("2025-10-08T12:00:00", nameof(RefreshCleanNames))]
[JellyfinMigrationBackup(JellyfinDb = true)]
public class RefreshCleanNamesAndValues : IAsyncMigrationRoutine
public class RefreshCleanNames : IAsyncMigrationRoutine
{
private readonly IStartupLogger<RefreshCleanNamesAndValues> _logger;
private readonly IStartupLogger<RefreshCleanNames> _logger;
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
/// <summary>
/// Initializes a new instance of the <see cref="RefreshCleanNamesAndValues"/> class.
/// Initializes a new instance of the <see cref="RefreshCleanNames"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="dbProvider">Instance of the <see cref="IDbContextFactory{JellyfinDbContext}"/> interface.</param>
public RefreshCleanNamesAndValues(
IStartupLogger<RefreshCleanNamesAndValues> logger,
public RefreshCleanNames(
IStartupLogger<RefreshCleanNames> logger,
IDbContextFactory<JellyfinDbContext> dbProvider)
{
_logger = logger;
@@ -36,12 +36,6 @@ public class RefreshCleanNamesAndValues : IAsyncMigrationRoutine
/// <inheritdoc />
public async Task PerformAsync(CancellationToken cancellationToken)
{
await RefreshCleanNamesAsync(cancellationToken).ConfigureAwait(false);
await RefreshCleanValuesAsync(cancellationToken).ConfigureAwait(false);
}
private async Task RefreshCleanNamesAsync(CancellationToken cancellationToken)
{
const int Limit = 10000;
int itemCount = 0;
@@ -105,69 +99,4 @@ public class RefreshCleanNamesAndValues : IAsyncMigrationRoutine
records,
sw.Elapsed);
}
private async Task RefreshCleanValuesAsync(CancellationToken cancellationToken)
{
const int Limit = 10000;
int itemCount = 0;
var sw = Stopwatch.StartNew();
using var context = _dbProvider.CreateDbContext();
var records = context.ItemValues.Count(b => !string.IsNullOrEmpty(b.Value));
_logger.LogInformation("Refreshing CleanValue for {Count} item values", records);
var processedInPartition = 0;
await foreach (var item in context.ItemValues
.Where(b => !string.IsNullOrEmpty(b.Value))
.OrderBy(e => e.ItemValueId)
.WithPartitionProgress((partition) => _logger.LogInformation("Processed: {Offset}/{Total} - Updated: {UpdatedCount} - Time: {Elapsed}", partition * Limit, records, itemCount, sw.Elapsed))
.PartitionEagerAsync(Limit, cancellationToken)
.WithCancellation(cancellationToken)
.ConfigureAwait(false))
{
try
{
var newCleanValue = string.IsNullOrWhiteSpace(item.Value) ? string.Empty : item.Value.GetCleanValue();
if (!string.Equals(newCleanValue, item.CleanValue, StringComparison.Ordinal))
{
_logger.LogDebug(
"Updating CleanValue for item value {Id}: '{OldValue}' -> '{NewValue}'",
item.ItemValueId,
item.CleanValue,
newCleanValue);
item.CleanValue = newCleanValue;
itemCount++;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to update CleanValue for item value {Id} ({Value})", item.ItemValueId, item.Value);
}
processedInPartition++;
if (processedInPartition >= Limit)
{
await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
// Clear tracked entities to avoid memory growth across partitions
context.ChangeTracker.Clear();
processedInPartition = 0;
}
}
// Save any remaining changes after the loop
if (processedInPartition > 0)
{
await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
context.ChangeTracker.Clear();
}
_logger.LogInformation(
"Refreshed CleanValue for {UpdatedCount} out of {TotalCount} item values in {Time}",
itemCount,
records,
sw.Elapsed);
}
}

View File

@@ -76,13 +76,7 @@ namespace MediaBrowser.MediaEncoding.Probing
/// <returns>Dictionary{System.StringSystem.String}.</returns>
private static Dictionary<string, string?> ConvertDictionaryToCaseInsensitive(IReadOnlyDictionary<string, string?> dict)
{
var result = new Dictionary<string, string?>(dict.Count, StringComparer.OrdinalIgnoreCase);
foreach (var (key, value) in dict)
{
result.TryAdd(key, value);
}
return result;
return new Dictionary<string, string?>(dict, StringComparer.OrdinalIgnoreCase);
}
}
}

View File

@@ -142,9 +142,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
if (string.IsNullOrWhiteSpace(overview))
{
overview = string.IsNullOrWhiteSpace(result.strDescriptionEN)
? result.strDescription
: result.strDescriptionEN;
overview = result.strDescriptionEN;
}
item.Overview = (overview ?? string.Empty).StripHtml();
@@ -242,8 +240,6 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
public string strAlbumCDart { get; set; }
public string strDescription { get; set; }
public string strDescriptionEN { get; set; }
public string strDescriptionDE { get; set; }

View File

@@ -236,7 +236,6 @@ public class SeriesMetadataService : MetadataService<Series, SeriesInfo>
{
var seriesChildren = series.GetRecursiveChildren(i => i is Episode || i is Season);
var seasons = seriesChildren.OfType<Season>().ToList();
var episodes = seriesChildren.OfType<Episode>().ToList();
var physicalSeasonIds = seasons
.Where(e => e.LocationType != LocationType.Virtual)
@@ -262,12 +261,11 @@ public class SeriesMetadataService : MetadataService<Series, SeriesInfo>
if (existingSeason is null)
{
var seasonName = GetValidSeasonNameForSeries(series, null, seasonNumber);
var season = await CreateSeasonAsync(series, seasonName, seasonNumber, cancellationToken).ConfigureAwait(false);
seasons.Add(season);
await CreateSeasonAsync(series, seasonName, seasonNumber, cancellationToken).ConfigureAwait(false);
}
else if (existingSeason.IsVirtualItem)
{
var episodeCount = episodes.Count(e => e.ParentIndexNumber == seasonNumber && !e.IsMissingEpisode);
var episodeCount = seriesChildren.OfType<Episode>().Count(e => e.ParentIndexNumber == seasonNumber && !e.IsMissingEpisode);
if (episodeCount > 0)
{
existingSeason.IsVirtualItem = false;
@@ -275,21 +273,6 @@ public class SeriesMetadataService : MetadataService<Series, SeriesInfo>
}
}
}
// Loop through episodes
foreach (var episode in episodes)
{
var season = seasons.FirstOrDefault(i => i.IndexNumber == episode.ParentIndexNumber);
if (season is null || episode.SeasonId.Equals(season.Id))
{
continue;
}
// Assign the correct season id and name to episode.
episode.SeasonId = season.Id;
episode.SeasonName = season.Name;
await episode.UpdateToRepositoryAsync(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
}
}
/// <summary>
@@ -300,7 +283,7 @@ public class SeriesMetadataService : MetadataService<Series, SeriesInfo>
/// <param name="seasonNumber">The season number.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The newly created season.</returns>
private async Task<Season> CreateSeasonAsync(
private async Task CreateSeasonAsync(
Series series,
string? seasonName,
int? seasonNumber,
@@ -323,8 +306,6 @@ public class SeriesMetadataService : MetadataService<Series, SeriesInfo>
series.AddChild(season);
await season.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken).ConfigureAwait(false);
return season;
}
private string GetValidSeasonNameForSeries(Series series, string? seasonName, int? seasonNumber)

View File

@@ -12,7 +12,6 @@ using System.Threading.Tasks;
using Jellyfin.Extensions;
using Jellyfin.XmlTv;
using Jellyfin.XmlTv.Entities;
using Jellyfin.XmlTv.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
@@ -181,8 +180,6 @@ namespace Jellyfin.LiveTv.Listings
string? episodeTitle = program.Episode?.Title;
var programCategories = program.Categories.Where(c => !string.IsNullOrWhiteSpace(c)).ToList();
var imageUrl = program.Icons.FirstOrDefault()?.Source;
var episodeImageUrl = program.Images?.FirstOrDefault(m => m.Type == ImageType.Still)?.Path;
var backgroundImageUrl = program.Images?.FirstOrDefault(m => m.Type == ImageType.Backdrop)?.Path;
var rating = program.Ratings.FirstOrDefault()?.Value;
var starRating = program.StarRatings?.FirstOrDefault()?.StarRating;
@@ -208,8 +205,6 @@ namespace Jellyfin.LiveTv.Listings
IsSports = programCategories.Any(c => info.SportsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
ImageUrl = string.IsNullOrEmpty(imageUrl) ? null : imageUrl,
HasImage = !string.IsNullOrEmpty(imageUrl),
BackdropImageUrl = string.IsNullOrEmpty(backgroundImageUrl) ? null : backgroundImageUrl,
ThumbImageUrl = string.IsNullOrEmpty(episodeImageUrl) ? null : episodeImageUrl,
OfficialRating = string.IsNullOrEmpty(rating) ? null : rating,
CommunityRating = starRating is null ? null : (float)starRating.Value,
SeriesId = program.Episode?.Episode is null ? null : program.Title?.GetMD5().ToString("N", CultureInfo.InvariantCulture)