Added implementation to FileSystemScanService

This commit is contained in:
Samuele Lorefice
2025-07-08 17:30:26 +02:00
parent 607fef4cb0
commit ce7dba34c8
2 changed files with 46 additions and 13 deletions

View File

@@ -5,11 +5,16 @@ using static System.String;
namespace Lactose.Services;
public class FileSystemScanService(
ILogger<FileSystemScanService> logger,
public class FileSystemScannerService(
ILogger<FileSystemScannerService> logger,
IAssetRepository assetRepository,
IFolderRepository folderRepository
) : BackgroundService {
public bool IsRunning { get; private set; } = false;
public bool IsInitialized { get; private set; } = false;
//TODO: Make this configurable
public TimeSpan ScanInterval { get; private set; } = TimeSpan.FromMinutes(30);
List<Folder> folders = [];
readonly List<Task> tasks = [];
@@ -108,17 +113,43 @@ public class FileSystemScanService(
new("video/x-msvideo", [".avi"]),
new("video/x-sgi-movie", [".movie"])
];
protected override Task ExecuteAsync(CancellationToken stoppingToken) {
while (!stoppingToken.IsCancellationRequested && !tasks.All(task => task.IsCompleted)) {
logger.LogInformation("Starting scan");
folders = folderRepository.GetAll().ToList();
// Launch a folder scan for each folder, passing the stopping token to each task
folders.ForEach(folder => { tasks.Add(Task.Run(() => ScanFolder(folder.BasePath), stoppingToken)); });
}
return Task.CompletedTask;
protected override Task ExecuteAsync(CancellationToken stoppingToken) {
var service = new Task(() => ServiceLogic(stoppingToken));
service.Start();
return service;
}
//TODO: This really needs a decent name.
void ServiceLogic(CancellationToken stoppingToken) {
PeriodicTimer scanTimer;
logger.LogInformation("Filesystem Scan Service starting...");
//TODO: fetch scan interval from DB if possible
// settingsRepository.GetSetting("scanInterval", out string? scanInterval);
scanTimer = new (ScanInterval);
logger.LogInformation($"Service will scan every {ScanInterval.TotalMinutes} minutes.");
IsInitialized = true;
while (!stoppingToken.IsCancellationRequested) {
logger.LogInformation("Retrieving folder paths to scan...");
folders = folderRepository.GetAll().ToList();
// Wait for all tasks to complete before starting a new scan
if(tasks.Count > 0) {
logger.LogInformation("Waiting for {count} tasks to complete...", tasks.Count);
Task.WaitAll(tasks.ToArray(), stoppingToken);
IsRunning = false;
}
if (folders.Count != 0) {
logger.LogInformation("Found {count} folders to scan.", folders.Count);
logger.LogInformation("Starting Tasks for scanning folders...");
// Launch a folder scan for each folder, passing the stopping token to each task
folders.ForEach(folder => { tasks.Add(Task.Run(() => ScanFolder(folder.BasePath), stoppingToken)); });
IsRunning = true;
} else {
logger.LogWarning("No folders to scan. Waiting for next scan interval...");
scanTimer.WaitForNextTickAsync(stoppingToken);
}
}
}
void ScanFolder(string path) {

View File

@@ -1,5 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABackgroundService_002Ecs_002Fl_003AC_0021_003FUsers_003FREDCODE_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F3965deb13a37647a5a8015a2a5b23a50f5db9329b3537cdbdf7566746e545bcf_003FBackgroundService_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConfigurationExtensions_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fb8c1c57742337e59591581af3eb2c647e9ed52d2951655fd74b1facf3ff520_003FConfigurationExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControllerBase_002Ecs_002Fl_003AC_0021_003FUsers_003Fnivek_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F96a4cc66aa48dda8a9d8be8febec4a769fc143f7a86dd53ecdebfb9c3177d_003FControllerBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIFileInfo_002Ecs_002Fl_003AC_0021_003FUsers_003Fnivek_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F781590a6c8e24e6b9f85d75a1ac30c819918_003F47_003Fda5e789a_003FIFileInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFileInfo_002Ecs_002Fl_003AC_0021_003FUsers_003Fnivek_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9fcad18e31a1983467a9fd4bfef344ee97d72fa4ab6ba20353b8f78db8437b1_003FFileInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFileInfo_002Ecs_002Fl_003AC_0021_003FUsers_003Fnivek_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9fcad18e31a1983467a9fd4bfef344ee97d72fa4ab6ba20353b8f78db8437b1_003FFileInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APeriodicTimer_002Ecs_002Fl_003AC_0021_003FUsers_003FREDCODE_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F6218e99a21d6c4fab8b6313176b59d476b17ffc69867b9e6b2605659275a21_003FPeriodicTimer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>