aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs')
-rw-r--r--Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs132
1 files changed, 81 insertions, 51 deletions
diff --git a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
index 7ea863d76..31ae82d6a 100644
--- a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
+++ b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
@@ -1,84 +1,114 @@
#pragma warning disable CS1591
using System;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using Jellyfin.Server.Implementations;
+using Jellyfin.Database.Implementations;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
-namespace Emby.Server.Implementations.Data
+namespace Emby.Server.Implementations.Data;
+
+public class CleanDatabaseScheduledTask : ILibraryPostScanTask
{
- public class CleanDatabaseScheduledTask : ILibraryPostScanTask
+ private readonly ILibraryManager _libraryManager;
+ private readonly ILogger<CleanDatabaseScheduledTask> _logger;
+ private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
+ private readonly IPathManager _pathManager;
+
+ public CleanDatabaseScheduledTask(
+ ILibraryManager libraryManager,
+ ILogger<CleanDatabaseScheduledTask> logger,
+ IDbContextFactory<JellyfinDbContext> dbProvider,
+ IPathManager pathManager)
{
- private readonly ILibraryManager _libraryManager;
- private readonly ILogger<CleanDatabaseScheduledTask> _logger;
- private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
-
- public CleanDatabaseScheduledTask(
- ILibraryManager libraryManager,
- ILogger<CleanDatabaseScheduledTask> logger,
- IDbContextFactory<JellyfinDbContext> dbProvider)
- {
- _libraryManager = libraryManager;
- _logger = logger;
- _dbProvider = dbProvider;
- }
+ _libraryManager = libraryManager;
+ _logger = logger;
+ _dbProvider = dbProvider;
+ _pathManager = pathManager;
+ }
- public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
- {
- await CleanDeadItems(cancellationToken, progress).ConfigureAwait(false);
- }
+ public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
+ {
+ await CleanDeadItems(cancellationToken, progress).ConfigureAwait(false);
+ }
- private async Task CleanDeadItems(CancellationToken cancellationToken, IProgress<double> progress)
+ private async Task CleanDeadItems(CancellationToken cancellationToken, IProgress<double> progress)
+ {
+ var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery
{
- var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery
- {
- HasDeadParentId = true
- });
+ HasDeadParentId = true
+ });
- var numComplete = 0;
- var numItems = itemIds.Count + 1;
+ var numComplete = 0;
+ var numItems = itemIds.Count + 1;
- _logger.LogDebug("Cleaning {0} items with dead parent links", numItems);
+ _logger.LogDebug("Cleaning {Number} items with dead parents", numItems);
- foreach (var itemId in itemIds)
- {
- cancellationToken.ThrowIfCancellationRequested();
+ foreach (var itemId in itemIds)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
- var item = _libraryManager.GetItemById(itemId);
+ var item = _libraryManager.GetItemById(itemId);
+ if (item is not null)
+ {
+ _logger.LogInformation("Cleaning item {Item} type: {Type} path: {Path}", item.Name, item.GetType().Name, item.Path ?? string.Empty);
- if (item is not null)
+ foreach (var mediaSource in item.GetMediaSources(false))
{
- _logger.LogInformation("Cleaning item {0} type: {1} path: {2}", item.Name, item.GetType().Name, item.Path ?? string.Empty);
+ // Delete extracted data
+ var mediaSourceItem = _libraryManager.GetItemById(mediaSource.Id);
+ if (mediaSourceItem is null)
+ {
+ continue;
+ }
- _libraryManager.DeleteItem(item, new DeleteOptions
+ var extractedDataFolders = _pathManager.GetExtractedDataPaths(mediaSourceItem);
+ foreach (var folder in extractedDataFolders)
{
- DeleteFileLocation = false
- });
+ if (Directory.Exists(folder))
+ {
+ try
+ {
+ Directory.Delete(folder, true);
+ }
+ catch (Exception e)
+ {
+ _logger.LogWarning("Failed to remove {Folder}: {Exception}", folder, e.Message);
+ }
+ }
+ }
}
- numComplete++;
- double percent = numComplete;
- percent /= numItems;
- progress.Report(percent * 100);
+ // Delete item
+ _libraryManager.DeleteItem(item, new DeleteOptions
+ {
+ DeleteFileLocation = false
+ });
}
- var context = await _dbProvider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
- await using (context.ConfigureAwait(false))
+ numComplete++;
+ double percent = numComplete;
+ percent /= numItems;
+ progress.Report(percent * 100);
+ }
+
+ var context = await _dbProvider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
+ await using (context.ConfigureAwait(false))
+ {
+ var transaction = await context.Database.BeginTransactionAsync(cancellationToken).ConfigureAwait(false);
+ await using (transaction.ConfigureAwait(false))
{
- var transaction = await context.Database.BeginTransactionAsync(cancellationToken).ConfigureAwait(false);
- await using (transaction.ConfigureAwait(false))
- {
- await context.ItemValues.Where(e => e.BaseItemsMap!.Count == 0).ExecuteDeleteAsync(cancellationToken).ConfigureAwait(false);
- await transaction.CommitAsync(cancellationToken).ConfigureAwait(false);
- }
+ await context.ItemValues.Where(e => e.BaseItemsMap!.Count == 0).ExecuteDeleteAsync(cancellationToken).ConfigureAwait(false);
+ await transaction.CommitAsync(cancellationToken).ConfigureAwait(false);
}
-
- progress.Report(100);
}
+
+ progress.Report(100);
}
}