using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Tasks; using Microsoft.Extensions.Logging; namespace JellyfinPlugin.Tasks { public class LibraryRetroactiveScanTask : IScheduledTask { private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; public LibraryRetroactiveScanTask(ILogger logger, ILibraryManager libraryManager) { _logger = logger; _libraryManager = libraryManager; } public string Name => "Skanuj brakujące czarne pasy (Black Bar Remover)"; public string Key => "BlackBarRetroactiveScanTask"; public string Description => "Skanuje istniejącą bibliotekę, pomijając już przeanalizowane pliki. Użyj tego po zainstalowaniu wtyczki."; public string Category => "Library"; public async Task ExecuteAsync(IProgress progress, CancellationToken cancellationToken) { var config = Plugin.Instance!.Configuration; if (!config.IsEnabled) { _logger.LogInformation("Wtyczka wyłączona. Pomijanie."); return; } var items = _libraryManager.RootFolder.GetRecursiveChildren() .Where(x => x is Movie || x is Episode) .ToList(); int total = items.Count; int processed = 0; foreach (var item in items) { cancellationToken.ThrowIfCancellationRequested(); if (item.ProviderIds != null && item.ProviderIds.ContainsKey("BlackBarCrop")) { processed++; progress.Report((processed / (double)total) * 100); continue; } var path = item.Path; if (!string.IsNullOrEmpty(path) && File.Exists(path)) { try { string cropData = await CropHelper.DetectCropAsync(path, config.CropDetectLimit); if (item.ProviderIds == null) { item.ProviderIds = new Dictionary(); } // Zawsze dodajemy flagę, nawet jak puste, żeby nie skanować drugi raz tego samego pliku // (puste oznacza że nie ma czarnych pasów do ucięcia) item.ProviderIds["BlackBarCrop"] = cropData ?? string.Empty; await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, cancellationToken); if (!string.IsNullOrEmpty(cropData)) _logger.LogInformation("Znaleziono pasy {Crop} w {Path}", cropData, path); } catch (Exception ex) { _logger.LogError(ex, "Błąd skanowania pliku {Path}", path); } } processed++; progress.Report((processed / (double)total) * 100); } } public IEnumerable GetDefaultTriggers() { return Array.Empty(); } } }