Migrating to modern c# namespace
Using the short namesapce declaration for conciseness
This commit is contained in:
@@ -9,147 +9,146 @@ using Icarus.Controllers.Utilities;
|
||||
using Icarus.Models;
|
||||
using Icarus.Database.Contexts;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
public class AlbumManager : BaseManager
|
||||
{
|
||||
public class AlbumManager : BaseManager
|
||||
#region Fields
|
||||
private AlbumContext _albumContext;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public AlbumManager(IConfiguration config)
|
||||
{
|
||||
#region Fields
|
||||
private AlbumContext _albumContext;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public AlbumManager(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||
_albumContext = new AlbumContext(_connectionString);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void SaveAlbumToDatabase(ref Song song)
|
||||
{
|
||||
_logger.Info("Starting process to save the album record of the song to the database");
|
||||
|
||||
var album = new Album();
|
||||
|
||||
album.Title = song.AlbumTitle;
|
||||
album.AlbumArtist = song.Artist;
|
||||
album.Year = song.Year.Value;
|
||||
var albumTitle = song.AlbumTitle;
|
||||
var albumArtist = song.Artist;
|
||||
|
||||
var albumRetrieved = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(albumTitle) && alb.AlbumArtist.Equals(albumArtist));
|
||||
|
||||
if (albumRetrieved == null)
|
||||
{
|
||||
album.SongCount = 1;
|
||||
_albumContext.Add(album);
|
||||
_albumContext.SaveChanges();
|
||||
|
||||
Console.WriteLine($"Album Id {album.AlbumID}");
|
||||
}
|
||||
else
|
||||
{
|
||||
album.AlbumID = albumRetrieved.AlbumID;
|
||||
}
|
||||
|
||||
song.AlbumID = album.AlbumID;
|
||||
}
|
||||
|
||||
|
||||
public void DeleteAlbumFromDatabase(Song song)
|
||||
{
|
||||
var album = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(song.AlbumTitle));
|
||||
|
||||
if (album == null)
|
||||
{
|
||||
_logger.Info("Cannot delete the album record because it does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteAlbumFromDb(album);
|
||||
}
|
||||
|
||||
|
||||
public Album UpdateAlbumInDatabase(Song oldSong, Song newSong)
|
||||
{
|
||||
var albumRecord = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(oldSong.AlbumTitle));
|
||||
var oldAlbumTitle = oldSong.AlbumTitle;
|
||||
var oldAlbumArtist = oldSong.Artist;
|
||||
var newAlbumTitle = newSong.AlbumTitle;
|
||||
var newAlbumArtist = newSong.Artist;
|
||||
|
||||
var info = string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(newAlbumArtist))
|
||||
newAlbumArtist = oldAlbumArtist;
|
||||
if (string.IsNullOrEmpty(newAlbumTitle))
|
||||
newAlbumTitle = oldAlbumTitle;
|
||||
|
||||
if ((string.IsNullOrEmpty(newAlbumTitle) && string.IsNullOrEmpty(newAlbumArtist) ||
|
||||
oldAlbumTitle.Equals(newAlbumTitle) && oldAlbumArtist.Equals(newAlbumArtist)))
|
||||
{
|
||||
_logger.Info("No change to the song's album");
|
||||
return albumRecord;
|
||||
}
|
||||
|
||||
info = "Change to the song's album";
|
||||
_logger.Info(info);
|
||||
|
||||
var existingAlbumRecord = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(oldSong.AlbumTitle));
|
||||
if (existingAlbumRecord == null)
|
||||
{
|
||||
_logger.Info("Creating new album record");
|
||||
|
||||
var newAlbumRecord = new Album
|
||||
{
|
||||
Title = newAlbumTitle,
|
||||
AlbumArtist = newAlbumArtist,
|
||||
Year = newSong.Year.Value
|
||||
};
|
||||
|
||||
_albumContext.Add(newAlbumRecord);
|
||||
_albumContext.SaveChanges();
|
||||
|
||||
return newAlbumRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Updating existing album record");
|
||||
|
||||
existingAlbumRecord = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(newSong.AlbumTitle));
|
||||
existingAlbumRecord.AlbumArtist = newAlbumArtist;
|
||||
|
||||
_albumContext.Update(existingAlbumRecord);
|
||||
_albumContext.SaveChanges();
|
||||
|
||||
return existingAlbumRecord;
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteAlbumFromDb(Album album)
|
||||
{
|
||||
if (SongsInAlbum(album) <= 1)
|
||||
{
|
||||
_albumContext.Remove(album);
|
||||
_albumContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private int SongsInAlbum(Album album)
|
||||
{
|
||||
var sngContext = new SongContext(_connectionString);
|
||||
var songs = sngContext.Songs.Where(sng => sng.AlbumID == album.AlbumID).ToList();
|
||||
|
||||
return songs.Count;
|
||||
}
|
||||
#endregion
|
||||
_config = config;
|
||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||
_albumContext = new AlbumContext(_connectionString);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void SaveAlbumToDatabase(ref Song song)
|
||||
{
|
||||
_logger.Info("Starting process to save the album record of the song to the database");
|
||||
|
||||
var album = new Album();
|
||||
|
||||
album.Title = song.AlbumTitle;
|
||||
album.AlbumArtist = song.Artist;
|
||||
album.Year = song.Year.Value;
|
||||
var albumTitle = song.AlbumTitle;
|
||||
var albumArtist = song.Artist;
|
||||
|
||||
var albumRetrieved = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(albumTitle) && alb.AlbumArtist.Equals(albumArtist));
|
||||
|
||||
if (albumRetrieved == null)
|
||||
{
|
||||
album.SongCount = 1;
|
||||
_albumContext.Add(album);
|
||||
_albumContext.SaveChanges();
|
||||
|
||||
Console.WriteLine($"Album Id {album.AlbumID}");
|
||||
}
|
||||
else
|
||||
{
|
||||
album.AlbumID = albumRetrieved.AlbumID;
|
||||
}
|
||||
|
||||
song.AlbumID = album.AlbumID;
|
||||
}
|
||||
|
||||
|
||||
public void DeleteAlbumFromDatabase(Song song)
|
||||
{
|
||||
var album = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(song.AlbumTitle));
|
||||
|
||||
if (album == null)
|
||||
{
|
||||
_logger.Info("Cannot delete the album record because it does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteAlbumFromDb(album);
|
||||
}
|
||||
|
||||
|
||||
public Album UpdateAlbumInDatabase(Song oldSong, Song newSong)
|
||||
{
|
||||
var albumRecord = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(oldSong.AlbumTitle));
|
||||
var oldAlbumTitle = oldSong.AlbumTitle;
|
||||
var oldAlbumArtist = oldSong.Artist;
|
||||
var newAlbumTitle = newSong.AlbumTitle;
|
||||
var newAlbumArtist = newSong.Artist;
|
||||
|
||||
var info = string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(newAlbumArtist))
|
||||
newAlbumArtist = oldAlbumArtist;
|
||||
if (string.IsNullOrEmpty(newAlbumTitle))
|
||||
newAlbumTitle = oldAlbumTitle;
|
||||
|
||||
if ((string.IsNullOrEmpty(newAlbumTitle) && string.IsNullOrEmpty(newAlbumArtist) ||
|
||||
oldAlbumTitle.Equals(newAlbumTitle) && oldAlbumArtist.Equals(newAlbumArtist)))
|
||||
{
|
||||
_logger.Info("No change to the song's album");
|
||||
return albumRecord;
|
||||
}
|
||||
|
||||
info = "Change to the song's album";
|
||||
_logger.Info(info);
|
||||
|
||||
var existingAlbumRecord = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(oldSong.AlbumTitle));
|
||||
if (existingAlbumRecord == null)
|
||||
{
|
||||
_logger.Info("Creating new album record");
|
||||
|
||||
var newAlbumRecord = new Album
|
||||
{
|
||||
Title = newAlbumTitle,
|
||||
AlbumArtist = newAlbumArtist,
|
||||
Year = newSong.Year.Value
|
||||
};
|
||||
|
||||
_albumContext.Add(newAlbumRecord);
|
||||
_albumContext.SaveChanges();
|
||||
|
||||
return newAlbumRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Updating existing album record");
|
||||
|
||||
existingAlbumRecord = _albumContext.Albums.FirstOrDefault(alb => alb.Title.Equals(newSong.AlbumTitle));
|
||||
existingAlbumRecord.AlbumArtist = newAlbumArtist;
|
||||
|
||||
_albumContext.Update(existingAlbumRecord);
|
||||
_albumContext.SaveChanges();
|
||||
|
||||
return existingAlbumRecord;
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteAlbumFromDb(Album album)
|
||||
{
|
||||
if (SongsInAlbum(album) <= 1)
|
||||
{
|
||||
_albumContext.Remove(album);
|
||||
_albumContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private int SongsInAlbum(Album album)
|
||||
{
|
||||
var sngContext = new SongContext(_connectionString);
|
||||
var songs = sngContext.Songs.Where(sng => sng.AlbumID == album.AlbumID).ToList();
|
||||
|
||||
return songs.Count;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -9,129 +9,128 @@ using Icarus.Controllers.Utilities;
|
||||
using Icarus.Models;
|
||||
using Icarus.Database.Contexts;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
public class ArtistManager : BaseManager
|
||||
{
|
||||
public class ArtistManager : BaseManager
|
||||
#region Fields
|
||||
private ArtistContext _artistContext;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public ArtistManager(IConfiguration config)
|
||||
{
|
||||
#region Fields
|
||||
private ArtistContext _artistContext;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public ArtistManager(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||
_artistContext = new ArtistContext(_connectionString);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void SaveArtistToDatabase(ref Song song)
|
||||
{
|
||||
_logger.Info("Starting process to save the artist record of the song to the database");
|
||||
|
||||
var artist = new Artist();
|
||||
|
||||
artist.Name = song.Artist;
|
||||
artist.SongCount = 1;
|
||||
var artistTitle = artist.Name;
|
||||
|
||||
var artistRetrieved = _artistContext.Artists.FirstOrDefault(art => art.Name.Equals(artistTitle));
|
||||
|
||||
if (artistRetrieved == null)
|
||||
{
|
||||
artist.SongCount = 1;
|
||||
_artistContext.Add(artist);
|
||||
_artistContext.SaveChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
artist.ArtistID = artistRetrieved.ArtistID;
|
||||
}
|
||||
|
||||
song.ArtistID = artist.ArtistID;
|
||||
}
|
||||
|
||||
public Artist UpdateArtistInDatabase(Song oldSongRecord, Song newSongRecord)
|
||||
{
|
||||
var oldArtistRecord = _artistContext.Artists.FirstOrDefault(art => art.Name.Equals(oldSongRecord.AlbumTitle));
|
||||
var oldArtistName = oldArtistRecord.Name;
|
||||
var newArtistName = newSongRecord.Artist;
|
||||
|
||||
if (string.IsNullOrEmpty(newArtistName) || oldArtistName.Equals(newArtistName))
|
||||
{
|
||||
_logger.Info("No change to the song's Artist");
|
||||
return oldArtistRecord;
|
||||
}
|
||||
|
||||
_logger.Info("Change to the song's record found");
|
||||
|
||||
if (oldArtistRecord.SongCount <= 1)
|
||||
{
|
||||
_logger.Info("Deleting artist record that no longer has any songs");
|
||||
|
||||
_artistContext.Remove(oldArtistRecord);
|
||||
_artistContext.SaveChanges();
|
||||
}
|
||||
|
||||
if (!(_artistContext.Artists.FirstOrDefault(art => art.Name.Equals(oldSongRecord.AlbumTitle)) != null))
|
||||
{
|
||||
_logger.Info("Creating new artist record");
|
||||
|
||||
var newArtistRecord = new Artist
|
||||
{
|
||||
Name = newArtistName
|
||||
};
|
||||
|
||||
_artistContext.Add(newArtistRecord);
|
||||
_artistContext.SaveChanges();
|
||||
|
||||
return newArtistRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Updating existing artist record");
|
||||
|
||||
var existingArtistRecord = _artistContext.Artists.FirstOrDefault(art => art.Name.Equals(newSongRecord.AlbumTitle));
|
||||
|
||||
_artistContext.Update(existingArtistRecord);
|
||||
_artistContext.SaveChanges();
|
||||
|
||||
return existingArtistRecord;
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteArtistFromDatabase(Song song)
|
||||
{
|
||||
if (!(_artistContext.Artists.FirstOrDefault(art => art.Name.Equals(song.Artist)) != null))
|
||||
{
|
||||
_logger.Info("Cannot delete the artist record because it does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
var artist = _artistContext.Artists.FirstOrDefault(art => art.Name.Equals(song.Artist));
|
||||
|
||||
if (SongsOfArtist(artist) <= 1)
|
||||
{
|
||||
_artistContext.Remove(artist);
|
||||
_artistContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private int SongsOfArtist(Artist artist)
|
||||
{
|
||||
var sngContext = new SongContext(_connectionString);
|
||||
var songs = sngContext.Songs.Where(sng => sng.ArtistID == artist.ArtistID).ToList();
|
||||
|
||||
return songs.Count;
|
||||
}
|
||||
#endregion
|
||||
_config = config;
|
||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||
_artistContext = new ArtistContext(_connectionString);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void SaveArtistToDatabase(ref Song song)
|
||||
{
|
||||
_logger.Info("Starting process to save the artist record of the song to the database");
|
||||
|
||||
var artist = new Artist();
|
||||
|
||||
artist.Name = song.Artist;
|
||||
artist.SongCount = 1;
|
||||
var artistTitle = artist.Name;
|
||||
|
||||
var artistRetrieved = _artistContext.Artists.FirstOrDefault(art => art.Name.Equals(artistTitle));
|
||||
|
||||
if (artistRetrieved == null)
|
||||
{
|
||||
artist.SongCount = 1;
|
||||
_artistContext.Add(artist);
|
||||
_artistContext.SaveChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
artist.ArtistID = artistRetrieved.ArtistID;
|
||||
}
|
||||
|
||||
song.ArtistID = artist.ArtistID;
|
||||
}
|
||||
|
||||
public Artist UpdateArtistInDatabase(Song oldSongRecord, Song newSongRecord)
|
||||
{
|
||||
var oldArtistRecord = _artistContext.Artists.FirstOrDefault(art => art.Name.Equals(oldSongRecord.AlbumTitle));
|
||||
var oldArtistName = oldArtistRecord.Name;
|
||||
var newArtistName = newSongRecord.Artist;
|
||||
|
||||
if (string.IsNullOrEmpty(newArtistName) || oldArtistName.Equals(newArtistName))
|
||||
{
|
||||
_logger.Info("No change to the song's Artist");
|
||||
return oldArtistRecord;
|
||||
}
|
||||
|
||||
_logger.Info("Change to the song's record found");
|
||||
|
||||
if (oldArtistRecord.SongCount <= 1)
|
||||
{
|
||||
_logger.Info("Deleting artist record that no longer has any songs");
|
||||
|
||||
_artistContext.Remove(oldArtistRecord);
|
||||
_artistContext.SaveChanges();
|
||||
}
|
||||
|
||||
if (!(_artistContext.Artists.FirstOrDefault(art => art.Name.Equals(oldSongRecord.AlbumTitle)) != null))
|
||||
{
|
||||
_logger.Info("Creating new artist record");
|
||||
|
||||
var newArtistRecord = new Artist
|
||||
{
|
||||
Name = newArtistName
|
||||
};
|
||||
|
||||
_artistContext.Add(newArtistRecord);
|
||||
_artistContext.SaveChanges();
|
||||
|
||||
return newArtistRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Updating existing artist record");
|
||||
|
||||
var existingArtistRecord = _artistContext.Artists.FirstOrDefault(art => art.Name.Equals(newSongRecord.AlbumTitle));
|
||||
|
||||
_artistContext.Update(existingArtistRecord);
|
||||
_artistContext.SaveChanges();
|
||||
|
||||
return existingArtistRecord;
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteArtistFromDatabase(Song song)
|
||||
{
|
||||
if (!(_artistContext.Artists.FirstOrDefault(art => art.Name.Equals(song.Artist)) != null))
|
||||
{
|
||||
_logger.Info("Cannot delete the artist record because it does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
var artist = _artistContext.Artists.FirstOrDefault(art => art.Name.Equals(song.Artist));
|
||||
|
||||
if (SongsOfArtist(artist) <= 1)
|
||||
{
|
||||
_artistContext.Remove(artist);
|
||||
_artistContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private int SongsOfArtist(Artist artist)
|
||||
{
|
||||
var sngContext = new SongContext(_connectionString);
|
||||
var songs = sngContext.Songs.Where(sng => sng.ArtistID == artist.ArtistID).ToList();
|
||||
|
||||
return songs.Count;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -3,14 +3,13 @@ using System;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NLog;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
public class BaseManager
|
||||
{
|
||||
public class BaseManager
|
||||
{
|
||||
#region Fields
|
||||
protected static Logger _logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
||||
protected IConfiguration _config;
|
||||
protected string _connectionString;
|
||||
#endregion
|
||||
}
|
||||
#region Fields
|
||||
protected static Logger _logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
||||
protected IConfiguration _config;
|
||||
protected string _connectionString;
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -12,161 +12,160 @@ using Icarus.Database.Contexts;
|
||||
using Icarus.Models;
|
||||
using Icarus.Types;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
public class CoverArtManager : BaseManager
|
||||
{
|
||||
public class CoverArtManager : BaseManager
|
||||
#region Fields
|
||||
private string _rootCoverArtPath;
|
||||
private CoverArtContext _coverArtContext;
|
||||
private byte[] _stockCoverArt = null;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public CoverArtManager(IConfiguration config)
|
||||
{
|
||||
#region Fields
|
||||
private string _rootCoverArtPath;
|
||||
private CoverArtContext _coverArtContext;
|
||||
private byte[] _stockCoverArt = null;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public CoverArtManager(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||
_rootCoverArtPath = _config.GetValue<string>("CoverArtPath");
|
||||
Initialize();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void SaveCoverArtToDatabase(ref Song song, ref CoverArt coverArt)
|
||||
{
|
||||
_logger.Info("Saving cover art record to the database");
|
||||
_coverArtContext.Add(coverArt);
|
||||
_coverArtContext.SaveChanges();
|
||||
|
||||
song.CoverArtID = coverArt.CoverArtID;
|
||||
}
|
||||
public void DeleteCoverArtFromDatabase(CoverArt coverArt)
|
||||
{
|
||||
_logger.Info("Attempting to delete cover art from the database");
|
||||
|
||||
_coverArtContext.Remove(coverArt);
|
||||
_coverArtContext.SaveChanges();
|
||||
}
|
||||
public void DeleteCoverArt(CoverArt coverArt)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stockCoverArtPath = _rootCoverArtPath + "CoverArt.png";
|
||||
if (!string.Equals(stockCoverArtPath, coverArt.ImagePath,
|
||||
StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
_logger.Info("Song does not contain the stock cover art");
|
||||
File.Delete(coverArt.ImagePath);
|
||||
_logger.Info("Cover art deleted from the filesystem");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Song contains the stock cover art");
|
||||
_logger.Info("Will not delete from from the filesystem");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
}
|
||||
|
||||
public CoverArt SaveCoverArt(Song song)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dirMgr = new DirectoryManager(_rootCoverArtPath);
|
||||
var defaultExtension = ".png";
|
||||
dirMgr.CreateDirectory(song);
|
||||
|
||||
var coverArt = new CoverArt
|
||||
{
|
||||
SongTitle = song.Title
|
||||
};
|
||||
|
||||
var segment = coverArt.GenerateFilename(0);
|
||||
var imagePath = dirMgr.SongDirectory + segment + defaultExtension;
|
||||
|
||||
coverArt.ImagePath = imagePath;
|
||||
|
||||
var metaData = new MetadataRetriever();
|
||||
var imgBytes = metaData.RetrieveCoverArtBytes(song);
|
||||
|
||||
if (imgBytes != null)
|
||||
{
|
||||
_logger.Info("Saving cover art to the filesystem");
|
||||
File.WriteAllBytes(coverArt.ImagePath, imgBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Song has no cover art, applying stock cover art");
|
||||
coverArt.ImagePath = _rootCoverArtPath + $"{segment}{defaultExtension}";
|
||||
metaData.UpdateCoverArt(song, coverArt);
|
||||
File.WriteAllBytes(coverArt.ImagePath, _stockCoverArt);
|
||||
}
|
||||
|
||||
return coverArt;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public CoverArt SaveCoverArt(IFormFile data, Song song)
|
||||
{
|
||||
var cover = new CoverArt { SongTitle = song.Title };
|
||||
|
||||
try
|
||||
{
|
||||
var dirMgr = new DirectoryManager(_rootCoverArtPath);
|
||||
var defaultExtension = ".png";
|
||||
dirMgr.CreateDirectory(song);
|
||||
|
||||
var segment = cover.GenerateFilename(0);
|
||||
var imagePath = dirMgr.SongDirectory + segment + defaultExtension;
|
||||
|
||||
cover.ImagePath = imagePath;
|
||||
|
||||
using (var fileStream = new FileStream(imagePath, FileMode.Create))
|
||||
{
|
||||
data.CopyTo(fileStream);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex.Message, "An error occurred");
|
||||
}
|
||||
|
||||
return cover;
|
||||
}
|
||||
|
||||
public CoverArt GetCoverArt(Song song)
|
||||
{
|
||||
return _coverArtContext.CoverArtImages.FirstOrDefault(cov => cov.SongTitle.Equals(song.Title));
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
_coverArtContext = new CoverArtContext(_connectionString);
|
||||
|
||||
if (System.IO.File.Exists(DirectoryPaths.CoverArtPath))
|
||||
_stockCoverArt = File.ReadAllBytes(DirectoryPaths.CoverArtPath);
|
||||
|
||||
if (!File.Exists(_rootCoverArtPath + "CoverArt.png"))
|
||||
{
|
||||
File.WriteAllBytes(_rootCoverArtPath + "CoverArt.png",
|
||||
_stockCoverArt);
|
||||
Console.WriteLine("Copied Stock Cover Art");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
_config = config;
|
||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||
_rootCoverArtPath = _config.GetValue<string>("CoverArtPath");
|
||||
Initialize();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void SaveCoverArtToDatabase(ref Song song, ref CoverArt coverArt)
|
||||
{
|
||||
_logger.Info("Saving cover art record to the database");
|
||||
_coverArtContext.Add(coverArt);
|
||||
_coverArtContext.SaveChanges();
|
||||
|
||||
song.CoverArtID = coverArt.CoverArtID;
|
||||
}
|
||||
public void DeleteCoverArtFromDatabase(CoverArt coverArt)
|
||||
{
|
||||
_logger.Info("Attempting to delete cover art from the database");
|
||||
|
||||
_coverArtContext.Remove(coverArt);
|
||||
_coverArtContext.SaveChanges();
|
||||
}
|
||||
public void DeleteCoverArt(CoverArt coverArt)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stockCoverArtPath = _rootCoverArtPath + "CoverArt.png";
|
||||
if (!string.Equals(stockCoverArtPath, coverArt.ImagePath,
|
||||
StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
_logger.Info("Song does not contain the stock cover art");
|
||||
File.Delete(coverArt.ImagePath);
|
||||
_logger.Info("Cover art deleted from the filesystem");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Song contains the stock cover art");
|
||||
_logger.Info("Will not delete from from the filesystem");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
}
|
||||
|
||||
public CoverArt SaveCoverArt(Song song)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dirMgr = new DirectoryManager(_rootCoverArtPath);
|
||||
var defaultExtension = ".png";
|
||||
dirMgr.CreateDirectory(song);
|
||||
|
||||
var coverArt = new CoverArt
|
||||
{
|
||||
SongTitle = song.Title
|
||||
};
|
||||
|
||||
var segment = coverArt.GenerateFilename(0);
|
||||
var imagePath = dirMgr.SongDirectory + segment + defaultExtension;
|
||||
|
||||
coverArt.ImagePath = imagePath;
|
||||
|
||||
var metaData = new MetadataRetriever();
|
||||
var imgBytes = metaData.RetrieveCoverArtBytes(song);
|
||||
|
||||
if (imgBytes != null)
|
||||
{
|
||||
_logger.Info("Saving cover art to the filesystem");
|
||||
File.WriteAllBytes(coverArt.ImagePath, imgBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Song has no cover art, applying stock cover art");
|
||||
coverArt.ImagePath = _rootCoverArtPath + $"{segment}{defaultExtension}";
|
||||
metaData.UpdateCoverArt(song, coverArt);
|
||||
File.WriteAllBytes(coverArt.ImagePath, _stockCoverArt);
|
||||
}
|
||||
|
||||
return coverArt;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public CoverArt SaveCoverArt(IFormFile data, Song song)
|
||||
{
|
||||
var cover = new CoverArt { SongTitle = song.Title };
|
||||
|
||||
try
|
||||
{
|
||||
var dirMgr = new DirectoryManager(_rootCoverArtPath);
|
||||
var defaultExtension = ".png";
|
||||
dirMgr.CreateDirectory(song);
|
||||
|
||||
var segment = cover.GenerateFilename(0);
|
||||
var imagePath = dirMgr.SongDirectory + segment + defaultExtension;
|
||||
|
||||
cover.ImagePath = imagePath;
|
||||
|
||||
using (var fileStream = new FileStream(imagePath, FileMode.Create))
|
||||
{
|
||||
data.CopyTo(fileStream);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex.Message, "An error occurred");
|
||||
}
|
||||
|
||||
return cover;
|
||||
}
|
||||
|
||||
public CoverArt GetCoverArt(Song song)
|
||||
{
|
||||
return _coverArtContext.CoverArtImages.FirstOrDefault(cov => cov.SongTitle.Equals(song.Title));
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
_coverArtContext = new CoverArtContext(_connectionString);
|
||||
|
||||
if (System.IO.File.Exists(DirectoryPaths.CoverArtPath))
|
||||
_stockCoverArt = File.ReadAllBytes(DirectoryPaths.CoverArtPath);
|
||||
|
||||
if (!File.Exists(_rootCoverArtPath + "CoverArt.png"))
|
||||
{
|
||||
File.WriteAllBytes(_rootCoverArtPath + "CoverArt.png",
|
||||
_stockCoverArt);
|
||||
Console.WriteLine("Copied Stock Cover Art");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -7,226 +7,225 @@ using Microsoft.Extensions.Configuration;
|
||||
using Icarus.Models;
|
||||
using Icarus.Types;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
// NOTE: Do not use metadata for the song's metadata
|
||||
public class DirectoryManager : BaseManager
|
||||
{
|
||||
// NOTE: Do not use metadata for the song's metadata
|
||||
public class DirectoryManager : BaseManager
|
||||
#region Fields
|
||||
private Song _song;
|
||||
private string _rootSongDirectory;
|
||||
private string _songDirectory;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
public string SongDirectory
|
||||
{
|
||||
#region Fields
|
||||
private Song _song;
|
||||
private string _rootSongDirectory;
|
||||
private string _songDirectory;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
public string SongDirectory
|
||||
{
|
||||
get => _songDirectory;
|
||||
set => _songDirectory = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public DirectoryManager(IConfiguration config, Song song)
|
||||
{
|
||||
_config = config;
|
||||
_song = song;
|
||||
Initialize();
|
||||
}
|
||||
public DirectoryManager(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
Initialize();
|
||||
}
|
||||
public DirectoryManager(string rootDirectory)
|
||||
{
|
||||
_rootSongDirectory = rootDirectory;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void CreateDirectory()
|
||||
{
|
||||
CreateDirectory(_song);
|
||||
}
|
||||
public void CreateDirectory(Song song)
|
||||
{
|
||||
_song = song;
|
||||
|
||||
try
|
||||
{
|
||||
_songDirectory = AlbumDirectory();
|
||||
|
||||
if (!Directory.Exists(_songDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(_songDirectory);
|
||||
Console.WriteLine($"The directory has been created");
|
||||
}
|
||||
|
||||
Console.WriteLine($"The song will be saved in the following" +
|
||||
$" directory: {_songDirectory}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
}
|
||||
public void DeleteEmptyDirectories()
|
||||
{
|
||||
try
|
||||
{
|
||||
var albumDirectory = AlbumDirectory();
|
||||
var artistDirectory = ArtistDirectory();
|
||||
if (IsDirectoryEmpty(albumDirectory))
|
||||
{
|
||||
Directory.Delete(albumDirectory);
|
||||
Console.WriteLine($"directory {albumDirectory} deleted");
|
||||
}
|
||||
if (IsDirectoryEmpty(artistDirectory))
|
||||
{
|
||||
Directory.Delete(artistDirectory);
|
||||
Console.WriteLine($"directory {artistDirectory} deleted");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred {exMsg}");
|
||||
}
|
||||
}
|
||||
public void DeleteEmptyDirectories(Song song)
|
||||
{
|
||||
try
|
||||
{
|
||||
var albumDirectory = AlbumDirectory(song);
|
||||
var artistDirectory = ArtistDirectory(song);
|
||||
|
||||
if (IsDirectoryEmpty(albumDirectory))
|
||||
{
|
||||
Directory.Delete(albumDirectory);
|
||||
_logger.Info("Album directory deleted");
|
||||
}
|
||||
if (IsDirectoryEmpty(artistDirectory))
|
||||
{
|
||||
Directory.Delete(artistDirectory);
|
||||
_logger.Info("Artist directory deleted");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
}
|
||||
|
||||
public string RetrieveAlbumPath(Song song)
|
||||
{
|
||||
_logger.Info("Retrieving album song path");
|
||||
|
||||
var albumPath = string.Empty;
|
||||
albumPath = AlbumDirectory(song);
|
||||
|
||||
return albumPath;
|
||||
}
|
||||
public string RetrieveArtistPath(Song song)
|
||||
{
|
||||
_logger.Info("Retrieving artist path");
|
||||
|
||||
var artistPath = string.Empty;
|
||||
artistPath = ArtistDirectory(song);
|
||||
|
||||
return artistPath;
|
||||
}
|
||||
|
||||
public string GenerateSongPath(Song song)
|
||||
{
|
||||
_logger.Info("Generating song path");
|
||||
|
||||
var songPath = string.Empty;
|
||||
var artistPath = ArtistDirectory(song);
|
||||
var albumPath = AlbumDirectory(song);
|
||||
|
||||
if (!Directory.Exists(artistPath))
|
||||
{
|
||||
_logger.Info("Artist path does not exist");
|
||||
|
||||
Directory.CreateDirectory(artistPath);
|
||||
|
||||
_logger.Info("Creating artist path");
|
||||
}
|
||||
if (!Directory.Exists(albumPath))
|
||||
{
|
||||
_logger.Info("Album path does not exist");
|
||||
|
||||
Directory.CreateDirectory(albumPath);
|
||||
|
||||
_logger.Info("Created album path");
|
||||
}
|
||||
|
||||
songPath = albumPath;
|
||||
|
||||
return songPath;
|
||||
}
|
||||
|
||||
private void Initialize(DirectoryType dirTypes = DirectoryType.Music)
|
||||
{
|
||||
switch (dirTypes)
|
||||
{
|
||||
case DirectoryType.Music:
|
||||
_rootSongDirectory = _config.GetValue<string>("RootMusicPath");
|
||||
break;
|
||||
case DirectoryType.CoverArt:
|
||||
_rootSongDirectory = _config.GetValue<string>("CoverArtPath");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsDirectoryEmpty(string path)
|
||||
{
|
||||
return !Directory.EnumerateFileSystemEntries(path).Any();
|
||||
}
|
||||
|
||||
private string AlbumDirectory()
|
||||
{
|
||||
return AlbumDirectory(_song);
|
||||
}
|
||||
private string AlbumDirectory(Song song)
|
||||
{
|
||||
var directory = ArtistDirectory(song);
|
||||
var segment = SerializeValue(song.AlbumTitle);
|
||||
directory += $@"{segment}/";
|
||||
Console.WriteLine($"Album directory {directory}");
|
||||
|
||||
return directory;
|
||||
}
|
||||
private string ArtistDirectory()
|
||||
{
|
||||
return ArtistDirectory(_song);
|
||||
}
|
||||
private string ArtistDirectory(Song song)
|
||||
{
|
||||
var directory = _rootSongDirectory;
|
||||
var segment = SerializeValue(song.Artist);
|
||||
directory += $@"{segment}/";
|
||||
Console.WriteLine($"Artist directory {directory}");
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
private string SerializeValue(string value)
|
||||
{
|
||||
const int length = 15;
|
||||
const string chars = "ABCDEF0123456789";
|
||||
var random = new Random();
|
||||
var output = new string(Enumerable.Repeat(chars, length).Select(s =>
|
||||
s[random.Next(s.Length)]).ToArray());
|
||||
|
||||
return output;
|
||||
}
|
||||
#endregion
|
||||
get => _songDirectory;
|
||||
set => _songDirectory = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public DirectoryManager(IConfiguration config, Song song)
|
||||
{
|
||||
_config = config;
|
||||
_song = song;
|
||||
Initialize();
|
||||
}
|
||||
public DirectoryManager(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
Initialize();
|
||||
}
|
||||
public DirectoryManager(string rootDirectory)
|
||||
{
|
||||
_rootSongDirectory = rootDirectory;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void CreateDirectory()
|
||||
{
|
||||
CreateDirectory(_song);
|
||||
}
|
||||
public void CreateDirectory(Song song)
|
||||
{
|
||||
_song = song;
|
||||
|
||||
try
|
||||
{
|
||||
_songDirectory = AlbumDirectory();
|
||||
|
||||
if (!Directory.Exists(_songDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(_songDirectory);
|
||||
Console.WriteLine($"The directory has been created");
|
||||
}
|
||||
|
||||
Console.WriteLine($"The song will be saved in the following" +
|
||||
$" directory: {_songDirectory}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
}
|
||||
public void DeleteEmptyDirectories()
|
||||
{
|
||||
try
|
||||
{
|
||||
var albumDirectory = AlbumDirectory();
|
||||
var artistDirectory = ArtistDirectory();
|
||||
if (IsDirectoryEmpty(albumDirectory))
|
||||
{
|
||||
Directory.Delete(albumDirectory);
|
||||
Console.WriteLine($"directory {albumDirectory} deleted");
|
||||
}
|
||||
if (IsDirectoryEmpty(artistDirectory))
|
||||
{
|
||||
Directory.Delete(artistDirectory);
|
||||
Console.WriteLine($"directory {artistDirectory} deleted");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred {exMsg}");
|
||||
}
|
||||
}
|
||||
public void DeleteEmptyDirectories(Song song)
|
||||
{
|
||||
try
|
||||
{
|
||||
var albumDirectory = AlbumDirectory(song);
|
||||
var artistDirectory = ArtistDirectory(song);
|
||||
|
||||
if (IsDirectoryEmpty(albumDirectory))
|
||||
{
|
||||
Directory.Delete(albumDirectory);
|
||||
_logger.Info("Album directory deleted");
|
||||
}
|
||||
if (IsDirectoryEmpty(artistDirectory))
|
||||
{
|
||||
Directory.Delete(artistDirectory);
|
||||
_logger.Info("Artist directory deleted");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
}
|
||||
|
||||
public string RetrieveAlbumPath(Song song)
|
||||
{
|
||||
_logger.Info("Retrieving album song path");
|
||||
|
||||
var albumPath = string.Empty;
|
||||
albumPath = AlbumDirectory(song);
|
||||
|
||||
return albumPath;
|
||||
}
|
||||
public string RetrieveArtistPath(Song song)
|
||||
{
|
||||
_logger.Info("Retrieving artist path");
|
||||
|
||||
var artistPath = string.Empty;
|
||||
artistPath = ArtistDirectory(song);
|
||||
|
||||
return artistPath;
|
||||
}
|
||||
|
||||
public string GenerateSongPath(Song song)
|
||||
{
|
||||
_logger.Info("Generating song path");
|
||||
|
||||
var songPath = string.Empty;
|
||||
var artistPath = ArtistDirectory(song);
|
||||
var albumPath = AlbumDirectory(song);
|
||||
|
||||
if (!Directory.Exists(artistPath))
|
||||
{
|
||||
_logger.Info("Artist path does not exist");
|
||||
|
||||
Directory.CreateDirectory(artistPath);
|
||||
|
||||
_logger.Info("Creating artist path");
|
||||
}
|
||||
if (!Directory.Exists(albumPath))
|
||||
{
|
||||
_logger.Info("Album path does not exist");
|
||||
|
||||
Directory.CreateDirectory(albumPath);
|
||||
|
||||
_logger.Info("Created album path");
|
||||
}
|
||||
|
||||
songPath = albumPath;
|
||||
|
||||
return songPath;
|
||||
}
|
||||
|
||||
private void Initialize(DirectoryType dirTypes = DirectoryType.Music)
|
||||
{
|
||||
switch (dirTypes)
|
||||
{
|
||||
case DirectoryType.Music:
|
||||
_rootSongDirectory = _config.GetValue<string>("RootMusicPath");
|
||||
break;
|
||||
case DirectoryType.CoverArt:
|
||||
_rootSongDirectory = _config.GetValue<string>("CoverArtPath");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsDirectoryEmpty(string path)
|
||||
{
|
||||
return !Directory.EnumerateFileSystemEntries(path).Any();
|
||||
}
|
||||
|
||||
private string AlbumDirectory()
|
||||
{
|
||||
return AlbumDirectory(_song);
|
||||
}
|
||||
private string AlbumDirectory(Song song)
|
||||
{
|
||||
var directory = ArtistDirectory(song);
|
||||
var segment = SerializeValue(song.AlbumTitle);
|
||||
directory += $@"{segment}/";
|
||||
Console.WriteLine($"Album directory {directory}");
|
||||
|
||||
return directory;
|
||||
}
|
||||
private string ArtistDirectory()
|
||||
{
|
||||
return ArtistDirectory(_song);
|
||||
}
|
||||
private string ArtistDirectory(Song song)
|
||||
{
|
||||
var directory = _rootSongDirectory;
|
||||
var segment = SerializeValue(song.Artist);
|
||||
directory += $@"{segment}/";
|
||||
Console.WriteLine($"Artist directory {directory}");
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
private string SerializeValue(string value)
|
||||
{
|
||||
const int length = 15;
|
||||
const string chars = "ABCDEF0123456789";
|
||||
var random = new Random();
|
||||
var output = new string(Enumerable.Repeat(chars, length).Select(s =>
|
||||
s[random.Next(s.Length)]).ToArray());
|
||||
|
||||
return output;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -9,129 +9,128 @@ using Icarus.Controllers.Utilities;
|
||||
using Icarus.Models;
|
||||
using Icarus.Database.Contexts;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
public class GenreManager : BaseManager
|
||||
{
|
||||
public class GenreManager : BaseManager
|
||||
#region Fields
|
||||
private GenreContext _genreContext;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public GenreManager(IConfiguration config)
|
||||
{
|
||||
#region Fields
|
||||
private GenreContext _genreContext;
|
||||
#endregion
|
||||
_config = config;
|
||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||
_genreContext = new GenreContext(_connectionString);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
#region Methods
|
||||
public void SaveGenreToDatabase(ref Song song)
|
||||
{
|
||||
_logger.Info("Starting process to save the genre record of the song to the database");
|
||||
|
||||
|
||||
#region Constructors
|
||||
public GenreManager(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||
_genreContext = new GenreContext(_connectionString);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void SaveGenreToDatabase(ref Song song)
|
||||
var genre = new Genre
|
||||
{
|
||||
_logger.Info("Starting process to save the genre record of the song to the database");
|
||||
GenreName = song.Genre,
|
||||
SongCount = 1
|
||||
};
|
||||
|
||||
var genre = new Genre
|
||||
var genreName = song.Genre;
|
||||
var genreRetrieved = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(genreName));
|
||||
|
||||
if (genreRetrieved == null)
|
||||
{
|
||||
_genreContext.Add(genre);
|
||||
_genreContext.SaveChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
genre.GenreID = genreRetrieved.GenreID;
|
||||
}
|
||||
|
||||
song.GenreID = genre.GenreID;
|
||||
}
|
||||
|
||||
public Genre UpdateGenreInDatabase(Song oldSongRecord, Song newSongRecord)
|
||||
{
|
||||
var oldGenreRecord = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(oldSongRecord.Genre));
|
||||
var oldGenreName = oldGenreRecord.GenreName;
|
||||
var newGenreName = newSongRecord.Genre;
|
||||
|
||||
if (string.IsNullOrEmpty(newGenreName) || oldGenreName.Equals(newGenreName))
|
||||
{
|
||||
_logger.Info("No change to the song's Genre");
|
||||
return oldGenreRecord;
|
||||
}
|
||||
|
||||
_logger.Info("Change to the song's genre found");
|
||||
|
||||
if (oldGenreRecord.SongCount <= 1)
|
||||
{
|
||||
_logger.Info("Deleting genre record");
|
||||
|
||||
_genreContext.Remove(oldGenreRecord);
|
||||
_genreContext.SaveChanges();
|
||||
}
|
||||
|
||||
if (!(_genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(oldSongRecord.Genre)) != null))
|
||||
{
|
||||
_logger.Info("Creating new genre record");
|
||||
|
||||
var newGenreRecord = new Genre
|
||||
{
|
||||
GenreName = song.Genre,
|
||||
SongCount = 1
|
||||
GenreName = newGenreName
|
||||
};
|
||||
|
||||
var genreName = song.Genre;
|
||||
var genreRetrieved = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(genreName));
|
||||
_genreContext.Add(newGenreRecord);
|
||||
_genreContext.SaveChanges();
|
||||
|
||||
if (genreRetrieved == null)
|
||||
{
|
||||
_genreContext.Add(genre);
|
||||
_genreContext.SaveChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
genre.GenreID = genreRetrieved.GenreID;
|
||||
}
|
||||
|
||||
song.GenreID = genre.GenreID;
|
||||
return newGenreRecord;
|
||||
}
|
||||
|
||||
public Genre UpdateGenreInDatabase(Song oldSongRecord, Song newSongRecord)
|
||||
else
|
||||
{
|
||||
var oldGenreRecord = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(oldSongRecord.Genre));
|
||||
var oldGenreName = oldGenreRecord.GenreName;
|
||||
var newGenreName = newSongRecord.Genre;
|
||||
_logger.Info("Updating existing genre record");
|
||||
|
||||
if (string.IsNullOrEmpty(newGenreName) || oldGenreName.Equals(newGenreName))
|
||||
{
|
||||
_logger.Info("No change to the song's Genre");
|
||||
return oldGenreRecord;
|
||||
}
|
||||
var existingGenreRecord = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(oldGenreRecord.GenreName));
|
||||
|
||||
_logger.Info("Change to the song's genre found");
|
||||
_genreContext.Update(existingGenreRecord);
|
||||
_genreContext.SaveChanges();
|
||||
|
||||
if (oldGenreRecord.SongCount <= 1)
|
||||
{
|
||||
_logger.Info("Deleting genre record");
|
||||
|
||||
_genreContext.Remove(oldGenreRecord);
|
||||
_genreContext.SaveChanges();
|
||||
}
|
||||
|
||||
if (!(_genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(oldSongRecord.Genre)) != null))
|
||||
{
|
||||
_logger.Info("Creating new genre record");
|
||||
|
||||
var newGenreRecord = new Genre
|
||||
{
|
||||
GenreName = newGenreName
|
||||
};
|
||||
|
||||
_genreContext.Add(newGenreRecord);
|
||||
_genreContext.SaveChanges();
|
||||
|
||||
return newGenreRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Updating existing genre record");
|
||||
|
||||
var existingGenreRecord = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(oldGenreRecord.GenreName));
|
||||
|
||||
_genreContext.Update(existingGenreRecord);
|
||||
_genreContext.SaveChanges();
|
||||
|
||||
return existingGenreRecord;
|
||||
}
|
||||
return existingGenreRecord;
|
||||
}
|
||||
|
||||
public void DeleteGenreFromDatabase(Song song)
|
||||
{
|
||||
if (!(_genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(song.Genre)) != null))
|
||||
{
|
||||
_logger.Info("Cannot delete the genre record because it does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
var genre = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(song.Genre));
|
||||
|
||||
if (SongsInGenre(genre) <= 1)
|
||||
{
|
||||
_genreContext.Remove(genre);
|
||||
_genreContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private int SongsInGenre(Genre genre)
|
||||
{
|
||||
var sngContext = new SongContext(_connectionString);
|
||||
var songs = sngContext.Songs.Where(sng => sng.GenreID == genre.GenreID).ToList();
|
||||
|
||||
return songs.Count;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public void DeleteGenreFromDatabase(Song song)
|
||||
{
|
||||
if (!(_genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(song.Genre)) != null))
|
||||
{
|
||||
_logger.Info("Cannot delete the genre record because it does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
var genre = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(song.Genre));
|
||||
|
||||
if (SongsInGenre(genre) <= 1)
|
||||
{
|
||||
_genreContext.Remove(genre);
|
||||
_genreContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private int SongsInGenre(Genre genre)
|
||||
{
|
||||
var sngContext = new SongContext(_connectionString);
|
||||
var songs = sngContext.Songs.Where(sng => sng.GenreID == genre.GenreID).ToList();
|
||||
|
||||
return songs.Count;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
+418
-419
@@ -15,493 +15,492 @@ using Icarus.Controllers.Utilities;
|
||||
using Icarus.Models;
|
||||
using Icarus.Database.Contexts;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
public class SongManager : BaseManager
|
||||
{
|
||||
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
|
||||
{
|
||||
#region Fields
|
||||
private string _tempDirectoryRoot;
|
||||
private string _archiveDirectoryRoot;
|
||||
private string _compressedSongFilename;
|
||||
private string _message;
|
||||
private SongContext _songContext;
|
||||
#endregion
|
||||
get => _archiveDirectoryRoot;
|
||||
set => _archiveDirectoryRoot = value;
|
||||
}
|
||||
public string CompressedSongFilename
|
||||
{
|
||||
get => _compressedSongFilename;
|
||||
set => _compressedSongFilename = value;
|
||||
}
|
||||
public string Message
|
||||
{
|
||||
get => _message;
|
||||
set => _message = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
public string ArchiveDirectoryRoot
|
||||
#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))
|
||||
{
|
||||
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.AlbumID;
|
||||
|
||||
var updatedArtist = artMgr.UpdateArtistInDatabase(oldSongRecord, updatedSong);
|
||||
oldSongRecord.ArtistID = updatedArtist.ArtistID;
|
||||
|
||||
var updatedGenre = gnrMgr.UpdateGenreInDatabase(oldSongRecord, updatedSong);
|
||||
oldSongRecord.GenreID = updatedGenre.GenreID;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
result.SongTitle = song.Title;
|
||||
result.Message = "Song does not exist";
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool DeleteSongFromFileSystem(Song songMetaData)
|
||||
try
|
||||
{
|
||||
bool successful = false;
|
||||
try
|
||||
{
|
||||
var songPath = songMetaData.SongPath();
|
||||
System.IO.File.Delete(songPath);
|
||||
successful = true;
|
||||
DirectoryManager dirMgr = new DirectoryManager(_config, songMetaData);
|
||||
dirMgr.DeleteEmptyDirectories();
|
||||
Console.WriteLine("Song successfully deleted");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
}
|
||||
var oldSongRecord = _songContext.RetrieveRecord(song);
|
||||
song.Filename = oldSongRecord.Filename;
|
||||
song.SongDirectory = oldSongRecord.SongDirectory;
|
||||
|
||||
return successful;
|
||||
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.AlbumID;
|
||||
|
||||
var updatedArtist = artMgr.UpdateArtistInDatabase(oldSongRecord, updatedSong);
|
||||
oldSongRecord.ArtistID = updatedArtist.ArtistID;
|
||||
|
||||
var updatedGenre = gnrMgr.UpdateGenreInDatabase(oldSongRecord, updatedSong);
|
||||
oldSongRecord.GenreID = updatedGenre.GenreID;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public bool DoesSongExist(Song song)
|
||||
{
|
||||
if (!_songContext.DoesRecordExist(song))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return true;
|
||||
public bool DeleteSongFromFileSystem(Song songMetaData)
|
||||
{
|
||||
bool successful = false;
|
||||
try
|
||||
{
|
||||
var songPath = songMetaData.SongPath();
|
||||
System.IO.File.Delete(songPath);
|
||||
successful = true;
|
||||
DirectoryManager dirMgr = new DirectoryManager(_config, songMetaData);
|
||||
dirMgr.DeleteEmptyDirectories();
|
||||
Console.WriteLine("Song successfully deleted");
|
||||
}
|
||||
public void DeleteSong(Song song)
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DeleteSongFromFilesystem(song))
|
||||
{
|
||||
_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);
|
||||
|
||||
coverMgr.DeleteCoverArtFromDatabase(coverArt);
|
||||
DeleteSongFromDatabase(song);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
var exMsg = ex.Message;
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
public async Task SaveSongToFileSystem(IFormFile songFile)
|
||||
public bool DoesSongExist(Song song)
|
||||
{
|
||||
if (!_songContext.DoesRecordExist(song))
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Info("Starting the process of saving the song to the filesystem");
|
||||
|
||||
var song = await SaveSongTemp(songFile);
|
||||
|
||||
DirectoryManager dirMgr = new DirectoryManager(_config, song);
|
||||
dirMgr.CreateDirectory();
|
||||
|
||||
var tempPath = song.SongPath();
|
||||
song.Filename = song.GenerateFilename(1);
|
||||
var filePath = $"{dirMgr.SongDirectory}{song.Filename}";
|
||||
|
||||
_logger.Info($"Absolute song path: {filePath}");
|
||||
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
var songBytes = System.IO.File.ReadAllBytes(tempPath);
|
||||
|
||||
_logger.Info("Saving song to the filesystem");
|
||||
fileStream.Write(songBytes, 0, songBytes.Count());
|
||||
|
||||
System.IO.File.Delete(tempPath);
|
||||
_logger.Info("Deleting temp file");
|
||||
|
||||
_logger.Info("Song successfully saved to filesystem");
|
||||
}
|
||||
});
|
||||
|
||||
song.SongDirectory = dirMgr.SongDirectory;
|
||||
|
||||
var coverMgr = new CoverArtManager(_config);
|
||||
var coverArt = coverMgr.SaveCoverArt(song);
|
||||
|
||||
coverMgr.SaveCoverArtToDatabase(ref song, ref coverArt);
|
||||
SaveSongToDatabase(song);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SaveSongToFileSystem(IFormFile songFile, IFormFile coverArtData, Song song)
|
||||
return true;
|
||||
}
|
||||
public void DeleteSong(Song song)
|
||||
{
|
||||
try
|
||||
{
|
||||
song.SongDirectory = _tempDirectoryRoot;
|
||||
song.DateCreated = DateTime.Now;
|
||||
|
||||
if (string.IsNullOrEmpty(song.Filename))
|
||||
if (DeleteSongFromFilesystem(song))
|
||||
{
|
||||
song.Filename = song.GenerateFilename(1);
|
||||
}
|
||||
|
||||
_logger.Info($"Temporary directory: {_tempDirectoryRoot}");
|
||||
|
||||
var tempPath = song.SongPath();
|
||||
|
||||
_logger.Info("Temporary song path: {0}", tempPath);
|
||||
|
||||
using (var filestream = new FileStream(tempPath, FileMode.Create))
|
||||
{
|
||||
_logger.Info("Saving song to temporary directory");
|
||||
songFile.CopyTo(filestream);
|
||||
_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 meta = new MetadataRetriever();
|
||||
var coverArt = coverMgr.SaveCoverArt(coverArtData, song);
|
||||
meta.UpdateCoverArt(song, coverArt);
|
||||
song.Duration = meta.RetrieveSongDuration(song.SongPath());
|
||||
|
||||
meta.UpdateMetadata(song, song);
|
||||
var coverArt = coverMgr.GetCoverArt(song);
|
||||
coverMgr.DeleteCoverArt(coverArt);
|
||||
|
||||
coverMgr.DeleteCoverArtFromDatabase(coverArt);
|
||||
DeleteSongFromDatabase(song);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task SaveSongToFileSystem(IFormFile songFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Info("Starting the process of saving the song to the filesystem");
|
||||
|
||||
var song = await SaveSongTemp(songFile);
|
||||
|
||||
DirectoryManager dirMgr = new DirectoryManager(_config, song);
|
||||
dirMgr.CreateDirectory();
|
||||
|
||||
song.SongDirectory = dirMgr.SongDirectory;
|
||||
var tempPath = song.SongPath();
|
||||
song.Filename = song.GenerateFilename(1);
|
||||
var filePath = $"{dirMgr.SongDirectory}{song.Filename}";
|
||||
|
||||
var filePath = song.SongPath();
|
||||
_logger.Info($"Absolute song path: {filePath}");
|
||||
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
var songBytes = System.IO.File.ReadAllBytes(tempPath);
|
||||
|
||||
try
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
if (System.IO.File.Exists(filePath) && System.IO.File.Exists(tempPath) && fileStream.Length > 0)
|
||||
{
|
||||
System.IO.File.Delete(tempPath);
|
||||
_logger.Info("Deleted temp song from filesystem: {0}", tempPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileStream.Write(songBytes, 0, songBytes.Count());
|
||||
_logger.Info("Saved song to filesystem: {0}", filePath);
|
||||
var songBytes = System.IO.File.ReadAllBytes(tempPath);
|
||||
|
||||
System.IO.File.Delete(tempPath);
|
||||
_logger.Info("Deleted temp song from filesystem: {0}", tempPath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error($"An error occurred: {msg}");
|
||||
}
|
||||
_logger.Info("Saving song to the filesystem");
|
||||
fileStream.Write(songBytes, 0, songBytes.Count());
|
||||
|
||||
_logger.Info("Song successfully saved to filesystem");
|
||||
}
|
||||
System.IO.File.Delete(tempPath);
|
||||
_logger.Info("Deleting temp file");
|
||||
|
||||
_logger.Info("Song successfully saved to filesystem");
|
||||
}
|
||||
});
|
||||
|
||||
song.SongDirectory = dirMgr.SongDirectory;
|
||||
|
||||
var coverMgr = new CoverArtManager(_config);
|
||||
var coverArt = coverMgr.SaveCoverArt(song);
|
||||
|
||||
coverMgr.SaveCoverArtToDatabase(ref song, ref coverArt);
|
||||
SaveSongToDatabase(song);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<SongData> RetrieveSong(Song songMetaData)
|
||||
catch (Exception ex)
|
||||
{
|
||||
var song = new SongData();
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred");
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveSongToFileSystem(IFormFile songFile, IFormFile coverArtData, Song song)
|
||||
{
|
||||
song.SongDirectory = _tempDirectoryRoot;
|
||||
song.DateCreated = DateTime.Now;
|
||||
|
||||
if (string.IsNullOrEmpty(song.Filename))
|
||||
{
|
||||
song.Filename = song.GenerateFilename(1);
|
||||
}
|
||||
|
||||
_logger.Info($"Temporary directory: {_tempDirectoryRoot}");
|
||||
|
||||
var tempPath = song.SongPath();
|
||||
|
||||
_logger.Info("Temporary song path: {0}", tempPath);
|
||||
|
||||
using (var filestream = new FileStream(tempPath, FileMode.Create))
|
||||
{
|
||||
_logger.Info("Saving song to temporary directory");
|
||||
songFile.CopyTo(filestream);
|
||||
}
|
||||
|
||||
var coverMgr = new CoverArtManager(_config);
|
||||
var meta = new MetadataRetriever();
|
||||
var coverArt = coverMgr.SaveCoverArt(coverArtData, song);
|
||||
meta.UpdateCoverArt(song, coverArt);
|
||||
song.Duration = meta.RetrieveSongDuration(song.SongPath());
|
||||
|
||||
meta.UpdateMetadata(song, song);
|
||||
|
||||
|
||||
DirectoryManager dirMgr = new DirectoryManager(_config, song);
|
||||
dirMgr.CreateDirectory();
|
||||
|
||||
song.SongDirectory = dirMgr.SongDirectory;
|
||||
|
||||
var filePath = song.SongPath();
|
||||
_logger.Info($"Absolute song path: {filePath}");
|
||||
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
var songBytes = System.IO.File.ReadAllBytes(tempPath);
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Fetching song from filesystem");
|
||||
song = await RetrieveSongFromFileSystem(songMetaData);
|
||||
if (System.IO.File.Exists(filePath) && System.IO.File.Exists(tempPath) && fileStream.Length > 0)
|
||||
{
|
||||
System.IO.File.Delete(tempPath);
|
||||
_logger.Info("Deleted temp song from filesystem: {0}", tempPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileStream.Write(songBytes, 0, songBytes.Count());
|
||||
_logger.Info("Saved song to filesystem: {0}", filePath);
|
||||
|
||||
System.IO.File.Delete(tempPath);
|
||||
_logger.Info("Deleted temp song from filesystem: {0}", tempPath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
var msg = ex.Message;
|
||||
_logger.Error($"An error occurred: {msg}");
|
||||
}
|
||||
|
||||
return song;
|
||||
_logger.Info("Song successfully saved to filesystem");
|
||||
}
|
||||
|
||||
coverMgr.SaveCoverArtToDatabase(ref song, ref coverArt);
|
||||
SaveSongToDatabase(song);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<SongData> RetrieveSong(Song songMetaData)
|
||||
{
|
||||
var song = new SongData();
|
||||
|
||||
private async Task<SongData> RetrieveSongFromFileSystem(Song details)
|
||||
try
|
||||
{
|
||||
byte[] uncompressedSong = await System.IO.File.ReadAllBytesAsync(details.SongPath());
|
||||
|
||||
return new SongData
|
||||
{
|
||||
Data = uncompressedSong
|
||||
};
|
||||
Console.WriteLine("Fetching song from filesystem");
|
||||
song = await RetrieveSongFromFileSystem(songMetaData);
|
||||
}
|
||||
private async Task<Song> SaveSongTemp(IFormFile songFile)
|
||||
catch (Exception ex)
|
||||
{
|
||||
var song = new Song();
|
||||
_logger.Info("Assigning song filename");
|
||||
song.SongDirectory = _tempDirectoryRoot;
|
||||
var filename = song.GenerateFilename(1);
|
||||
song.Filename = filename;
|
||||
|
||||
using (var filestream = new FileStream(song.SongPath(), FileMode.Create))
|
||||
{
|
||||
_logger.Info("Saving temp song: {0}", song.SongPath());
|
||||
await songFile.CopyToAsync(filestream);
|
||||
}
|
||||
await Task.Run(() =>
|
||||
{
|
||||
MetadataRetriever meta = new MetadataRetriever();
|
||||
song = meta.RetrieveMetaData(song.SongPath());
|
||||
});
|
||||
|
||||
song.SongDirectory = _tempDirectoryRoot;
|
||||
song.DateCreated = DateTime.Now;
|
||||
song.Filename = filename;
|
||||
|
||||
return song;
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
|
||||
return song;
|
||||
}
|
||||
|
||||
private bool SongRecordChanged(Song currentSong, Song songUpdates)
|
||||
|
||||
|
||||
private async Task<SongData> RetrieveSongFromFileSystem(Song details)
|
||||
{
|
||||
byte[] uncompressedSong = await System.IO.File.ReadAllBytesAsync(details.SongPath());
|
||||
|
||||
return new SongData
|
||||
{
|
||||
var currentTitle = currentSong.Title;
|
||||
var currentArtist = currentSong.Artist;
|
||||
var currentAlbum = currentSong.AlbumTitle;
|
||||
var currentGenre = currentSong.Genre;
|
||||
var currentYear = currentSong.Year;
|
||||
Data = uncompressedSong
|
||||
};
|
||||
}
|
||||
private async Task<Song> SaveSongTemp(IFormFile songFile)
|
||||
{
|
||||
var song = new Song();
|
||||
_logger.Info("Assigning song filename");
|
||||
song.SongDirectory = _tempDirectoryRoot;
|
||||
var filename = song.GenerateFilename(1);
|
||||
song.Filename = filename;
|
||||
|
||||
if (!currentTitle.Equals(songUpdates.Title) || !currentArtist.Equals(songUpdates.Artist) ||
|
||||
!currentAlbum.Equals(songUpdates.AlbumTitle) ||
|
||||
!currentGenre.Equals(songUpdates.Genre) || currentYear != songUpdates.Year)
|
||||
return true;
|
||||
using (var filestream = new FileStream(song.SongPath(), FileMode.Create))
|
||||
{
|
||||
_logger.Info("Saving temp song: {0}", song.SongPath());
|
||||
await songFile.CopyToAsync(filestream);
|
||||
}
|
||||
await Task.Run(() =>
|
||||
{
|
||||
MetadataRetriever meta = new MetadataRetriever();
|
||||
song = meta.RetrieveMetaData(song.SongPath());
|
||||
});
|
||||
|
||||
song.SongDirectory = _tempDirectoryRoot;
|
||||
song.DateCreated = DateTime.Now;
|
||||
song.Filename = filename;
|
||||
|
||||
return song;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
_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);
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
private bool DeleteSongFromFilesystem(Song song)
|
||||
{
|
||||
var songPath = song.SongPath();
|
||||
|
||||
_logger.Info("Deleting song from the filesystem");
|
||||
|
||||
try
|
||||
{
|
||||
System.IO.File.Delete(songPath);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
private void DeleteEmptyDirectories(ref Song oldSong, ref Song updatedSong)
|
||||
{
|
||||
DirectoryManager mgr = new DirectoryManager(_config);
|
||||
_logger.Info("Song exists on the filesystem");
|
||||
|
||||
_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)
|
||||
{
|
||||
_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);
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
private bool DeleteSongFromFilesystem(Song song)
|
||||
{
|
||||
var songPath = song.SongPath();
|
||||
|
||||
_logger.Info("Deleting song from the filesystem");
|
||||
|
||||
try
|
||||
{
|
||||
System.IO.File.Delete(songPath);
|
||||
}
|
||||
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);
|
||||
albumMgr.DeleteAlbumFromDatabase(song);
|
||||
artistMgr.DeleteArtistFromDatabase(song);
|
||||
genreMgr.DeleteGenreFromDatabase(song);
|
||||
|
||||
var sngContext = new SongContext(_connectionString);
|
||||
sngContext.Songs.Remove(song);
|
||||
sngContext.SaveChanges();
|
||||
}
|
||||
#endregion
|
||||
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);
|
||||
albumMgr.DeleteAlbumFromDatabase(song);
|
||||
artistMgr.DeleteArtistFromDatabase(song);
|
||||
genreMgr.DeleteGenreFromDatabase(song);
|
||||
|
||||
var sngContext = new SongContext(_connectionString);
|
||||
sngContext.Songs.Remove(song);
|
||||
sngContext.SaveChanges();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -16,395 +16,393 @@ using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.OpenSsl;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
using RestSharp;
|
||||
|
||||
using Icarus.Models;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
#region Classes
|
||||
public class TokenManager : BaseManager
|
||||
{
|
||||
#region Classes
|
||||
public class TokenManager : BaseManager
|
||||
#region Fields
|
||||
private string _clientId;
|
||||
private string _clientSecret;
|
||||
private string _privateKeyPath = string.Empty;
|
||||
private string _privateKey = string.Empty;
|
||||
private string _publicKeyPath = string.Empty;
|
||||
private string _publicKey = string.Empty;
|
||||
private string _audience;
|
||||
private string _grantType;
|
||||
private string _url;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public TokenManager(IConfiguration config)
|
||||
{
|
||||
#region Fields
|
||||
private string _clientId;
|
||||
private string _clientSecret;
|
||||
private string _privateKeyPath = string.Empty;
|
||||
private string _privateKey = string.Empty;
|
||||
private string _publicKeyPath = string.Empty;
|
||||
private string _publicKey = string.Empty;
|
||||
private string _audience;
|
||||
private string _grantType;
|
||||
private string _url;
|
||||
#endregion
|
||||
_config = config;
|
||||
InitializeValues();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
#region Methods
|
||||
public LoginResult RetrieveLoginResult(User user)
|
||||
{
|
||||
_logger.Info("Preparing Auth0 API request");
|
||||
|
||||
var client = new RestClient(_url);
|
||||
var request = new RestRequest("oauth/token", Method.POST);
|
||||
var tokenRequest = RetrieveTokenRequest();
|
||||
|
||||
_logger.Info("Serializing token object into JSON");
|
||||
var tokenObject = JsonConvert.SerializeObject(tokenRequest);
|
||||
|
||||
request.AddParameter("application/json; charset=utf-8",
|
||||
tokenObject, ParameterType.RequestBody);
|
||||
|
||||
request.RequestFormat = DataFormat.Json;
|
||||
|
||||
_logger.Info("Sending request");
|
||||
IRestResponse response = client.Execute(request);
|
||||
_logger.Info("Response received");
|
||||
|
||||
|
||||
#region Constructors
|
||||
public TokenManager(IConfiguration config)
|
||||
_logger.Info("Deserializing response");
|
||||
var tokenResult = JsonConvert
|
||||
.DeserializeObject<TokenTierOne>(response.Content);
|
||||
_logger.Info("Response deserialized");
|
||||
|
||||
return new LoginResult
|
||||
{
|
||||
_config = config;
|
||||
InitializeValues();
|
||||
}
|
||||
#endregion
|
||||
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||
Message = "Successfully retrieved token"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#region Methods
|
||||
public LoginResult RetrieveLoginResult(User user)
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
public LoginResult LogIn(User user)
|
||||
{
|
||||
var tokenResult = new TokenTierOne();
|
||||
tokenResult.TokenType = "Jwt";
|
||||
|
||||
var privateKey = ReadKeyContent(_privateKeyPath).Result;
|
||||
var publicKey = ReadKeyContent(_publicKeyPath).Result;
|
||||
|
||||
var payload = Payload();
|
||||
|
||||
var token = CreateToken(payload, privateKey);
|
||||
tokenResult.AccessToken = token;
|
||||
|
||||
var expClaim = payload.FirstOrDefault(cl =>
|
||||
{
|
||||
_logger.Info("Preparing Auth0 API request");
|
||||
return cl.Type.Equals("exp");
|
||||
});
|
||||
|
||||
var client = new RestClient(_url);
|
||||
var request = new RestRequest("oauth/token", Method.POST);
|
||||
var tokenRequest = RetrieveTokenRequest();
|
||||
tokenResult.Expiration = System.Convert.ToInt32(expClaim.Value);
|
||||
|
||||
_logger.Info("Serializing token object into JSON");
|
||||
var tokenObject = JsonConvert.SerializeObject(tokenRequest);
|
||||
|
||||
request.AddParameter("application/json; charset=utf-8",
|
||||
tokenObject, ParameterType.RequestBody);
|
||||
|
||||
request.RequestFormat = DataFormat.Json;
|
||||
|
||||
_logger.Info("Sending request");
|
||||
IRestResponse response = client.Execute(request);
|
||||
_logger.Info("Response received");
|
||||
|
||||
|
||||
_logger.Info("Deserializing response");
|
||||
var tokenResult = JsonConvert
|
||||
.DeserializeObject<TokenTierOne>(response.Content);
|
||||
_logger.Info("Response deserialized");
|
||||
|
||||
return new LoginResult
|
||||
{
|
||||
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||
Message = "Successfully retrieved token"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
public LoginResult LogIn(User user)
|
||||
return new LoginResult
|
||||
{
|
||||
var tokenResult = new TokenTierOne();
|
||||
tokenResult.TokenType = "Jwt";
|
||||
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||
Message = "Successfully retrieved token"
|
||||
};
|
||||
}
|
||||
|
||||
var privateKey = ReadKeyContent(_privateKeyPath).Result;
|
||||
var publicKey = ReadKeyContent(_publicKeyPath).Result;
|
||||
public LoginResult LoginSymmetric(User user)
|
||||
{
|
||||
var tokenResult = new TokenTierOne();
|
||||
tokenResult.TokenType = "Jwt";
|
||||
|
||||
var payload = Payload();
|
||||
var payload = Payload();
|
||||
payload.Add(new System.Security.Claims.Claim("user_id", user.UserID.ToString(), ClaimValueTypes.Integer));
|
||||
|
||||
var token = CreateToken(payload, privateKey);
|
||||
tokenResult.AccessToken = token;
|
||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JWT:Secret"]));
|
||||
var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||
var token = new JwtSecurityToken(
|
||||
_config["JWT:Issuer"],
|
||||
_config["JWT:Audience"],
|
||||
payload,
|
||||
expires: DateTime.UtcNow.AddMinutes(30),
|
||||
signingCredentials: signIn);
|
||||
|
||||
tokenResult.AccessToken = new JwtSecurityTokenHandler().WriteToken(token);
|
||||
|
||||
var expClaim = payload.FirstOrDefault(cl =>
|
||||
{
|
||||
return cl.Type.Equals("exp");
|
||||
});
|
||||
|
||||
tokenResult.Expiration = System.Convert.ToInt32(expClaim.Value);
|
||||
|
||||
return new LoginResult
|
||||
{
|
||||
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||
Message = "Successfully retrieved token"
|
||||
};
|
||||
}
|
||||
|
||||
public LoginResult LoginSymmetric(User user)
|
||||
var expClaim = payload.FirstOrDefault(cl =>
|
||||
{
|
||||
var tokenResult = new TokenTierOne();
|
||||
tokenResult.TokenType = "Jwt";
|
||||
return cl.Type.Equals("exp");
|
||||
});
|
||||
|
||||
var payload = Payload();
|
||||
payload.Add(new System.Security.Claims.Claim("user_id", user.UserID.ToString(), ClaimValueTypes.Integer));
|
||||
var expiredDate = DateTime.Parse(expClaim.Value);
|
||||
var exp = Math.Floor((expiredDate - DateTime.UnixEpoch).TotalSeconds);
|
||||
tokenResult.Expiration = Convert.ToInt32(exp);
|
||||
|
||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JWT:Secret"]));
|
||||
var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||
var token = new JwtSecurityToken(
|
||||
_config["JWT:Issuer"],
|
||||
_config["JWT:Audience"],
|
||||
payload,
|
||||
expires: DateTime.UtcNow.AddMinutes(30),
|
||||
signingCredentials: signIn);
|
||||
|
||||
tokenResult.AccessToken = new JwtSecurityTokenHandler().WriteToken(token);
|
||||
|
||||
var expClaim = payload.FirstOrDefault(cl =>
|
||||
{
|
||||
return cl.Type.Equals("exp");
|
||||
});
|
||||
|
||||
var expiredDate = DateTime.Parse(expClaim.Value);
|
||||
var exp = Math.Floor((expiredDate - DateTime.UnixEpoch).TotalSeconds);
|
||||
tokenResult.Expiration = Convert.ToInt32(exp);
|
||||
|
||||
return new LoginResult
|
||||
{
|
||||
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||
Message = "Successfully retrieved token"
|
||||
};
|
||||
}
|
||||
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
public bool IsTokenValid(string scope, string accessToken)
|
||||
return new LoginResult
|
||||
{
|
||||
var result = false;
|
||||
var token = DecodeToken(accessToken);
|
||||
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||
Message = "Successfully retrieved token"
|
||||
};
|
||||
}
|
||||
|
||||
if (token == null || token.Erroneous())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = (!token.TokenExpired() && token.ContainsScope(scope)) ? true : false;
|
||||
|
||||
// What would make a token valid?
|
||||
// 1. The expiration date must be before the current date
|
||||
// 2. The desired scope must be part of the scopes within the access token
|
||||
// 3. Must be able to be decoded
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
public bool IsTokenValid(string scope, string accessToken)
|
||||
{
|
||||
var result = false;
|
||||
var token = DecodeToken(accessToken);
|
||||
|
||||
if (token == null || token.Erroneous())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
public Token DecodeToken(string accessToken)
|
||||
result = (!token.TokenExpired() && token.ContainsScope(scope)) ? true : false;
|
||||
|
||||
// What would make a token valid?
|
||||
// 1. The expiration date must be before the current date
|
||||
// 2. The desired scope must be part of the scopes within the access token
|
||||
// 3. Must be able to be decoded
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
public Token DecodeToken(string accessToken)
|
||||
{
|
||||
var rsaParams = GetRSAPublic(_publicKey);
|
||||
Token tok = null;
|
||||
|
||||
try
|
||||
{
|
||||
var rsaParams = GetRSAPublic(_publicKey);
|
||||
Token tok = null;
|
||||
|
||||
try
|
||||
using (var rsa = new RSACryptoServiceProvider())
|
||||
{
|
||||
using (var rsa = new RSACryptoServiceProvider())
|
||||
{
|
||||
rsa.ImportParameters(rsaParams);
|
||||
rsa.ImportParameters(rsaParams);
|
||||
|
||||
IJsonSerializer serializer = new JsonNetSerializer();
|
||||
IDateTimeProvider provider = new UtcDateTimeProvider();
|
||||
IJwtValidator validator = new JwtValidator(serializer, provider);
|
||||
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
|
||||
var algorithm = new JWT.Algorithms.RS256Algorithm(rsa);
|
||||
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
|
||||
|
||||
var json = decoder.Decode(accessToken);
|
||||
tok = JsonConvert.DeserializeObject<Token>(json);
|
||||
}
|
||||
IJsonSerializer serializer = new JsonNetSerializer();
|
||||
IDateTimeProvider provider = new UtcDateTimeProvider();
|
||||
IJwtValidator validator = new JwtValidator(serializer, provider);
|
||||
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
|
||||
var algorithm = new JWT.Algorithms.RS256Algorithm(rsa);
|
||||
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
|
||||
|
||||
var json = decoder.Decode(accessToken);
|
||||
tok = JsonConvert.DeserializeObject<Token>(json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error("An error occurred: {0}", ex.Message);
|
||||
}
|
||||
|
||||
|
||||
return tok;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error("An error occurred: {0}", ex.Message);
|
||||
}
|
||||
|
||||
|
||||
private string AllScopes()
|
||||
return tok;
|
||||
}
|
||||
|
||||
|
||||
private string AllScopes()
|
||||
{
|
||||
var allScopes = new List<String>()
|
||||
{
|
||||
var allScopes = new List<String>()
|
||||
{
|
||||
"download:songs",
|
||||
"read:song_details",
|
||||
"upload:songs",
|
||||
"delete:songs",
|
||||
"read:albums",
|
||||
"read:artists",
|
||||
"update:songs",
|
||||
"stream:songs",
|
||||
"read:genre",
|
||||
"read:year",
|
||||
"download:cover_art"
|
||||
};
|
||||
"download:songs",
|
||||
"read:song_details",
|
||||
"upload:songs",
|
||||
"delete:songs",
|
||||
"read:albums",
|
||||
"read:artists",
|
||||
"update:songs",
|
||||
"stream:songs",
|
||||
"read:genre",
|
||||
"read:year",
|
||||
"download:cover_art"
|
||||
};
|
||||
|
||||
var scopes = string.Empty;
|
||||
var scopes = string.Empty;
|
||||
|
||||
for (var i = 0; i < allScopes.Count; i++)
|
||||
for (var i = 0; i < allScopes.Count; i++)
|
||||
{
|
||||
if (i == allScopes.Count - 1)
|
||||
{
|
||||
if (i == allScopes.Count - 1)
|
||||
scopes += allScopes[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
scopes += allScopes[i] + " ";
|
||||
}
|
||||
}
|
||||
|
||||
return scopes;
|
||||
}
|
||||
|
||||
private List<Claim> Payload()
|
||||
{
|
||||
var expLimit = 30;
|
||||
var currentDate = DateTime.Now;
|
||||
var expiredDate = currentDate.AddMinutes(expLimit);
|
||||
var issued = Math.Floor((currentDate - DateTime.UnixEpoch).TotalSeconds);
|
||||
var expires = Math.Floor((expiredDate - DateTime.UnixEpoch).TotalSeconds);
|
||||
var issuer = "https://soaricarus.auth0.com";
|
||||
issuer = "http://localhost:5002";
|
||||
var audience = "https://icarus/api";
|
||||
audience = "http://localhost:5002";
|
||||
var subject = _config["JWT:Subject"];
|
||||
|
||||
var claim = new List<System.Security.Claims.Claim>()
|
||||
{
|
||||
new System.Security.Claims.Claim("scope", AllScopes(), "string"),
|
||||
new System.Security.Claims.Claim(JwtRegisteredClaimNames.Exp, expiredDate.ToString()),
|
||||
new System.Security.Claims.Claim(JwtRegisteredClaimNames.Aud, audience),
|
||||
new System.Security.Claims.Claim(JwtRegisteredClaimNames.Iss, issuer),
|
||||
new Claim(JwtRegisteredClaimNames.Sub, subject),
|
||||
new System.Security.Claims.Claim(JwtRegisteredClaimNames.Iat, currentDate.ToString())
|
||||
};
|
||||
|
||||
return claim;
|
||||
}
|
||||
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
private string CreateToken(List<Claim> claims, string privateKey)
|
||||
{
|
||||
var token = string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(privateKey))
|
||||
{
|
||||
privateKey = ReadKeyContent(_privateKeyPath).Result;
|
||||
}
|
||||
|
||||
RSAParameters rsaParams;
|
||||
using (var tr = new System.IO.StringReader(privateKey))
|
||||
{
|
||||
var pemReader = new PemReader(tr);
|
||||
var keyPair = pemReader.ReadObject() as AsymmetricCipherKeyPair;
|
||||
if (keyPair == null)
|
||||
{
|
||||
throw new Exception("Could not read RSA private key");
|
||||
}
|
||||
var privateRsaParams = keyPair.Private as RsaPrivateCrtKeyParameters;
|
||||
rsaParams = DotNetUtilities.ToRSAParameters(privateRsaParams);
|
||||
}
|
||||
|
||||
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
|
||||
{
|
||||
var rsaParamsPublic = GetRSAPublic(ReadKeyContent(_publicKeyPath).Result);
|
||||
var rsaPublic = new RSACryptoServiceProvider();
|
||||
|
||||
rsa.ImportParameters(rsaParams);
|
||||
rsaPublic.ImportParameters(rsaParamsPublic);
|
||||
|
||||
Dictionary<string, object> payload = new Dictionary<string, object>();
|
||||
|
||||
foreach (var claim in claims)
|
||||
{
|
||||
var type = claim.Type;
|
||||
var val = Int32.TryParse(claim.Value, out _);
|
||||
|
||||
if (val)
|
||||
{
|
||||
scopes += allScopes[i];
|
||||
payload.Add(type, Convert.ToInt32(claim.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
scopes += allScopes[i] + " ";
|
||||
}
|
||||
}
|
||||
|
||||
return scopes;
|
||||
}
|
||||
|
||||
private List<Claim> Payload()
|
||||
{
|
||||
var expLimit = 30;
|
||||
var currentDate = DateTime.Now;
|
||||
var expiredDate = currentDate.AddMinutes(expLimit);
|
||||
var issued = Math.Floor((currentDate - DateTime.UnixEpoch).TotalSeconds);
|
||||
var expires = Math.Floor((expiredDate - DateTime.UnixEpoch).TotalSeconds);
|
||||
var issuer = "https://soaricarus.auth0.com";
|
||||
issuer = "http://localhost:5002";
|
||||
var audience = "https://icarus/api";
|
||||
audience = "http://localhost:5002";
|
||||
var subject = _config["JWT:Subject"];
|
||||
|
||||
var claim = new List<System.Security.Claims.Claim>()
|
||||
{
|
||||
new System.Security.Claims.Claim("scope", AllScopes(), "string"),
|
||||
new System.Security.Claims.Claim(JwtRegisteredClaimNames.Exp, expiredDate.ToString()),
|
||||
new System.Security.Claims.Claim(JwtRegisteredClaimNames.Aud, audience),
|
||||
new System.Security.Claims.Claim(JwtRegisteredClaimNames.Iss, issuer),
|
||||
new Claim(JwtRegisteredClaimNames.Sub, subject),
|
||||
new System.Security.Claims.Claim(JwtRegisteredClaimNames.Iat, currentDate.ToString())
|
||||
};
|
||||
|
||||
return claim;
|
||||
}
|
||||
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
private string CreateToken(List<Claim> claims, string privateKey)
|
||||
{
|
||||
var token = string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(privateKey))
|
||||
{
|
||||
privateKey = ReadKeyContent(_privateKeyPath).Result;
|
||||
}
|
||||
|
||||
RSAParameters rsaParams;
|
||||
using (var tr = new System.IO.StringReader(privateKey))
|
||||
{
|
||||
var pemReader = new PemReader(tr);
|
||||
var keyPair = pemReader.ReadObject() as AsymmetricCipherKeyPair;
|
||||
if (keyPair == null)
|
||||
{
|
||||
throw new Exception("Could not read RSA private key");
|
||||
}
|
||||
var privateRsaParams = keyPair.Private as RsaPrivateCrtKeyParameters;
|
||||
rsaParams = DotNetUtilities.ToRSAParameters(privateRsaParams);
|
||||
}
|
||||
|
||||
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
|
||||
{
|
||||
var rsaParamsPublic = GetRSAPublic(ReadKeyContent(_publicKeyPath).Result);
|
||||
var rsaPublic = new RSACryptoServiceProvider();
|
||||
|
||||
rsa.ImportParameters(rsaParams);
|
||||
rsaPublic.ImportParameters(rsaParamsPublic);
|
||||
|
||||
Dictionary<string, object> payload = new Dictionary<string, object>();
|
||||
|
||||
foreach (var claim in claims)
|
||||
{
|
||||
var type = claim.Type;
|
||||
var val = Int32.TryParse(claim.Value, out _);
|
||||
|
||||
if (val)
|
||||
{
|
||||
payload.Add(type, Convert.ToInt32(claim.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
payload.Add(type, claim.Value);
|
||||
}
|
||||
|
||||
payload.Add(type, claim.Value);
|
||||
}
|
||||
|
||||
var algorithm = new JWT.Algorithms.RS256Algorithm(rsaPublic, rsa);
|
||||
IJsonSerializer serializer = new JsonNetSerializer();
|
||||
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
|
||||
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
|
||||
|
||||
token = encoder.Encode(payload, privateKey);
|
||||
}
|
||||
|
||||
return token;
|
||||
var algorithm = new JWT.Algorithms.RS256Algorithm(rsaPublic, rsa);
|
||||
IJsonSerializer serializer = new JsonNetSerializer();
|
||||
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
|
||||
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
|
||||
|
||||
token = encoder.Encode(payload, privateKey);
|
||||
}
|
||||
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
private RSAParameters GetRSAPublic(string publicKey)
|
||||
return token;
|
||||
}
|
||||
|
||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||
private RSAParameters GetRSAPublic(string publicKey)
|
||||
{
|
||||
using (var tr = new System.IO.StringReader(publicKey))
|
||||
{
|
||||
using (var tr = new System.IO.StringReader(publicKey))
|
||||
var pemReader = new PemReader(tr);
|
||||
var publicKeyParams = pemReader.ReadObject() as RsaKeyParameters;
|
||||
if (publicKeyParams == null)
|
||||
{
|
||||
var pemReader = new PemReader(tr);
|
||||
var publicKeyParams = pemReader.ReadObject() as RsaKeyParameters;
|
||||
if (publicKeyParams == null)
|
||||
{
|
||||
throw new Exception("Could not read RSA public key");
|
||||
}
|
||||
return DotNetUtilities.ToRSAParameters(publicKeyParams);
|
||||
throw new Exception("Could not read RSA public key");
|
||||
}
|
||||
return DotNetUtilities.ToRSAParameters(publicKeyParams);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> ReadKeyContent(string filepath)
|
||||
private async Task<string> ReadKeyContent(string filepath)
|
||||
{
|
||||
return await System.IO.File.ReadAllTextAsync(filepath);
|
||||
}
|
||||
|
||||
private TokenRequest RetrieveTokenRequest()
|
||||
{
|
||||
_logger.Info("Retrieving token object");
|
||||
|
||||
return new TokenRequest
|
||||
{
|
||||
return await System.IO.File.ReadAllTextAsync(filepath);
|
||||
}
|
||||
|
||||
private TokenRequest RetrieveTokenRequest()
|
||||
{
|
||||
_logger.Info("Retrieving token object");
|
||||
ClientId = _clientId, ClientSecret = _clientSecret,
|
||||
Audience = _audience, GrantType = _grantType
|
||||
};
|
||||
}
|
||||
|
||||
return new TokenRequest
|
||||
{
|
||||
ClientId = _clientId, ClientSecret = _clientSecret,
|
||||
Audience = _audience, GrantType = _grantType
|
||||
};
|
||||
}
|
||||
private void InitializeValues()
|
||||
{
|
||||
_logger.Info("Analyzing Auth0 information");
|
||||
|
||||
private void InitializeValues()
|
||||
{
|
||||
_logger.Info("Analyzing Auth0 information");
|
||||
_clientId = _config["Auth0:ClientId"];
|
||||
_clientSecret = _config["Auth0:ClientSecret"];
|
||||
_audience = _config["Auth0:ApiIdentifier"];
|
||||
_grantType = "client_credentials";
|
||||
_url = $"https://{_config["Auth0:Domain"]}";
|
||||
}
|
||||
|
||||
_clientId = _config["Auth0:ClientId"];
|
||||
_clientSecret = _config["Auth0:ClientSecret"];
|
||||
_audience = _config["Auth0:ApiIdentifier"];
|
||||
_grantType = "client_credentials";
|
||||
_url = $"https://{_config["Auth0:Domain"]}";
|
||||
}
|
||||
|
||||
#region Testing Methods
|
||||
// For testing purposes
|
||||
private void PrintCredentials()
|
||||
{
|
||||
Console.WriteLine("Auth0 credentials:");
|
||||
Console.WriteLine($"Client Id: {_clientId}");
|
||||
Console.WriteLine($"Client Secret: {_clientSecret}");
|
||||
Console.WriteLine($"Audience: {_audience}");
|
||||
Console.WriteLine($"Url: {_url}");
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Testing Methods
|
||||
// For testing purposes
|
||||
private void PrintCredentials()
|
||||
{
|
||||
Console.WriteLine("Auth0 credentials:");
|
||||
Console.WriteLine($"Client Id: {_clientId}");
|
||||
Console.WriteLine($"Client Secret: {_clientSecret}");
|
||||
Console.WriteLine($"Audience: {_audience}");
|
||||
Console.WriteLine($"Url: {_url}");
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
||||
#region Classes
|
||||
private class TokenRequest
|
||||
{
|
||||
[JsonProperty("client_id")]
|
||||
public string ClientId { get; set; }
|
||||
[JsonProperty("client_secret")]
|
||||
public string ClientSecret { get; set; }
|
||||
[JsonProperty("audience")]
|
||||
public string Audience { get; set; }
|
||||
[JsonProperty("grant_type")]
|
||||
public string GrantType { get; set; }
|
||||
}
|
||||
private class TokenTierOne
|
||||
{
|
||||
[JsonProperty("access_token")]
|
||||
public string AccessToken { get; set; }
|
||||
[JsonProperty("expires_in")]
|
||||
public int Expiration { get; set; }
|
||||
[JsonProperty("token_type")]
|
||||
public string TokenType { get; set; }
|
||||
}
|
||||
#endregion
|
||||
#region Classes
|
||||
private class TokenRequest
|
||||
{
|
||||
[JsonProperty("client_id")]
|
||||
public string ClientId { get; set; }
|
||||
[JsonProperty("client_secret")]
|
||||
public string ClientSecret { get; set; }
|
||||
[JsonProperty("audience")]
|
||||
public string Audience { get; set; }
|
||||
[JsonProperty("grant_type")]
|
||||
public string GrantType { get; set; }
|
||||
}
|
||||
private class TokenTierOne
|
||||
{
|
||||
[JsonProperty("access_token")]
|
||||
public string AccessToken { get; set; }
|
||||
[JsonProperty("expires_in")]
|
||||
public int Expiration { get; set; }
|
||||
[JsonProperty("token_type")]
|
||||
public string TokenType { get; set; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
Reference in New Issue
Block a user