feat: add library scanning mechanic
This commit is contained in:
91
Tools/LibraryWatcher.cs
Normal file
91
Tools/LibraryWatcher.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using Shadow.Data;
|
||||
using Shadow.Entities;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Shadow.Tools;
|
||||
public class LibraryWatcher(string watchPath, string[] excludedPaths, ApplicationDbContext dbContext)
|
||||
{
|
||||
private readonly string libraryPath = watchPath;
|
||||
private readonly string[] excludedPaths = excludedPaths;
|
||||
private readonly ApplicationDbContext db = dbContext;
|
||||
private readonly GeneralUseHelpers guhf = new();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a sorted list of paths to all files in a directory, recursively.
|
||||
/// </summary>
|
||||
/// <param name="directory">Path to directory</param>
|
||||
/// <returns>Sorted list of filepaths</returns>
|
||||
public async Task<List<string>> GetFilesRecursivelyAsync(string directory)
|
||||
{
|
||||
string[] allowedExtensions = [".flac", ".m4a", ".mp3", ".ogg", ".wav"];
|
||||
try
|
||||
{
|
||||
List<string> files =
|
||||
Directory.GetFiles(directory, "*", SearchOption.AllDirectories)
|
||||
.Where(file => allowedExtensions.Any(file.ToLower().EndsWith))
|
||||
.ToList();
|
||||
|
||||
files.Sort();
|
||||
return files;
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
Console.WriteLine($"[Error] Directory \"{directory}\" does not exist!\n" +
|
||||
" Please create it manually, or use `Shadow setupWizard`.");
|
||||
throw new DirectoryNotFoundException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all multimedia content inside of library
|
||||
/// </summary>
|
||||
/// <returns>List of multimedia filepaths</returns>
|
||||
public async Task<List<string>> GetAllMultimediaAsync()
|
||||
{
|
||||
|
||||
// List files in cache
|
||||
// Note: currently, the only excluded path from scanning is the thumbnail cache.
|
||||
// This might change in the future.
|
||||
List<string> cacheFiles = await GetFilesRecursivelyAsync(excludedPaths[0]);
|
||||
|
||||
// List files in library excluding cache
|
||||
List<string> libraryContent = await GetFilesRecursivelyAsync(libraryPath);
|
||||
List<string> libraryMultimedia = libraryContent.Except(cacheFiles).ToList();
|
||||
|
||||
return libraryMultimedia;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scan the library in its entirety
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<string>> PerformFullScanAsync()
|
||||
{
|
||||
Console.WriteLine("Performing full library scan...");
|
||||
|
||||
List<string> multimedia = await GetAllMultimediaAsync();
|
||||
foreach (string filepath in multimedia)
|
||||
{
|
||||
Console.WriteLine(filepath);
|
||||
Dictionary<string, string> fileInfo = await MetadataExtractor.ExtractAsync(filepath);
|
||||
|
||||
// Pretend we are doing parsing here...
|
||||
Console.WriteLine(GeneralUseHelpers.DictAsJson(fileInfo));
|
||||
MediaParser.CreateSong(db, fileInfo);
|
||||
}
|
||||
|
||||
Console.WriteLine($"Full scan complete! Processed {multimedia.Count} files.");
|
||||
|
||||
// Update state inside of DB
|
||||
string currentLibraryState = MetadataExtractor.GetStringMD5(string.Join("\n", multimedia));
|
||||
Global lastLibraryState = db.Globals.FirstOrDefault(g => g.Key == "libraryState")
|
||||
?? new() { Key = "libraryState"};
|
||||
lastLibraryState.Value = currentLibraryState;
|
||||
db.Update(lastLibraryState);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return multimedia;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user