Browse Source

Remove chapters on file change (#14984)

Tim Eisele 6 days ago
parent
commit
5c519270b8

+ 2 - 17
Emby.Server.Implementations/Chapters/ChapterManager.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Globalization;
 using System.IO;
 using System.Linq;
 using System.Threading;
@@ -251,23 +250,9 @@ public class ChapterManager : IChapterManager
     }
 
     /// <inheritdoc />
-    public void DeleteChapterImages(Video video)
+    public async Task DeleteChapterDataAsync(Guid itemId, CancellationToken cancellationToken)
     {
-        var path = _pathManager.GetChapterImageFolderPath(video);
-        try
-        {
-            if (Directory.Exists(path))
-            {
-                _logger.LogInformation("Removing chapter images for {Name} [{Id}]", video.Name, video.Id);
-                Directory.Delete(path, true);
-            }
-        }
-        catch (Exception ex)
-        {
-            _logger.LogWarning("Failed to remove chapter image folder for {Item}: {Exception}", video.Id, ex);
-        }
-
-        _chapterRepository.DeleteChapters(video.Id);
+        await _chapterRepository.DeleteChaptersAsync(itemId, cancellationToken).ConfigureAwait(false);
     }
 
     private IReadOnlyList<string> GetSavedChapterImages(Video video, IDirectoryService directoryService)

+ 6 - 0
Emby.Server.Implementations/Library/ExternalDataManager.cs

@@ -3,6 +3,7 @@ using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Controller.Chapters;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.MediaSegments;
@@ -20,6 +21,7 @@ public class ExternalDataManager : IExternalDataManager
     private readonly IMediaSegmentManager _mediaSegmentManager;
     private readonly IPathManager _pathManager;
     private readonly ITrickplayManager _trickplayManager;
+    private readonly IChapterManager _chapterManager;
     private readonly ILogger<ExternalDataManager> _logger;
 
     /// <summary>
@@ -29,18 +31,21 @@ public class ExternalDataManager : IExternalDataManager
     /// <param name="mediaSegmentManager">The media segment manager.</param>
     /// <param name="pathManager">The path manager.</param>
     /// <param name="trickplayManager">The trickplay manager.</param>
+    /// <param name="chapterManager">The chapter manager.</param>
     /// <param name="logger">The logger.</param>
     public ExternalDataManager(
         IKeyframeManager keyframeManager,
         IMediaSegmentManager mediaSegmentManager,
         IPathManager pathManager,
         ITrickplayManager trickplayManager,
+        IChapterManager chapterManager,
         ILogger<ExternalDataManager> logger)
     {
         _keyframeManager = keyframeManager;
         _mediaSegmentManager = mediaSegmentManager;
         _pathManager = pathManager;
         _trickplayManager = trickplayManager;
+        _chapterManager = chapterManager;
         _logger = logger;
     }
 
@@ -67,5 +72,6 @@ public class ExternalDataManager : IExternalDataManager
         await _keyframeManager.DeleteKeyframeDataAsync(itemId, cancellationToken).ConfigureAwait(false);
         await _mediaSegmentManager.DeleteSegmentsAsync(itemId, cancellationToken).ConfigureAwait(false);
         await _trickplayManager.DeleteTrickplayDataAsync(itemId, cancellationToken).ConfigureAwait(false);
+        await _chapterManager.DeleteChapterDataAsync(itemId, cancellationToken).ConfigureAwait(false);
     }
 }

+ 9 - 4
Jellyfin.Server.Implementations/Item/ChapterRepository.cs

@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
 using Jellyfin.Database.Implementations;
 using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Drawing;
@@ -82,11 +84,14 @@ public class ChapterRepository : IChapterRepository
     }
 
     /// <inheritdoc />
-    public void DeleteChapters(Guid itemId)
+    public async Task DeleteChaptersAsync(Guid itemId, CancellationToken cancellationToken)
     {
-        using var context = _dbProvider.CreateDbContext();
-        context.Chapters.Where(c => c.ItemId.Equals(itemId)).ExecuteDelete();
-        context.SaveChanges();
+        var dbContext = await _dbProvider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
+        await using (dbContext.ConfigureAwait(false))
+        {
+            await dbContext.Chapters.Where(c => c.ItemId.Equals(itemId)).ExecuteDeleteAsync(cancellationToken).ConfigureAwait(false);
+            await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
+        }
     }
 
     private Chapter Map(ChapterInfo chapterInfo, int index, Guid itemId)

+ 5 - 3
MediaBrowser.Controller/Chapters/IChapterManager.cs

@@ -48,8 +48,10 @@ public interface IChapterManager
     Task<bool> RefreshChapterImages(Video video, IDirectoryService directoryService, IReadOnlyList<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken);
 
     /// <summary>
-    /// Deletes the chapter images.
+    /// Deletes the chapter data.
     /// </summary>
-    /// <param name="video">Video to use.</param>
-    void DeleteChapterImages(Video video);
+    /// <param name="itemId">The item id.</param>
+    /// <param name="cancellationToken">The cancellation token.</param>
+    /// <returns>Task.</returns>
+    Task DeleteChapterDataAsync(Guid itemId, CancellationToken cancellationToken);
 }

+ 5 - 1
MediaBrowser.Controller/Persistence/IChapterRepository.cs

@@ -1,5 +1,7 @@
 using System;
 using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
 using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Controller.Persistence;
@@ -13,7 +15,9 @@ public interface IChapterRepository
     /// Deletes the chapters.
     /// </summary>
     /// <param name="itemId">The item.</param>
-    void DeleteChapters(Guid itemId);
+    /// <param name="cancellationToken">The cancellation token.</param>
+    /// <returns>Task.</returns>
+    Task DeleteChaptersAsync(Guid itemId, CancellationToken cancellationToken);
 
     /// <summary>
     /// Saves the chapters.