mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-15 12:10:47 +01:00
Compare commits
1 Commits
renovate/s
...
renovate/s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25cd24811c |
@@ -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)
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user