diff options
| author | JPVenson <github@jpb.email> | 2024-11-19 20:53:38 +0000 |
|---|---|---|
| committer | JPVenson <github@jpb.email> | 2024-11-19 20:53:38 +0000 |
| commit | 0dd6dacc4f40a9530b359b3e389f0851e57983e0 (patch) | |
| tree | a3fdf7611c2e09ba62bab0f28484a9ba5876a78d /Jellyfin.Server | |
| parent | 136a7995f7d9bb3c85b22cffadfd17030300bc2a (diff) | |
| parent | 06c603428bceccdb793eb34cc0340e25552d6c1d (diff) | |
Merge remote-tracking branch 'origin/master' into feature/EFUserData
Diffstat (limited to 'Jellyfin.Server')
4 files changed, 87 insertions, 7 deletions
diff --git a/Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs b/Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs index 801026c54..901ed55be 100644 --- a/Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs +++ b/Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs @@ -101,7 +101,7 @@ namespace Jellyfin.Server.Infrastructure count: null); } - private async Task SendFileAsync(string filePath, HttpResponse response, long offset, long? count) + private async Task SendFileAsync(string filePath, HttpResponse response, long offset, long? count, CancellationToken cancellationToken = default) { var fileInfo = GetFileInfo(filePath); if (offset < 0 || offset > fileInfo.Length) @@ -118,6 +118,9 @@ namespace Jellyfin.Server.Infrastructure // Copied from SendFileFallback.SendFileAsync const int BufferSize = 1024 * 16; + var useRequestAborted = !cancellationToken.CanBeCanceled; + var localCancel = useRequestAborted ? response.HttpContext.RequestAborted : cancellationToken; + var fileStream = new FileStream( filePath, FileMode.Open, @@ -127,10 +130,17 @@ namespace Jellyfin.Server.Infrastructure options: FileOptions.Asynchronous | FileOptions.SequentialScan); await using (fileStream.ConfigureAwait(false)) { - fileStream.Seek(offset, SeekOrigin.Begin); - await StreamCopyOperation - .CopyToAsync(fileStream, response.Body, count, BufferSize, CancellationToken.None) - .ConfigureAwait(true); + try + { + localCancel.ThrowIfCancellationRequested(); + fileStream.Seek(offset, SeekOrigin.Begin); + await StreamCopyOperation + .CopyToAsync(fileStream, response.Body, count, BufferSize, localCancel) + .ConfigureAwait(true); + } + catch (OperationCanceledException) when (useRequestAborted) + { + } } } diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index 0459436b1..fa799ae6e 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -48,6 +48,7 @@ namespace Jellyfin.Server.Migrations typeof(Routines.UpdateDefaultPluginRepository), typeof(Routines.FixAudioData), typeof(Routines.MoveTrickplayFiles), + typeof(Routines.RemoveDuplicatePlaylistChildren), typeof(Routines.MigrateLibraryDb), }; diff --git a/Jellyfin.Server/Migrations/Routines/FixPlaylistOwner.cs b/Jellyfin.Server/Migrations/Routines/FixPlaylistOwner.cs index 3655a610d..192c170b2 100644 --- a/Jellyfin.Server/Migrations/Routines/FixPlaylistOwner.cs +++ b/Jellyfin.Server/Migrations/Routines/FixPlaylistOwner.cs @@ -15,12 +15,12 @@ namespace Jellyfin.Server.Migrations.Routines; /// </summary> internal class FixPlaylistOwner : IMigrationRoutine { - private readonly ILogger<RemoveDuplicateExtras> _logger; + private readonly ILogger<FixPlaylistOwner> _logger; private readonly ILibraryManager _libraryManager; private readonly IPlaylistManager _playlistManager; public FixPlaylistOwner( - ILogger<RemoveDuplicateExtras> logger, + ILogger<FixPlaylistOwner> logger, ILibraryManager libraryManager, IPlaylistManager playlistManager) { diff --git a/Jellyfin.Server/Migrations/Routines/RemoveDuplicatePlaylistChildren.cs b/Jellyfin.Server/Migrations/Routines/RemoveDuplicatePlaylistChildren.cs new file mode 100644 index 000000000..f84bccc25 --- /dev/null +++ b/Jellyfin.Server/Migrations/Routines/RemoveDuplicatePlaylistChildren.cs @@ -0,0 +1,69 @@ +using System; +using System.Linq; +using System.Threading; + +using Jellyfin.Data.Enums; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Playlists; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Migrations.Routines; + +/// <summary> +/// Remove duplicate playlist entries. +/// </summary> +internal class RemoveDuplicatePlaylistChildren : IMigrationRoutine +{ + private readonly ILogger<RemoveDuplicatePlaylistChildren> _logger; + private readonly ILibraryManager _libraryManager; + private readonly IPlaylistManager _playlistManager; + + public RemoveDuplicatePlaylistChildren( + ILogger<RemoveDuplicatePlaylistChildren> logger, + ILibraryManager libraryManager, + IPlaylistManager playlistManager) + { + _logger = logger; + _libraryManager = libraryManager; + _playlistManager = playlistManager; + } + + /// <inheritdoc/> + public Guid Id => Guid.Parse("{96C156A2-7A13-4B3B-A8B8-FB80C94D20C0}"); + + /// <inheritdoc/> + public string Name => "RemoveDuplicatePlaylistChildren"; + + /// <inheritdoc/> + public bool PerformOnNewInstall => false; + + /// <inheritdoc/> + public void Perform() + { + var playlists = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Playlist] + }) + .Cast<Playlist>() + .Where(p => !p.OpenAccess || !p.OwnerUserId.Equals(Guid.Empty)) + .ToArray(); + + if (playlists.Length > 0) + { + foreach (var playlist in playlists) + { + var linkedChildren = playlist.LinkedChildren; + if (linkedChildren.Length > 0) + { + var nullItemChildren = linkedChildren.Where(c => c.ItemId is null); + var deduplicatedChildren = linkedChildren.DistinctBy(c => c.ItemId); + var newLinkedChildren = nullItemChildren.Concat(deduplicatedChildren); + playlist.LinkedChildren = linkedChildren; + playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).GetAwaiter().GetResult(); + _playlistManager.SavePlaylistFile(playlist); + } + } + } + } +} |
