aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server
diff options
context:
space:
mode:
authorJPVenson <github@jpb.email>2024-11-19 20:53:38 +0000
committerJPVenson <github@jpb.email>2024-11-19 20:53:38 +0000
commit0dd6dacc4f40a9530b359b3e389f0851e57983e0 (patch)
treea3fdf7611c2e09ba62bab0f28484a9ba5876a78d /Jellyfin.Server
parent136a7995f7d9bb3c85b22cffadfd17030300bc2a (diff)
parent06c603428bceccdb793eb34cc0340e25552d6c1d (diff)
Merge remote-tracking branch 'origin/master' into feature/EFUserData
Diffstat (limited to 'Jellyfin.Server')
-rw-r--r--Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs20
-rw-r--r--Jellyfin.Server/Migrations/MigrationRunner.cs1
-rw-r--r--Jellyfin.Server/Migrations/Routines/FixPlaylistOwner.cs4
-rw-r--r--Jellyfin.Server/Migrations/Routines/RemoveDuplicatePlaylistChildren.cs69
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);
+ }
+ }
+ }
+ }
+}