#pragma warning disable RS0030 // Do not use banned APIs using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Jellyfin.Database.Implementations; using Jellyfin.Server.Implementations.Item; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.ScheduledTasks.Tasks; /// /// Task to clean up any detached userdata from the database. /// public class CleanupUserDataTask : IScheduledTask { private readonly ILocalizationManager _localization; private readonly IDbContextFactory _dbProvider; private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The localisation Provider. /// The DB context factory. /// A logger. public CleanupUserDataTask(ILocalizationManager localization, IDbContextFactory dbProvider, ILogger logger) { _localization = localization; _dbProvider = dbProvider; _logger = logger; } /// public string Name => _localization.GetLocalizedString("CleanupUserDataTask"); /// public string Description => _localization.GetLocalizedString("CleanupUserDataTaskDescription"); /// public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory"); /// public string Key => nameof(CleanupUserDataTask); /// public async Task ExecuteAsync(IProgress progress, CancellationToken cancellationToken) { const int LimitDays = 90; var userDataDate = DateTime.UtcNow.AddDays(LimitDays * -1); var dbContext = await _dbProvider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false); await using (dbContext.ConfigureAwait(false)) { var detachedUserData = dbContext.UserData.Where(e => e.ItemId == BaseItemRepository.PlaceholderId); _logger.LogInformation("There are {NoDetached} detached UserData entries.", detachedUserData.Count()); detachedUserData = detachedUserData.Where(e => e.RetentionDate < userDataDate); _logger.LogInformation("{NoDetached} are older then {Limit} days.", detachedUserData.Count(), LimitDays); await detachedUserData.ExecuteDeleteAsync(cancellationToken).ConfigureAwait(false); } progress.Report(100); } /// public IEnumerable GetDefaultTriggers() { yield break; } }