Files
icarus/Icarus/Controllers/Managers/SongManager.cs
T
KD 9d90247bf8 Suppressing warning for endpoints (#107)
* Suppressing warning for endpoints

* Minor refactoring
2025-03-01 16:36:02 -05:00

466 lines
14 KiB
C#

using NLog;
using Icarus.Controllers.Utilities;
using Icarus.Models;
using Icarus.Database.Contexts;
namespace Icarus.Controllers.Managers;
public class SongManager : BaseManager
{
#region Fields
private string? _tempDirectoryRoot;
private string? _archiveDirectoryRoot;
private string? _compressedSongFilename;
private string? _message;
private SongContext? _songContext;
#endregion
#region Properties
public string? ArchiveDirectoryRoot
{
get => _archiveDirectoryRoot;
set => _archiveDirectoryRoot = value;
}
public string? CompressedSongFilename
{
get => _compressedSongFilename;
set => _compressedSongFilename = value;
}
public string? Message
{
get => _message;
set => _message = value;
}
#endregion
#region Constructors
public SongManager(IConfiguration config)
{
_config = config;
Initialize();
}
public SongManager(IConfiguration config, string tempDirectoryRoot)
{
_config = config;
_tempDirectoryRoot = tempDirectoryRoot;
Initialize();
}
#endregion
#region Methods
public SongResult UpdateSong(Song song)
{
var result = new SongResult();
if (!DoesSongExist(song))
{
result.SongTitle = song.Title;
result.Message = "Song does not exist";
return result;
}
try
{
var oldSongRecord = _songContext!.RetrieveRecord(song);
song.Filename = oldSongRecord.Filename;
song.SongDirectory = oldSongRecord.SongDirectory;
MetadataRetriever updateMetadata = new MetadataRetriever();
updateMetadata.UpdateMetadata(song, oldSongRecord);
var updatedSong = updateMetadata.UpdatedSongRecord;
var albMgr = new AlbumManager(_config!);
var gnrMgr = new GenreManager(_config!);
var artMgr = new ArtistManager(_config!);
var updatedAlbum = albMgr.UpdateAlbumInDatabase(oldSongRecord, updatedSong!);
oldSongRecord.AlbumId = updatedAlbum.Id;
var updatedArtist = artMgr.UpdateArtistInDatabase(oldSongRecord, updatedSong!);
oldSongRecord.ArtistId = updatedArtist.Id;
var updatedGenre = gnrMgr.UpdateGenreInDatabase(oldSongRecord, updatedSong!);
oldSongRecord.GenreId = updatedGenre.Id;
UpdateSongInDatabase(ref oldSongRecord, ref updatedSong!, ref result);
DeleteEmptyDirectories(ref oldSongRecord, ref updatedSong);
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred");
result.Message = $"An error occurred: {msg}";
result.SongTitle = song.Title;
}
return result;
}
public bool DeleteSongFromFileSystem(Song songMetaData)
{
bool successful = false;
try
{
var songPath = songMetaData.SongPath();
System.IO.File.Delete(songPath);
successful = !System.IO.File.Exists(songPath);
if (successful)
{
Console.WriteLine("Song successfully deleted");
}
DirectoryManager dirMgr = new DirectoryManager(_config!, songMetaData);
var deletedAmount = dirMgr.DeleteEmptyDirectories(songMetaData.SongDirectory, 1);
if (deletedAmount > 0)
{
Console.WriteLine($"{deletedAmount} directories deleted");
}
}
catch (Exception ex)
{
var exMsg = ex.Message;
}
return successful;
}
public bool DoesSongExist(Song song)
{
if (!_songContext!.DoesRecordExist(song))
{
return false;
}
return true;
}
public void DeleteSong(Song song)
{
try
{
if (DeleteSongFromFilesystem(song, true))
{
_logger.Error("Failed to delete the song");
throw new Exception("Failed to delete the song");
}
_logger.Info("Song deleted from the filesystem");
var coverMgr = new CoverArtManager(_config!);
var coverArt = coverMgr.GetCoverArt(song);
coverMgr.DeleteCoverArt(coverArt);
DeleteSongFromDatabase(song);
coverMgr.DeleteCoverArtFromDatabase(coverArt);
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred");
}
}
public Song SaveFlacSongToFileSystem(IFormFile songFile, IFormFile coverArtData, Song song)
{
// Save temp song (Should already be saved to the filesystem by the time it gets to this method)
// Save cover art
// Update the song's metadata with the song object
// Save song to its final directory
// Save cover art to the database
// Save song to the database
var coverMgr = new CoverArtManager(_config!);
var coverArt = coverMgr.SaveCoverArt(coverArtData, song);
var meta = new Utilities.MetadataRetriever();
meta.UpdateMetadata(song, song);
DirectoryManager dirMgr = new DirectoryManager(_config!, song);
dirMgr.CreateDirectory();
var tempPath = song.SongPath();
song.SongDirectory = dirMgr.SongDirectory;
song.Filename = song.GenerateFilename(true, AudioFileExtensionsType.FLAC);
var filePath = song.SongPath();
_logger.Info($"Absolute song path: {filePath}");
this.MoveSongToFinalDestination(tempPath, filePath);
SaveSongToDatabase(song, coverArt);
return song;
}
private void MoveSongToFinalDestination(string sourcePath, string targetPath)
{
using (var fileStream = new FileStream(targetPath, FileMode.Create))
{
var songBytes = System.IO.File.ReadAllBytes(sourcePath);
try
{
if (System.IO.File.Exists(sourcePath) && System.IO.File.Exists(sourcePath) && fileStream.Length > 0)
{
System.IO.File.Delete(sourcePath);
_logger.Info("Deleted temp song from filesystem: {0}", sourcePath);
}
else
{
fileStream.Write(songBytes, 0, songBytes.Count());
_logger.Info("Saved song to filesystem: {0}", targetPath);
System.IO.File.Delete(sourcePath);
_logger.Info("Deleted temp song from filesystem: {0}", sourcePath);
}
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error($"An error occurred: {msg}");
}
_logger.Info("Song successfully saved to filesystem");
}
}
public async Task<SongData> RetrieveSong(Song songMetaData)
{
var song = new SongData();
try
{
Console.WriteLine("Fetching song from filesystem");
song = await RetrieveSongFromFileSystem(songMetaData);
}
catch (Exception ex)
{
var exMsg = ex.Message;
Console.WriteLine($"An error occurred: {exMsg}");
}
return song;
}
private async Task<SongData> RetrieveSongFromFileSystem(Song details)
{
byte[] uncompressedSong = await System.IO.File.ReadAllBytesAsync(details.SongPath());
return new SongData
{
Data = uncompressedSong
};
}
public async Task<Song> SaveSongTemp(IFormFile songFile)
{
_logger.Info("Assigning song filename");
var song = new Song { SongDirectory = this._tempDirectoryRoot! };
var filename = await song.GenerateFilenameAsync(false) + "-" + songFile.FileName;
song.Filename = filename;
var songPath = song.SongPath();
using (var filestream = new FileStream(songPath, FileMode.Create))
{
_logger.Info("Saving temp song: {0}", songPath);
await songFile.CopyToAsync(filestream);
}
song.DateCreated = DateTime.Now;
return song;
}
public Icarus.Models.CreateFileResult Create(IFormFile file, string filePath, string prompt)
{
if (System.IO.File.Exists(filePath))
{
return CreateFileResult.AlreadyExists;
}
using (var filestream = new FileStream(filePath, FileMode.Create))
{
Console.WriteLine(prompt);
file.CopyTo(filestream);
if (System.IO.File.Exists(filePath))
{
return CreateFileResult.FileCreatedAndExists;
}
}
return 0;
}
private bool SongRecordChanged(Song currentSong, Song songUpdates)
{
var currentTitle = currentSong.Title;
var currentArtist = currentSong.Artist;
var currentAlbum = currentSong.AlbumTitle;
var currentGenre = currentSong.Genre;
var currentYear = currentSong.Year;
if (!currentTitle!.Equals(songUpdates.Title) || !currentArtist!.Equals(songUpdates.Artist) ||
!currentAlbum!.Equals(songUpdates.AlbumTitle) ||
!currentGenre!.Equals(songUpdates.Genre) || currentYear != songUpdates.Year)
return true;
return false;
}
private void DeleteEmptyDirectories(ref Song oldSong, ref Song updatedSong)
{
DirectoryManager mgr = new DirectoryManager(_config!);
_logger.Info("Checking to see if there are any directories to delete");
mgr.DeleteEmptyDirectories(oldSong);
}
private void Initialize()
{
try
{
_connectionString = _config!.GetConnectionString("DefaultConnection");
_songContext = new SongContext(_connectionString!);
}
catch (Exception ex)
{
Console.WriteLine($"Error Occurred: {ex.Message}");
}
}
private void SaveSongToDatabase(Song song, CoverArt? cover)
{
_logger.Info("Starting process to save the song to the database");
var albumMgr = new AlbumManager(_config!);
var artistMgr = new ArtistManager(_config!);
var genreMgr = new GenreManager(_config!);
var coverMgr = new CoverArtManager(_config!);
albumMgr.SaveAlbumToDatabase(ref song);
artistMgr.SaveArtistToDatabase(ref song);
genreMgr.SaveGenreToDatabase(ref song);
var info = "Saving Song to DB";
_logger.Info(info);
_songContext!.Add(song);
_songContext!.SaveChanges();
coverMgr.SaveCoverArtToDatabase(ref song, ref cover!);
}
private bool DeleteSongFromFilesystem(Song song, bool deleteDirectory = false)
{
var songPath = song.SongPath();
_logger.Info("Deleting song from the filesystem");
try
{
System.IO.File.Delete(songPath);
DeleteEmptyDirectories(ref song, ref song);
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred when attempting to delete the song from the filesystem");
return false;
}
return DoesSongExistOnFilesystem(song);
}
private bool DoesSongExistOnFilesystem(Song song)
{
if (!System.IO.File.Exists(song.SongPath()))
{
_logger.Info("Song does not exist on the filesystem");
return false;
}
_logger.Info("Song exists on the filesystem");
return true;
}
private void UpdateSongInDatabase(ref Song oldSongRecord, ref Song newSongRecord, ref SongResult result)
{
var updatedSongRecord = oldSongRecord;
var songContext = new SongContext(_connectionString!);
if (!SongRecordChanged(oldSongRecord, newSongRecord))
{
_logger.Info("No change to the song record");
return;
}
_logger.Info("Changes to song record found");
if (!string.IsNullOrEmpty(newSongRecord.Title))
updatedSongRecord.Title = newSongRecord.Title;
if (!string.IsNullOrEmpty(newSongRecord.AlbumTitle))
{
updatedSongRecord.AlbumTitle = newSongRecord.AlbumTitle;
}
if (!string.IsNullOrEmpty(newSongRecord.Artist))
{
updatedSongRecord.Artist = newSongRecord.Artist;
}
if (!string.IsNullOrEmpty(newSongRecord.Genre))
{
updatedSongRecord.Genre = newSongRecord.Genre;
Console.WriteLine("Genre changed");
Console.WriteLine($"{updatedSongRecord.Genre} {newSongRecord.Genre}");
}
if (newSongRecord.Year != null || newSongRecord.Year > 0)
updatedSongRecord.Year = newSongRecord.Year;
_logger.Info("Applied changes to song record");
_logger.Info("Saving song metadata to the database");
songContext.Update(updatedSongRecord);
songContext.SaveChanges();
newSongRecord = updatedSongRecord;
result.Message = "Successfully updated song";
result.SongTitle = updatedSongRecord.Title!;
}
private void DeleteSongFromDatabase(Song song)
{
_logger.Info("Starting process to delete records related to the song from the database");
var albumMgr = new AlbumManager(_config!);
var artistMgr = new ArtistManager(_config!);
var genreMgr = new GenreManager(_config!);
var sngContext = new SongContext(_connectionString!);
sngContext.Songs!.Remove(song);
sngContext.SaveChanges();
artistMgr.DeleteArtistFromDatabase(song);
albumMgr.DeleteAlbumFromDatabase(song);
genreMgr.DeleteGenreFromDatabase(song);
}
#endregion
}