92 lines
2.8 KiB
C#

using System.IO;
using songrequests_blazor.Data;
using System.Collections.Concurrent;
using Microsoft.EntityFrameworkCore;
namespace songrequests_blazor.Services
{
public class ScanService : IHostedService, IDisposable
{
public static BlockingCollection<Library> Queue { get; set; } = new();
IDbContextFactory<LocalDbContext> _dbContextFactory;
public ScanService(IDbContextFactory<LocalDbContext> contextFactory)
{
_dbContextFactory = contextFactory;
}
public static void AddToQueue(Library itm)
{
if (itm.ScanPaths == null || itm.ScanPaths.Count == 0) return;
if (!Queue.Contains(itm)) Queue.Add(itm);
}
public void Dispose()
{
Queue.Dispose();
}
private Timer? timer;
public async Task StartAsync(CancellationToken cancellationToken)
{
await Task.Run(() =>
{
timer = new Timer(ScanFiles, cancellationToken, 0, 5000);
});
}
public async Task StopAsync(CancellationToken cancellationToken)
{
// BlockingCollection leeren
await Task.Run(() =>
{
while (Queue.TryTake(out _)) { }
});
}
private void ScanFiles(object? state)
{
CancellationToken token;
if (state != null)
{
token = (CancellationToken)state;
}
else
{
token = new CancellationTokenSource().Token;
}
while (Queue?.Count > 0)
{
Library lib = Queue.Take();
List<Song> files = new List<Song>();
foreach (var ScanPath in lib.ScanPaths ?? [])
{
Console.WriteLine($"{DateTime.Now:g} Scanning {ScanPath}");
foreach (string file in Directory.GetFiles(ScanPath, "*.mp3", SearchOption.AllDirectories))
{
if (lib.Songs == null || !lib.Songs.Any(s => s.Uri.Trim().ToLower() == file.Trim().ToLower()))
{
var song = Song.FromFile(file);
song.Library = lib;
files.Add(song);
}
}
}
Console.WriteLine($"{DateTime.Now:g} Adding found files to library...");
using (LocalDbContext db = _dbContextFactory.CreateDbContext())
{
db.Libraries.Update(lib);
if (lib.Songs == null) lib.Songs = new();
lib.Songs.AddRange(files);
db.SaveChanges();
}
}
}
}
}