feat: orphan songs not present in the media directory

This commit is contained in:
2026-01-28 05:16:17 +01:00
parent b46ab28615
commit 03940a99ba

View File

@@ -1,3 +1,4 @@
using Microsoft.EntityFrameworkCore;
using Shadow.Data;
using Shadow.Entities;
using System;
@@ -65,27 +66,79 @@ public class LibraryWatcher(string watchPath, string[] excludedPaths, Applicatio
{
Console.WriteLine("Performing full library scan...");
List<string> multimedia = await GetAllMultimediaAsync();
foreach (string filepath in multimedia)
// Current library state as present in database
List<Song> currentLibraryMedia = await db.Songs
.Where(s => s.State == 0)
.ToListAsync();
// Updated library state
List<Song> updatedSongList = [];
List<string> newMultimediaPathNames = await GetAllMultimediaAsync();
foreach (string filepath in newMultimediaPathNames)
{
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);
Song? songInDb = db.Songs
.Include(s => s.Album)
.FirstOrDefault(s => s.Uri == fileInfo["_shadow:fileHash"]);
if (songInDb != null)
{
// Don't parse the song
Console.WriteLine("Skipping song as it already exists in database...");
// But update it's location in case it has been moved
songInDb.Filepath = filepath;
// And state in case it has been reinstated
songInDb.State = 0; // Set non-orphaned state
songInDb.Album.State = 0; // -||-
db.Update(songInDb); // Is this necessary?
await db.SaveChangesAsync();
// Afterwards include it in the updated song list
updatedSongList.Add(songInDb);
}
else
{
// A new song? Parse it and add to DB
Song? newSong = MediaParser.CreateSong(db, fileInfo);
// Sanity check
if (newSong != null)
updatedSongList.Add(newSong);
}
}
Console.WriteLine($"Full scan complete! Processed {multimedia.Count} files.");
Console.WriteLine($"Full scan complete! Processed {newMultimediaPathNames.Count} files.");
List<Song> orphanedSongs = currentLibraryMedia
.Except(updatedSongList)
.ToList();
Console.WriteLine($"Detected {orphanedSongs.Count} new orphaned songs");
foreach (Song s in orphanedSongs)
{
Song dbSong = db.Songs
.Include(d => d.Artist)
.First(d => d.Id == s.Id);
Console.WriteLine($"- {dbSong.Title} by {dbSong.Artist.Name} (previous path: {dbSong.Filepath})");
dbSong.State = 1;
await db.SaveChangesAsync();
}
Console.WriteLine();
// Update state inside of DB
string currentLibraryState = MetadataExtractor.GetStringMD5(string.Join("\n", multimedia));
string updatedLibraryState = MetadataExtractor.GetStringMD5(string.Join("\n", newMultimediaPathNames));
Global lastLibraryState = db.Globals.FirstOrDefault(g => g.Key == "libraryState")
?? new() { Key = "libraryState"};
lastLibraryState.Value = currentLibraryState;
lastLibraryState.Value = updatedLibraryState;
db.Update(lastLibraryState);
await db.SaveChangesAsync();
return multimedia;
return newMultimediaPathNames;
}
}