Migrating to modern c# namespace
Using the short namesapce declaration for conciseness
This commit is contained in:
@@ -6,26 +6,25 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
|
|
||||||
using Icarus.Authorization;
|
using Icarus.Authorization;
|
||||||
|
|
||||||
namespace Icarus.Authorization.Handlers
|
namespace Icarus.Authorization.Handlers;
|
||||||
|
|
||||||
|
public class HasScopeHandler : AuthorizationHandler<HasScopeRequirement>
|
||||||
{
|
{
|
||||||
public class HasScopeHandler : AuthorizationHandler<HasScopeRequirement>
|
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasScopeRequirement requirement)
|
||||||
{
|
{
|
||||||
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasScopeRequirement requirement)
|
if (!context.User.HasClaim(c => c.Type == "scope" && c.Issuer == requirement.Issuer))
|
||||||
{
|
{
|
||||||
if (!context.User.HasClaim(c => c.Type == "scope" && c.Issuer == requirement.Issuer))
|
|
||||||
{
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
var scopes = context.User.FindFirst(c =>
|
|
||||||
c.Type == "scope" && c.Issuer == requirement.Issuer).Value.Split(' ');
|
|
||||||
|
|
||||||
if (scopes.Any(s => s == requirement.Scope))
|
|
||||||
{
|
|
||||||
context.Succeed(requirement);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var scopes = context.User.FindFirst(c =>
|
||||||
|
c.Type == "scope" && c.Issuer == requirement.Issuer).Value.Split(' ');
|
||||||
|
|
||||||
|
if (scopes.Any(s => s == requirement.Scope))
|
||||||
|
{
|
||||||
|
context.Succeed(requirement);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,18 +2,17 @@ using System;
|
|||||||
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
namespace Icarus.Authorization
|
namespace Icarus.Authorization;
|
||||||
|
|
||||||
|
public class HasScopeRequirement : IAuthorizationRequirement
|
||||||
{
|
{
|
||||||
public class HasScopeRequirement : IAuthorizationRequirement
|
public string Issuer { get; }
|
||||||
|
public string Scope { get; }
|
||||||
|
|
||||||
|
|
||||||
|
public HasScopeRequirement(string scope, string issuer)
|
||||||
{
|
{
|
||||||
public string Issuer { get; }
|
Scope = scope ?? throw new ArgumentNullException(nameof(scope));
|
||||||
public string Scope { get; }
|
Issuer = issuer ?? throw new ArgumentNullException(nameof(issuer));
|
||||||
|
|
||||||
|
|
||||||
public HasScopeRequirement(string scope, string issuer)
|
|
||||||
{
|
|
||||||
Scope = scope ?? throw new ArgumentNullException(nameof(scope));
|
|
||||||
Issuer = issuer ?? throw new ArgumentNullException(nameof(issuer));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+60
-61
@@ -6,75 +6,74 @@ using Org.BouncyCastle.Crypto.Parameters;
|
|||||||
using Org.BouncyCastle.OpenSsl;
|
using Org.BouncyCastle.OpenSsl;
|
||||||
|
|
||||||
|
|
||||||
namespace Icarus.Certs
|
namespace Icarus.Certs;
|
||||||
|
|
||||||
|
public class SigningIssuerCertificate : IDisposable
|
||||||
{
|
{
|
||||||
public class SigningIssuerCertificate : IDisposable
|
private readonly RSACryptoServiceProvider _rsa;
|
||||||
|
|
||||||
|
public SigningIssuerCertificate()
|
||||||
{
|
{
|
||||||
private readonly RSACryptoServiceProvider _rsa;
|
_rsa = new RSACryptoServiceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
public SigningIssuerCertificate()
|
public RsaSecurityKey GetIssuerSigningKey(string publicKeyPath)
|
||||||
|
{
|
||||||
|
var file = publicKeyPath;
|
||||||
|
var publicKey = System.IO.File.ReadAllText(file);
|
||||||
|
|
||||||
|
using (var reader = System.IO.File.OpenText(file))
|
||||||
{
|
{
|
||||||
_rsa = new RSACryptoServiceProvider();
|
var pem = new PemReader(reader);
|
||||||
|
var o = (RsaKeyParameters)pem.ReadObject();
|
||||||
|
var parameters = new RSAParameters();
|
||||||
|
parameters.Modulus = o.Modulus.ToByteArray();
|
||||||
|
parameters.Exponent = o.Exponent.ToByteArray();
|
||||||
|
_rsa.ImportParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RsaSecurityKey GetIssuerSigningKey(string publicKeyPath)
|
return new RsaSecurityKey(_rsa);
|
||||||
{
|
|
||||||
var file = publicKeyPath;
|
|
||||||
var publicKey = System.IO.File.ReadAllText(file);
|
|
||||||
|
|
||||||
using (var reader = System.IO.File.OpenText(file))
|
|
||||||
{
|
|
||||||
var pem = new PemReader(reader);
|
|
||||||
var o = (RsaKeyParameters)pem.ReadObject();
|
|
||||||
var parameters = new RSAParameters();
|
|
||||||
parameters.Modulus = o.Modulus.ToByteArray();
|
|
||||||
parameters.Exponent = o.Exponent.ToByteArray();
|
|
||||||
_rsa.ImportParameters(parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RsaSecurityKey(_rsa);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_rsa?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class SigningAudienceCertificate : IDisposable
|
public void Dispose()
|
||||||
{
|
{
|
||||||
private readonly RSACryptoServiceProvider _rsa;
|
_rsa?.Dispose();
|
||||||
|
|
||||||
public SigningAudienceCertificate()
|
|
||||||
{
|
|
||||||
_rsa = new RSACryptoServiceProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SigningCredentials GetAudienceSigningKey(string keyPath)
|
|
||||||
{
|
|
||||||
var file = keyPath;
|
|
||||||
var publicKey = System.IO.File.ReadAllText(file);
|
|
||||||
|
|
||||||
using (var reader = System.IO.File.OpenText(file))
|
|
||||||
{
|
|
||||||
var pem = new PemReader(reader);
|
|
||||||
var o = (RsaKeyParameters)pem.ReadObject();
|
|
||||||
var parameters = new RSAParameters();
|
|
||||||
parameters.Modulus = o.Modulus.ToByteArray();
|
|
||||||
parameters.Exponent = o.Exponent.ToByteArray();
|
|
||||||
_rsa.ImportParameters(parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SigningCredentials(
|
|
||||||
key: new RsaSecurityKey(_rsa),
|
|
||||||
algorithm: SecurityAlgorithms.RsaSha256);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_rsa?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SigningAudienceCertificate : IDisposable
|
||||||
|
{
|
||||||
|
private readonly RSACryptoServiceProvider _rsa;
|
||||||
|
|
||||||
|
public SigningAudienceCertificate()
|
||||||
|
{
|
||||||
|
_rsa = new RSACryptoServiceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SigningCredentials GetAudienceSigningKey(string keyPath)
|
||||||
|
{
|
||||||
|
var file = keyPath;
|
||||||
|
var publicKey = System.IO.File.ReadAllText(file);
|
||||||
|
|
||||||
|
using (var reader = System.IO.File.OpenText(file))
|
||||||
|
{
|
||||||
|
var pem = new PemReader(reader);
|
||||||
|
var o = (RsaKeyParameters)pem.ReadObject();
|
||||||
|
var parameters = new RSAParameters();
|
||||||
|
parameters.Modulus = o.Modulus.ToByteArray();
|
||||||
|
parameters.Exponent = o.Exponent.ToByteArray();
|
||||||
|
_rsa.ImportParameters(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SigningCredentials(
|
||||||
|
key: new RsaSecurityKey(_rsa),
|
||||||
|
algorithm: SecurityAlgorithms.RsaSha256);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_rsa?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Icarus.Constants
|
namespace Icarus.Constants;
|
||||||
|
|
||||||
|
public class DirectoryPaths
|
||||||
{
|
{
|
||||||
public class DirectoryPaths
|
public static string CoverArtPath =>
|
||||||
{
|
Directory.GetCurrentDirectory() + "/Images/Stock/CoverArt.png";
|
||||||
public static string CoverArtPath =>
|
|
||||||
Directory.GetCurrentDirectory() + "/Images/Stock/CoverArt.png";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,147 +9,146 @@ using Icarus.Controllers.Utilities;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
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
|
_config = config;
|
||||||
private AlbumContext _albumContext;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
_albumContext = new AlbumContext(_connectionString);
|
||||||
|
|
||||||
|
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
|
#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.Models;
|
||||||
using Icarus.Database.Contexts;
|
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
|
_config = config;
|
||||||
private ArtistContext _artistContext;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
_artistContext = new ArtistContext(_connectionString);
|
||||||
|
|
||||||
|
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
|
#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 Microsoft.Extensions.Configuration;
|
||||||
using NLog;
|
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();
|
||||||
#region Fields
|
protected IConfiguration _config;
|
||||||
protected static Logger _logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
protected string _connectionString;
|
||||||
protected IConfiguration _config;
|
#endregion
|
||||||
protected string _connectionString;
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,161 +12,160 @@ using Icarus.Database.Contexts;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Types;
|
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
|
_config = config;
|
||||||
private string _rootCoverArtPath;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
private CoverArtContext _coverArtContext;
|
_rootCoverArtPath = _config.GetValue<string>("CoverArtPath");
|
||||||
private byte[] _stockCoverArt = null;
|
Initialize();
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
|
#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.Models;
|
||||||
using Icarus.Types;
|
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
|
#region Fields
|
||||||
public class DirectoryManager : BaseManager
|
private Song _song;
|
||||||
|
private string _rootSongDirectory;
|
||||||
|
private string _songDirectory;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public string SongDirectory
|
||||||
{
|
{
|
||||||
#region Fields
|
get => _songDirectory;
|
||||||
private Song _song;
|
set => _songDirectory = value;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
#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.Models;
|
||||||
using Icarus.Database.Contexts;
|
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
|
_config = config;
|
||||||
private GenreContext _genreContext;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
_genreContext = new GenreContext(_connectionString);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
#region Methods
|
||||||
#endregion
|
public void SaveGenreToDatabase(ref Song song)
|
||||||
|
{
|
||||||
|
_logger.Info("Starting process to save the genre record of the song to the database");
|
||||||
|
|
||||||
|
var genre = new Genre
|
||||||
#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)
|
|
||||||
{
|
{
|
||||||
_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,
|
GenreName = newGenreName
|
||||||
SongCount = 1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var genreName = song.Genre;
|
_genreContext.Add(newGenreRecord);
|
||||||
var genreRetrieved = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(genreName));
|
_genreContext.SaveChanges();
|
||||||
|
|
||||||
if (genreRetrieved == null)
|
return newGenreRecord;
|
||||||
{
|
|
||||||
_genreContext.Add(genre);
|
|
||||||
_genreContext.SaveChanges();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
genre.GenreID = genreRetrieved.GenreID;
|
|
||||||
}
|
|
||||||
|
|
||||||
song.GenreID = genre.GenreID;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public Genre UpdateGenreInDatabase(Song oldSongRecord, Song newSongRecord)
|
|
||||||
{
|
{
|
||||||
var oldGenreRecord = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(oldSongRecord.Genre));
|
_logger.Info("Updating existing genre record");
|
||||||
var oldGenreName = oldGenreRecord.GenreName;
|
|
||||||
var newGenreName = newSongRecord.Genre;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(newGenreName) || oldGenreName.Equals(newGenreName))
|
var existingGenreRecord = _genreContext.Genres.FirstOrDefault(gnr => gnr.GenreName.Equals(oldGenreRecord.GenreName));
|
||||||
{
|
|
||||||
_logger.Info("No change to the song's Genre");
|
|
||||||
return oldGenreRecord;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.Info("Change to the song's genre found");
|
_genreContext.Update(existingGenreRecord);
|
||||||
|
_genreContext.SaveChanges();
|
||||||
|
|
||||||
if (oldGenreRecord.SongCount <= 1)
|
return existingGenreRecord;
|
||||||
{
|
|
||||||
_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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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.Models;
|
||||||
using Icarus.Database.Contexts;
|
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
|
get => _archiveDirectoryRoot;
|
||||||
private string _tempDirectoryRoot;
|
set => _archiveDirectoryRoot = value;
|
||||||
private string _archiveDirectoryRoot;
|
}
|
||||||
private string _compressedSongFilename;
|
public string CompressedSongFilename
|
||||||
private string _message;
|
{
|
||||||
private SongContext _songContext;
|
get => _compressedSongFilename;
|
||||||
#endregion
|
set => _compressedSongFilename = value;
|
||||||
|
}
|
||||||
|
public string Message
|
||||||
|
{
|
||||||
|
get => _message;
|
||||||
|
set => _message = value;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
#region Constructors
|
||||||
public string ArchiveDirectoryRoot
|
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;
|
result.SongTitle = song.Title;
|
||||||
set => _archiveDirectoryRoot = value;
|
result.Message = "Song does not exist";
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteSongFromFileSystem(Song songMetaData)
|
try
|
||||||
{
|
{
|
||||||
bool successful = false;
|
var oldSongRecord = _songContext.RetrieveRecord(song);
|
||||||
try
|
song.Filename = oldSongRecord.Filename;
|
||||||
{
|
song.SongDirectory = oldSongRecord.SongDirectory;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
return result;
|
||||||
{
|
}
|
||||||
if (!_songContext.DoesRecordExist(song))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
var exMsg = ex.Message;
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return successful;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task SaveSongToFileSystem(IFormFile songFile)
|
public bool DoesSongExist(Song song)
|
||||||
|
{
|
||||||
|
if (!_songContext.DoesRecordExist(song))
|
||||||
{
|
{
|
||||||
try
|
return false;
|
||||||
{
|
|
||||||
_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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveSongToFileSystem(IFormFile songFile, IFormFile coverArtData, Song song)
|
return true;
|
||||||
|
}
|
||||||
|
public void DeleteSong(Song song)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
song.SongDirectory = _tempDirectoryRoot;
|
if (DeleteSongFromFilesystem(song))
|
||||||
song.DateCreated = DateTime.Now;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(song.Filename))
|
|
||||||
{
|
{
|
||||||
song.Filename = song.GenerateFilename(1);
|
_logger.Error("Failed to delete the song");
|
||||||
}
|
|
||||||
|
throw new Exception("Failed to delete the song");
|
||||||
_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.Info("Song deleted from the filesystem");
|
||||||
|
|
||||||
var coverMgr = new CoverArtManager(_config);
|
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);
|
DirectoryManager dirMgr = new DirectoryManager(_config, song);
|
||||||
dirMgr.CreateDirectory();
|
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}");
|
_logger.Info($"Absolute song path: {filePath}");
|
||||||
|
|
||||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
|
||||||
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
var songBytes = System.IO.File.ReadAllBytes(tempPath);
|
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (System.IO.File.Exists(filePath) && System.IO.File.Exists(tempPath) && fileStream.Length > 0)
|
var songBytes = System.IO.File.ReadAllBytes(tempPath);
|
||||||
{
|
|
||||||
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("Saving song to the filesystem");
|
||||||
_logger.Info("Deleted temp song from filesystem: {0}", tempPath);
|
fileStream.Write(songBytes, 0, songBytes.Count());
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var msg = ex.Message;
|
|
||||||
_logger.Error($"An error occurred: {msg}");
|
|
||||||
}
|
|
||||||
|
|
||||||
_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);
|
coverMgr.SaveCoverArtToDatabase(ref song, ref coverArt);
|
||||||
SaveSongToDatabase(song);
|
SaveSongToDatabase(song);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
|
||||||
|
|
||||||
public async Task<SongData> RetrieveSong(Song songMetaData)
|
|
||||||
{
|
{
|
||||||
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
|
try
|
||||||
{
|
{
|
||||||
Console.WriteLine("Fetching song from filesystem");
|
if (System.IO.File.Exists(filePath) && System.IO.File.Exists(tempPath) && fileStream.Length > 0)
|
||||||
song = await RetrieveSongFromFileSystem(songMetaData);
|
{
|
||||||
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var exMsg = ex.Message;
|
var msg = ex.Message;
|
||||||
Console.WriteLine($"An error occurred: {exMsg}");
|
_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());
|
Console.WriteLine("Fetching song from filesystem");
|
||||||
|
song = await RetrieveSongFromFileSystem(songMetaData);
|
||||||
return new SongData
|
|
||||||
{
|
|
||||||
Data = uncompressedSong
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
private async Task<Song> SaveSongTemp(IFormFile songFile)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var song = new Song();
|
var exMsg = ex.Message;
|
||||||
_logger.Info("Assigning song filename");
|
Console.WriteLine($"An error occurred: {exMsg}");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
Data = uncompressedSong
|
||||||
var currentArtist = currentSong.Artist;
|
};
|
||||||
var currentAlbum = currentSong.AlbumTitle;
|
}
|
||||||
var currentGenre = currentSong.Genre;
|
private async Task<Song> SaveSongTemp(IFormFile songFile)
|
||||||
var currentYear = currentSong.Year;
|
{
|
||||||
|
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) ||
|
using (var filestream = new FileStream(song.SongPath(), FileMode.Create))
|
||||||
!currentAlbum.Equals(songUpdates.AlbumTitle) ||
|
{
|
||||||
!currentGenre.Equals(songUpdates.Genre) || currentYear != songUpdates.Year)
|
_logger.Info("Saving temp song: {0}", song.SongPath());
|
||||||
return true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteEmptyDirectories(ref Song oldSong, ref Song updatedSong)
|
_logger.Info("Song exists on the filesystem");
|
||||||
{
|
|
||||||
DirectoryManager mgr = new DirectoryManager(_config);
|
|
||||||
|
|
||||||
_logger.Info("Checking to see if there are any directories to delete");
|
return true;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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.Crypto.Parameters;
|
||||||
using Org.BouncyCastle.OpenSsl;
|
using Org.BouncyCastle.OpenSsl;
|
||||||
using Org.BouncyCastle.Security;
|
using Org.BouncyCastle.Security;
|
||||||
|
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Controllers.Managers
|
namespace Icarus.Controllers.Managers;
|
||||||
|
|
||||||
|
#region Classes
|
||||||
|
public class TokenManager : BaseManager
|
||||||
{
|
{
|
||||||
#region Classes
|
#region Fields
|
||||||
public class TokenManager : BaseManager
|
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
|
_config = config;
|
||||||
private string _clientId;
|
InitializeValues();
|
||||||
private string _clientSecret;
|
}
|
||||||
private string _privateKeyPath = string.Empty;
|
#endregion
|
||||||
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
|
#region Methods
|
||||||
#endregion
|
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
|
_logger.Info("Deserializing response");
|
||||||
public TokenManager(IConfiguration config)
|
var tokenResult = JsonConvert
|
||||||
|
.DeserializeObject<TokenTierOne>(response.Content);
|
||||||
|
_logger.Info("Response deserialized");
|
||||||
|
|
||||||
|
return new LoginResult
|
||||||
{
|
{
|
||||||
_config = config;
|
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||||
InitializeValues();
|
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||||
}
|
Message = "Successfully retrieved token"
|
||||||
#endregion
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Methods
|
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||||
public LoginResult RetrieveLoginResult(User user)
|
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);
|
tokenResult.Expiration = System.Convert.ToInt32(expClaim.Value);
|
||||||
var request = new RestRequest("oauth/token", Method.POST);
|
|
||||||
var tokenRequest = RetrieveTokenRequest();
|
|
||||||
|
|
||||||
_logger.Info("Serializing token object into JSON");
|
return new LoginResult
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
var tokenResult = new TokenTierOne();
|
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||||
tokenResult.TokenType = "Jwt";
|
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||||
|
Message = "Successfully retrieved token"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var privateKey = ReadKeyContent(_privateKeyPath).Result;
|
public LoginResult LoginSymmetric(User user)
|
||||||
var publicKey = ReadKeyContent(_publicKeyPath).Result;
|
{
|
||||||
|
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);
|
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JWT:Secret"]));
|
||||||
tokenResult.AccessToken = token;
|
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 =>
|
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 tokenResult = new TokenTierOne();
|
return cl.Type.Equals("exp");
|
||||||
tokenResult.TokenType = "Jwt";
|
});
|
||||||
|
|
||||||
var payload = Payload();
|
var expiredDate = DateTime.Parse(expClaim.Value);
|
||||||
payload.Add(new System.Security.Claims.Claim("user_id", user.UserID.ToString(), ClaimValueTypes.Integer));
|
var exp = Math.Floor((expiredDate - DateTime.UnixEpoch).TotalSeconds);
|
||||||
|
tokenResult.Expiration = Convert.ToInt32(exp);
|
||||||
|
|
||||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JWT:Secret"]));
|
return new LoginResult
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
var result = false;
|
UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken,
|
||||||
var token = DecodeToken(accessToken);
|
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
|
||||||
|
Message = "Successfully retrieved token"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (token == null || token.Erroneous())
|
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||||
{
|
public bool IsTokenValid(string scope, string accessToken)
|
||||||
return result;
|
{
|
||||||
}
|
var result = false;
|
||||||
|
var token = DecodeToken(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
|
|
||||||
|
|
||||||
|
if (token == null || token.Erroneous())
|
||||||
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
result = (!token.TokenExpired() && token.ContainsScope(scope)) ? true : false;
|
||||||
public Token DecodeToken(string accessToken)
|
|
||||||
|
// 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);
|
using (var rsa = new RSACryptoServiceProvider())
|
||||||
Token tok = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
using (var rsa = new RSACryptoServiceProvider())
|
rsa.ImportParameters(rsaParams);
|
||||||
{
|
|
||||||
rsa.ImportParameters(rsaParams);
|
|
||||||
|
|
||||||
IJsonSerializer serializer = new JsonNetSerializer();
|
IJsonSerializer serializer = new JsonNetSerializer();
|
||||||
IDateTimeProvider provider = new UtcDateTimeProvider();
|
IDateTimeProvider provider = new UtcDateTimeProvider();
|
||||||
IJwtValidator validator = new JwtValidator(serializer, provider);
|
IJwtValidator validator = new JwtValidator(serializer, provider);
|
||||||
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
|
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
|
||||||
var algorithm = new JWT.Algorithms.RS256Algorithm(rsa);
|
var algorithm = new JWT.Algorithms.RS256Algorithm(rsa);
|
||||||
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
|
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
|
||||||
|
|
||||||
var json = decoder.Decode(accessToken);
|
var json = decoder.Decode(accessToken);
|
||||||
tok = JsonConvert.DeserializeObject<Token>(json);
|
tok = JsonConvert.DeserializeObject<Token>(json);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
}
|
||||||
{
|
catch (Exception ex)
|
||||||
_logger.Error("An error occurred: {0}", ex.Message);
|
{
|
||||||
}
|
_logger.Error("An error occurred: {0}", ex.Message);
|
||||||
|
|
||||||
|
|
||||||
return tok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private string AllScopes()
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private string AllScopes()
|
||||||
|
{
|
||||||
|
var allScopes = new List<String>()
|
||||||
{
|
{
|
||||||
var allScopes = new List<String>()
|
"download:songs",
|
||||||
{
|
"read:song_details",
|
||||||
"download:songs",
|
"upload:songs",
|
||||||
"read:song_details",
|
"delete:songs",
|
||||||
"upload:songs",
|
"read:albums",
|
||||||
"delete:songs",
|
"read:artists",
|
||||||
"read:albums",
|
"update:songs",
|
||||||
"read:artists",
|
"stream:songs",
|
||||||
"update:songs",
|
"read:genre",
|
||||||
"stream:songs",
|
"read:year",
|
||||||
"read:genre",
|
"download:cover_art"
|
||||||
"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
|
else
|
||||||
{
|
{
|
||||||
scopes += allScopes[i] + " ";
|
payload.Add(type, claim.Value);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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")]
|
return token;
|
||||||
private RSAParameters GetRSAPublic(string publicKey)
|
}
|
||||||
|
|
||||||
|
[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);
|
throw new Exception("Could not read RSA public key");
|
||||||
var publicKeyParams = pemReader.ReadObject() as RsaKeyParameters;
|
|
||||||
if (publicKeyParams == null)
|
|
||||||
{
|
|
||||||
throw new Exception("Could not read RSA public key");
|
|
||||||
}
|
|
||||||
return DotNetUtilities.ToRSAParameters(publicKeyParams);
|
|
||||||
}
|
}
|
||||||
|
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);
|
ClientId = _clientId, ClientSecret = _clientSecret,
|
||||||
}
|
Audience = _audience, GrantType = _grantType
|
||||||
|
};
|
||||||
private TokenRequest RetrieveTokenRequest()
|
}
|
||||||
{
|
|
||||||
_logger.Info("Retrieving token object");
|
|
||||||
|
|
||||||
return new TokenRequest
|
private void InitializeValues()
|
||||||
{
|
{
|
||||||
ClientId = _clientId, ClientSecret = _clientSecret,
|
_logger.Info("Analyzing Auth0 information");
|
||||||
Audience = _audience, GrantType = _grantType
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeValues()
|
_clientId = _config["Auth0:ClientId"];
|
||||||
{
|
_clientSecret = _config["Auth0:ClientSecret"];
|
||||||
_logger.Info("Analyzing Auth0 information");
|
_audience = _config["Auth0:ApiIdentifier"];
|
||||||
|
_grantType = "client_credentials";
|
||||||
|
_url = $"https://{_config["Auth0:Domain"]}";
|
||||||
|
}
|
||||||
|
|
||||||
_clientId = _config["Auth0:ClientId"];
|
#region Testing Methods
|
||||||
_clientSecret = _config["Auth0:ClientSecret"];
|
// For testing purposes
|
||||||
_audience = _config["Auth0:ApiIdentifier"];
|
private void PrintCredentials()
|
||||||
_grantType = "client_credentials";
|
{
|
||||||
_url = $"https://{_config["Auth0:Domain"]}";
|
Console.WriteLine("Auth0 credentials:");
|
||||||
}
|
Console.WriteLine($"Client Id: {_clientId}");
|
||||||
|
Console.WriteLine($"Client Secret: {_clientSecret}");
|
||||||
#region Testing Methods
|
Console.WriteLine($"Audience: {_audience}");
|
||||||
// For testing purposes
|
Console.WriteLine($"Url: {_url}");
|
||||||
private void PrintCredentials()
|
}
|
||||||
{
|
#endregion
|
||||||
Console.WriteLine("Auth0 credentials:");
|
#endregion
|
||||||
Console.WriteLine($"Client Id: {_clientId}");
|
|
||||||
Console.WriteLine($"Client Secret: {_clientSecret}");
|
|
||||||
Console.WriteLine($"Audience: {_audience}");
|
|
||||||
Console.WriteLine($"Url: {_url}");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Classes
|
#region Classes
|
||||||
private class TokenRequest
|
private class TokenRequest
|
||||||
{
|
{
|
||||||
[JsonProperty("client_id")]
|
[JsonProperty("client_id")]
|
||||||
public string ClientId { get; set; }
|
public string ClientId { get; set; }
|
||||||
[JsonProperty("client_secret")]
|
[JsonProperty("client_secret")]
|
||||||
public string ClientSecret { get; set; }
|
public string ClientSecret { get; set; }
|
||||||
[JsonProperty("audience")]
|
[JsonProperty("audience")]
|
||||||
public string Audience { get; set; }
|
public string Audience { get; set; }
|
||||||
[JsonProperty("grant_type")]
|
[JsonProperty("grant_type")]
|
||||||
public string GrantType { get; set; }
|
public string GrantType { get; set; }
|
||||||
}
|
}
|
||||||
private class TokenTierOne
|
private class TokenTierOne
|
||||||
{
|
{
|
||||||
[JsonProperty("access_token")]
|
[JsonProperty("access_token")]
|
||||||
public string AccessToken { get; set; }
|
public string AccessToken { get; set; }
|
||||||
[JsonProperty("expires_in")]
|
[JsonProperty("expires_in")]
|
||||||
public int Expiration { get; set; }
|
public int Expiration { get; set; }
|
||||||
[JsonProperty("token_type")]
|
[JsonProperty("token_type")]
|
||||||
public string TokenType { get; set; }
|
public string TokenType { get; set; }
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|||||||
@@ -7,339 +7,338 @@ using TagLib;
|
|||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Controllers.Utilities
|
namespace Icarus.Controllers.Utilities;
|
||||||
|
|
||||||
|
public class MetadataRetriever
|
||||||
{
|
{
|
||||||
public class MetadataRetriever
|
#region Fields
|
||||||
|
private static NLog.Logger _logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
||||||
|
private Song _updatedSong;
|
||||||
|
private string _message;
|
||||||
|
private string _title;
|
||||||
|
private string _artist;
|
||||||
|
private string _album;
|
||||||
|
private string _genre;
|
||||||
|
private int _year;
|
||||||
|
private int _duration;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public Song UpdatedSongRecord
|
||||||
{
|
{
|
||||||
#region Fields
|
get => _updatedSong;
|
||||||
private static NLog.Logger _logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
set => _updatedSong = value;
|
||||||
private Song _updatedSong;
|
|
||||||
private string _message;
|
|
||||||
private string _title;
|
|
||||||
private string _artist;
|
|
||||||
private string _album;
|
|
||||||
private string _genre;
|
|
||||||
private int _year;
|
|
||||||
private int _duration;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
public Song UpdatedSongRecord
|
|
||||||
{
|
|
||||||
get => _updatedSong;
|
|
||||||
set => _updatedSong = value;
|
|
||||||
}
|
|
||||||
public string Message
|
|
||||||
{
|
|
||||||
get => _message;
|
|
||||||
set => _message = value;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public static void PrintMetadata(Song song)
|
|
||||||
{
|
|
||||||
Console.WriteLine("\n\nMetadata of the song:");
|
|
||||||
Console.WriteLine($"ID: {song.SongID}");
|
|
||||||
Console.WriteLine($"Title: {song.Title}");
|
|
||||||
Console.WriteLine($"Artist: {song.Artist}");
|
|
||||||
Console.WriteLine($"Album: {song.AlbumTitle}");
|
|
||||||
Console.WriteLine($"Genre: {song.Genre}");
|
|
||||||
Console.WriteLine($"Year: {song.Year}");
|
|
||||||
Console.WriteLine($"Duration: {song.Duration}");
|
|
||||||
Console.WriteLine($"AlbumID: {song.AlbumID}");
|
|
||||||
Console.WriteLine($"ArtistID: {song.ArtistID}");
|
|
||||||
Console.WriteLine($"GenreID: {song.GenreID}");
|
|
||||||
Console.WriteLine($"Song Path: {song.SongPath()}");
|
|
||||||
Console.WriteLine($"Filename: {song.Filename}");
|
|
||||||
Console.WriteLine("\n");
|
|
||||||
|
|
||||||
_logger.Info("Metadata of the song");
|
|
||||||
_logger.Info($"Title: {song.Title}");
|
|
||||||
_logger.Info($"Artist: {song.Artist}");
|
|
||||||
_logger.Info($"Album: {song.AlbumTitle}");
|
|
||||||
_logger.Info($"Genre: {song.Genre}");
|
|
||||||
_logger.Info($"Year: {song.Year}");
|
|
||||||
_logger.Info($"Duration: {song.Duration}");
|
|
||||||
}
|
|
||||||
public Song RetrieveMetaData(string filePath)
|
|
||||||
{
|
|
||||||
Song song = new Song();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
TagLib.File fileTag = TagLib.File.Create(filePath);
|
|
||||||
_title = fileTag.Tag.Title;
|
|
||||||
_artist = string.Join("", fileTag.Tag.Performers);
|
|
||||||
_album = fileTag.Tag.Album;
|
|
||||||
_genre = string.Join("", fileTag.Tag.Genres);
|
|
||||||
_year = (int)fileTag.Tag.Year;
|
|
||||||
_duration = (int)fileTag.Properties.Duration.TotalSeconds;
|
|
||||||
var albumArtist = string.Join("", fileTag.Tag.AlbumArtists);
|
|
||||||
var track = (int)fileTag.Tag.Track;
|
|
||||||
var disc = (int)fileTag.Tag.Disc;
|
|
||||||
|
|
||||||
song.Title = _title;
|
|
||||||
song.Artist = _artist;
|
|
||||||
song.AlbumTitle = _album;
|
|
||||||
song.AlbumArtist = albumArtist;
|
|
||||||
song.Genre = _genre;
|
|
||||||
song.Year = _year;
|
|
||||||
song.Duration = _duration;
|
|
||||||
song.Track = track;
|
|
||||||
song.Disc = disc;
|
|
||||||
song.TrackCount = (int)fileTag.Tag.TrackCount;
|
|
||||||
song.DiscCount = (int)fileTag.Tag.DiscCount;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var msg = ex.Message;
|
|
||||||
Console.WriteLine("An error occurred in MetadataRetriever");
|
|
||||||
Console.WriteLine(msg);
|
|
||||||
_logger.Error(msg, "An error occurred in MetadataRetriever");
|
|
||||||
}
|
|
||||||
|
|
||||||
return song;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RetrieveSongDuration(string filepath)
|
|
||||||
{
|
|
||||||
var duration = 0;
|
|
||||||
var fileTag = TagLib.File.Create(filepath);
|
|
||||||
duration = (int)fileTag.Properties.Duration.TotalSeconds;
|
|
||||||
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] RetrieveCoverArtBytes(Song song)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Console.WriteLine("Fetching image");
|
|
||||||
var tag = TagLib.File.Create(song.SongPath());
|
|
||||||
byte[] imgBytes = tag.Tag.Pictures[0].Data.Data;
|
|
||||||
|
|
||||||
return imgBytes;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var msg = ex.Message;
|
|
||||||
_logger.Error(msg, "An error occurred in MetadataRetriever");
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void UpdateMetadata(Song updatedSong, Song oldSong)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
InitializeUpdatedSong(oldSong);
|
|
||||||
var songValues = CheckSongValues(updatedSong);
|
|
||||||
PerformUpdate(updatedSong, songValues);
|
|
||||||
Message = "Successfully updated metadata";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var msg = ex.Message;
|
|
||||||
Console.WriteLine($"An error occurred: {msg}");
|
|
||||||
_logger.Error(msg, "An error occurred");
|
|
||||||
Message = "Failed to update metadata";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void UpdateCoverArt(Song song, CoverArt coverArt)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Updating song's cover art");
|
|
||||||
|
|
||||||
var tag = TagLib.File.Create(song.SongPath());
|
|
||||||
var pics = tag.Tag.Pictures;
|
|
||||||
Array.Resize(ref pics, 1);
|
|
||||||
|
|
||||||
pics[0] = new Picture(coverArt.ImagePath)
|
|
||||||
{
|
|
||||||
Description = "Cover Art"
|
|
||||||
};
|
|
||||||
|
|
||||||
tag.Tag.Pictures = pics;
|
|
||||||
tag.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PerformUpdate(Song updatedSong, SortedDictionary<string, bool> checkedValues)
|
|
||||||
{
|
|
||||||
var filePath = updatedSong.SongPath();
|
|
||||||
var title = updatedSong.Title;
|
|
||||||
var artist = updatedSong.Artist;
|
|
||||||
var album = updatedSong.AlbumTitle;
|
|
||||||
var genre = updatedSong.Genre;
|
|
||||||
var year = updatedSong.Year;
|
|
||||||
var albumArtist = updatedSong.AlbumArtist;
|
|
||||||
var track = updatedSong.Track;
|
|
||||||
var trackCount = updatedSong.TrackCount;
|
|
||||||
var disc = updatedSong.Disc;
|
|
||||||
var discCount = updatedSong.DiscCount;
|
|
||||||
TagLib.File fileTag = TagLib.File.Create(filePath);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Updating metadata of {title}");
|
|
||||||
_logger.Info($"Updating metadata of {title}");
|
|
||||||
|
|
||||||
foreach (var key in checkedValues.Keys)
|
|
||||||
{
|
|
||||||
bool result = checkedValues[key];
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
switch (key.ToLower())
|
|
||||||
{
|
|
||||||
case "title":
|
|
||||||
_updatedSong.Title = title;
|
|
||||||
fileTag.Tag.Title = title;
|
|
||||||
break;
|
|
||||||
case "artists":
|
|
||||||
_updatedSong.Artist = artist;
|
|
||||||
fileTag.Tag.Performers = new []{artist};
|
|
||||||
break;
|
|
||||||
case "album":
|
|
||||||
_updatedSong.AlbumTitle = album;
|
|
||||||
fileTag.Tag.Album = album;
|
|
||||||
break;
|
|
||||||
case "genre":
|
|
||||||
_updatedSong.Genre = genre;
|
|
||||||
fileTag.Tag.Genres = new []{genre};
|
|
||||||
break;
|
|
||||||
case "year":
|
|
||||||
_updatedSong.Year = year;
|
|
||||||
fileTag.Tag.Year = (uint)year;
|
|
||||||
break;
|
|
||||||
case "albumartist":
|
|
||||||
_updatedSong.AlbumArtist = albumArtist;
|
|
||||||
fileTag.Tag.AlbumArtists = new []{albumArtist};
|
|
||||||
break;
|
|
||||||
case "track":
|
|
||||||
_updatedSong.Track = track;
|
|
||||||
fileTag.Tag.Track = (uint)(track);
|
|
||||||
break;
|
|
||||||
case "trackcount":
|
|
||||||
_updatedSong.TrackCount = trackCount;
|
|
||||||
fileTag.Tag.TrackCount = (uint)(trackCount);
|
|
||||||
break;
|
|
||||||
case "disc":
|
|
||||||
_updatedSong.Disc = disc;
|
|
||||||
fileTag.Tag.Disc = (uint)(disc);
|
|
||||||
break;
|
|
||||||
case "disccount":
|
|
||||||
_updatedSong.DiscCount = discCount;
|
|
||||||
fileTag.Tag.DiscCount = (uint)(discCount);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileTag.Save();
|
|
||||||
|
|
||||||
Console.WriteLine("Successfully updated metadata");
|
|
||||||
_logger.Info("Successfully updated metadata");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var msg = ex.Message;
|
|
||||||
Console.WriteLine($"An error occurred:\n{msg}");
|
|
||||||
_logger.Error(msg, "An error occurred");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void InitializeUpdatedSong(Song song)
|
|
||||||
{
|
|
||||||
_updatedSong = song;
|
|
||||||
}
|
|
||||||
private void PrintMetadata()
|
|
||||||
{
|
|
||||||
Console.WriteLine("\n\nMetadata of the song:");
|
|
||||||
Console.WriteLine($"Title: {_title}");
|
|
||||||
Console.WriteLine($"Artist: {_artist}");
|
|
||||||
Console.WriteLine($"Album: {_album}");
|
|
||||||
Console.WriteLine($"Genre: {_genre}");
|
|
||||||
Console.WriteLine($"Year: {_year}");
|
|
||||||
Console.WriteLine($"Duration: {_duration}\n\n");
|
|
||||||
|
|
||||||
_logger.Info("Metadata of the song");
|
|
||||||
_logger.Info($"Title: {_title}");
|
|
||||||
_logger.Info($"Artist: {_artist}");
|
|
||||||
_logger.Info($"Album: {_album}");
|
|
||||||
_logger.Info($"Genre: {_genre}");
|
|
||||||
_logger.Info($"Year: {_year}");
|
|
||||||
_logger.Info($"Duration: {_duration}");
|
|
||||||
}
|
|
||||||
private void PrintMetadata(Song song, string message)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"\n\n{message}");
|
|
||||||
Console.WriteLine($"Title: {song.Title}");
|
|
||||||
Console.WriteLine($"Artist: {song.Artist}");
|
|
||||||
Console.WriteLine($"Album: {song.AlbumTitle}");
|
|
||||||
Console.WriteLine($"Genre: {song.Genre}");
|
|
||||||
Console.WriteLine($"Year: {song.Year}");
|
|
||||||
Console.WriteLine($"Duration: {song.Duration}\n\n");
|
|
||||||
|
|
||||||
_logger.Info(message);
|
|
||||||
_logger.Info($"Title: {_title}");
|
|
||||||
_logger.Info($"Artist: {_artist}");
|
|
||||||
_logger.Info($"Album: {_album}");
|
|
||||||
_logger.Info($"Genre: {_genre}");
|
|
||||||
_logger.Info($"Year: {_year}");
|
|
||||||
_logger.Info($"Duration: {_duration}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private SortedDictionary<string, bool> CheckSongValues(Song song)
|
|
||||||
{
|
|
||||||
var songValues = new SortedDictionary<string, bool>();
|
|
||||||
Console.WriteLine("Checking for null data");
|
|
||||||
_logger.Info("Checking for null data");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
songValues["Title"] = String.IsNullOrEmpty(song.Title);
|
|
||||||
songValues["Artists"] = String.IsNullOrEmpty(song.Artist);
|
|
||||||
songValues["Album"] = String.IsNullOrEmpty(song.AlbumTitle);
|
|
||||||
songValues["Genre"] = String.IsNullOrEmpty(song.Genre);
|
|
||||||
songValues["AlbumArtist"] = String.IsNullOrEmpty(song.AlbumArtist);
|
|
||||||
|
|
||||||
songValues["Year"] = CheckIntField(song.Year);
|
|
||||||
songValues["Track"] = CheckIntField(song.Track);
|
|
||||||
songValues["TrackCount"] = CheckIntField(song.TrackCount);
|
|
||||||
songValues["Disc"] = CheckIntField(song.Disc);
|
|
||||||
songValues["DiscCount"] = CheckIntField(song.Disc);
|
|
||||||
|
|
||||||
Console.WriteLine("Checking for null data completed");
|
|
||||||
_logger.Info("Checking for null data completed");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var msg = ex.Message;
|
|
||||||
Console.WriteLine($"An error occurred: \n{msg}");
|
|
||||||
_logger.Error(msg, "An error occurred");
|
|
||||||
}
|
|
||||||
|
|
||||||
return songValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckIntField(int? value)
|
|
||||||
{
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (value == 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
public string Message
|
||||||
|
{
|
||||||
|
get => _message;
|
||||||
|
set => _message = value;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public static void PrintMetadata(Song song)
|
||||||
|
{
|
||||||
|
Console.WriteLine("\n\nMetadata of the song:");
|
||||||
|
Console.WriteLine($"ID: {song.SongID}");
|
||||||
|
Console.WriteLine($"Title: {song.Title}");
|
||||||
|
Console.WriteLine($"Artist: {song.Artist}");
|
||||||
|
Console.WriteLine($"Album: {song.AlbumTitle}");
|
||||||
|
Console.WriteLine($"Genre: {song.Genre}");
|
||||||
|
Console.WriteLine($"Year: {song.Year}");
|
||||||
|
Console.WriteLine($"Duration: {song.Duration}");
|
||||||
|
Console.WriteLine($"AlbumID: {song.AlbumID}");
|
||||||
|
Console.WriteLine($"ArtistID: {song.ArtistID}");
|
||||||
|
Console.WriteLine($"GenreID: {song.GenreID}");
|
||||||
|
Console.WriteLine($"Song Path: {song.SongPath()}");
|
||||||
|
Console.WriteLine($"Filename: {song.Filename}");
|
||||||
|
Console.WriteLine("\n");
|
||||||
|
|
||||||
|
_logger.Info("Metadata of the song");
|
||||||
|
_logger.Info($"Title: {song.Title}");
|
||||||
|
_logger.Info($"Artist: {song.Artist}");
|
||||||
|
_logger.Info($"Album: {song.AlbumTitle}");
|
||||||
|
_logger.Info($"Genre: {song.Genre}");
|
||||||
|
_logger.Info($"Year: {song.Year}");
|
||||||
|
_logger.Info($"Duration: {song.Duration}");
|
||||||
|
}
|
||||||
|
public Song RetrieveMetaData(string filePath)
|
||||||
|
{
|
||||||
|
Song song = new Song();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TagLib.File fileTag = TagLib.File.Create(filePath);
|
||||||
|
_title = fileTag.Tag.Title;
|
||||||
|
_artist = string.Join("", fileTag.Tag.Performers);
|
||||||
|
_album = fileTag.Tag.Album;
|
||||||
|
_genre = string.Join("", fileTag.Tag.Genres);
|
||||||
|
_year = (int)fileTag.Tag.Year;
|
||||||
|
_duration = (int)fileTag.Properties.Duration.TotalSeconds;
|
||||||
|
var albumArtist = string.Join("", fileTag.Tag.AlbumArtists);
|
||||||
|
var track = (int)fileTag.Tag.Track;
|
||||||
|
var disc = (int)fileTag.Tag.Disc;
|
||||||
|
|
||||||
|
song.Title = _title;
|
||||||
|
song.Artist = _artist;
|
||||||
|
song.AlbumTitle = _album;
|
||||||
|
song.AlbumArtist = albumArtist;
|
||||||
|
song.Genre = _genre;
|
||||||
|
song.Year = _year;
|
||||||
|
song.Duration = _duration;
|
||||||
|
song.Track = track;
|
||||||
|
song.Disc = disc;
|
||||||
|
song.TrackCount = (int)fileTag.Tag.TrackCount;
|
||||||
|
song.DiscCount = (int)fileTag.Tag.DiscCount;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
Console.WriteLine("An error occurred in MetadataRetriever");
|
||||||
|
Console.WriteLine(msg);
|
||||||
|
_logger.Error(msg, "An error occurred in MetadataRetriever");
|
||||||
|
}
|
||||||
|
|
||||||
|
return song;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RetrieveSongDuration(string filepath)
|
||||||
|
{
|
||||||
|
var duration = 0;
|
||||||
|
var fileTag = TagLib.File.Create(filepath);
|
||||||
|
duration = (int)fileTag.Properties.Duration.TotalSeconds;
|
||||||
|
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] RetrieveCoverArtBytes(Song song)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("Fetching image");
|
||||||
|
var tag = TagLib.File.Create(song.SongPath());
|
||||||
|
byte[] imgBytes = tag.Tag.Pictures[0].Data.Data;
|
||||||
|
|
||||||
|
return imgBytes;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
_logger.Error(msg, "An error occurred in MetadataRetriever");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void UpdateMetadata(Song updatedSong, Song oldSong)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InitializeUpdatedSong(oldSong);
|
||||||
|
var songValues = CheckSongValues(updatedSong);
|
||||||
|
PerformUpdate(updatedSong, songValues);
|
||||||
|
Message = "Successfully updated metadata";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
Console.WriteLine($"An error occurred: {msg}");
|
||||||
|
_logger.Error(msg, "An error occurred");
|
||||||
|
Message = "Failed to update metadata";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void UpdateCoverArt(Song song, CoverArt coverArt)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Updating song's cover art");
|
||||||
|
|
||||||
|
var tag = TagLib.File.Create(song.SongPath());
|
||||||
|
var pics = tag.Tag.Pictures;
|
||||||
|
Array.Resize(ref pics, 1);
|
||||||
|
|
||||||
|
pics[0] = new Picture(coverArt.ImagePath)
|
||||||
|
{
|
||||||
|
Description = "Cover Art"
|
||||||
|
};
|
||||||
|
|
||||||
|
tag.Tag.Pictures = pics;
|
||||||
|
tag.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PerformUpdate(Song updatedSong, SortedDictionary<string, bool> checkedValues)
|
||||||
|
{
|
||||||
|
var filePath = updatedSong.SongPath();
|
||||||
|
var title = updatedSong.Title;
|
||||||
|
var artist = updatedSong.Artist;
|
||||||
|
var album = updatedSong.AlbumTitle;
|
||||||
|
var genre = updatedSong.Genre;
|
||||||
|
var year = updatedSong.Year;
|
||||||
|
var albumArtist = updatedSong.AlbumArtist;
|
||||||
|
var track = updatedSong.Track;
|
||||||
|
var trackCount = updatedSong.TrackCount;
|
||||||
|
var disc = updatedSong.Disc;
|
||||||
|
var discCount = updatedSong.DiscCount;
|
||||||
|
TagLib.File fileTag = TagLib.File.Create(filePath);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Updating metadata of {title}");
|
||||||
|
_logger.Info($"Updating metadata of {title}");
|
||||||
|
|
||||||
|
foreach (var key in checkedValues.Keys)
|
||||||
|
{
|
||||||
|
bool result = checkedValues[key];
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
switch (key.ToLower())
|
||||||
|
{
|
||||||
|
case "title":
|
||||||
|
_updatedSong.Title = title;
|
||||||
|
fileTag.Tag.Title = title;
|
||||||
|
break;
|
||||||
|
case "artists":
|
||||||
|
_updatedSong.Artist = artist;
|
||||||
|
fileTag.Tag.Performers = new []{artist};
|
||||||
|
break;
|
||||||
|
case "album":
|
||||||
|
_updatedSong.AlbumTitle = album;
|
||||||
|
fileTag.Tag.Album = album;
|
||||||
|
break;
|
||||||
|
case "genre":
|
||||||
|
_updatedSong.Genre = genre;
|
||||||
|
fileTag.Tag.Genres = new []{genre};
|
||||||
|
break;
|
||||||
|
case "year":
|
||||||
|
_updatedSong.Year = year;
|
||||||
|
fileTag.Tag.Year = (uint)year;
|
||||||
|
break;
|
||||||
|
case "albumartist":
|
||||||
|
_updatedSong.AlbumArtist = albumArtist;
|
||||||
|
fileTag.Tag.AlbumArtists = new []{albumArtist};
|
||||||
|
break;
|
||||||
|
case "track":
|
||||||
|
_updatedSong.Track = track;
|
||||||
|
fileTag.Tag.Track = (uint)(track);
|
||||||
|
break;
|
||||||
|
case "trackcount":
|
||||||
|
_updatedSong.TrackCount = trackCount;
|
||||||
|
fileTag.Tag.TrackCount = (uint)(trackCount);
|
||||||
|
break;
|
||||||
|
case "disc":
|
||||||
|
_updatedSong.Disc = disc;
|
||||||
|
fileTag.Tag.Disc = (uint)(disc);
|
||||||
|
break;
|
||||||
|
case "disccount":
|
||||||
|
_updatedSong.DiscCount = discCount;
|
||||||
|
fileTag.Tag.DiscCount = (uint)(discCount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileTag.Save();
|
||||||
|
|
||||||
|
Console.WriteLine("Successfully updated metadata");
|
||||||
|
_logger.Info("Successfully updated metadata");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
Console.WriteLine($"An error occurred:\n{msg}");
|
||||||
|
_logger.Error(msg, "An error occurred");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void InitializeUpdatedSong(Song song)
|
||||||
|
{
|
||||||
|
_updatedSong = song;
|
||||||
|
}
|
||||||
|
private void PrintMetadata()
|
||||||
|
{
|
||||||
|
Console.WriteLine("\n\nMetadata of the song:");
|
||||||
|
Console.WriteLine($"Title: {_title}");
|
||||||
|
Console.WriteLine($"Artist: {_artist}");
|
||||||
|
Console.WriteLine($"Album: {_album}");
|
||||||
|
Console.WriteLine($"Genre: {_genre}");
|
||||||
|
Console.WriteLine($"Year: {_year}");
|
||||||
|
Console.WriteLine($"Duration: {_duration}\n\n");
|
||||||
|
|
||||||
|
_logger.Info("Metadata of the song");
|
||||||
|
_logger.Info($"Title: {_title}");
|
||||||
|
_logger.Info($"Artist: {_artist}");
|
||||||
|
_logger.Info($"Album: {_album}");
|
||||||
|
_logger.Info($"Genre: {_genre}");
|
||||||
|
_logger.Info($"Year: {_year}");
|
||||||
|
_logger.Info($"Duration: {_duration}");
|
||||||
|
}
|
||||||
|
private void PrintMetadata(Song song, string message)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"\n\n{message}");
|
||||||
|
Console.WriteLine($"Title: {song.Title}");
|
||||||
|
Console.WriteLine($"Artist: {song.Artist}");
|
||||||
|
Console.WriteLine($"Album: {song.AlbumTitle}");
|
||||||
|
Console.WriteLine($"Genre: {song.Genre}");
|
||||||
|
Console.WriteLine($"Year: {song.Year}");
|
||||||
|
Console.WriteLine($"Duration: {song.Duration}\n\n");
|
||||||
|
|
||||||
|
_logger.Info(message);
|
||||||
|
_logger.Info($"Title: {_title}");
|
||||||
|
_logger.Info($"Artist: {_artist}");
|
||||||
|
_logger.Info($"Album: {_album}");
|
||||||
|
_logger.Info($"Genre: {_genre}");
|
||||||
|
_logger.Info($"Year: {_year}");
|
||||||
|
_logger.Info($"Duration: {_duration}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private SortedDictionary<string, bool> CheckSongValues(Song song)
|
||||||
|
{
|
||||||
|
var songValues = new SortedDictionary<string, bool>();
|
||||||
|
Console.WriteLine("Checking for null data");
|
||||||
|
_logger.Info("Checking for null data");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
songValues["Title"] = String.IsNullOrEmpty(song.Title);
|
||||||
|
songValues["Artists"] = String.IsNullOrEmpty(song.Artist);
|
||||||
|
songValues["Album"] = String.IsNullOrEmpty(song.AlbumTitle);
|
||||||
|
songValues["Genre"] = String.IsNullOrEmpty(song.Genre);
|
||||||
|
songValues["AlbumArtist"] = String.IsNullOrEmpty(song.AlbumArtist);
|
||||||
|
|
||||||
|
songValues["Year"] = CheckIntField(song.Year);
|
||||||
|
songValues["Track"] = CheckIntField(song.Track);
|
||||||
|
songValues["TrackCount"] = CheckIntField(song.TrackCount);
|
||||||
|
songValues["Disc"] = CheckIntField(song.Disc);
|
||||||
|
songValues["DiscCount"] = CheckIntField(song.Disc);
|
||||||
|
|
||||||
|
Console.WriteLine("Checking for null data completed");
|
||||||
|
_logger.Info("Checking for null data completed");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
Console.WriteLine($"An error occurred: \n{msg}");
|
||||||
|
_logger.Error(msg, "An error occurred");
|
||||||
|
}
|
||||||
|
|
||||||
|
return songValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckIntField(int? value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (value == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,84 +7,83 @@ using NLog;
|
|||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Controllers.Utilities
|
namespace Icarus.Controllers.Utilities;
|
||||||
|
|
||||||
|
public class PasswordEncryption
|
||||||
{
|
{
|
||||||
public class PasswordEncryption
|
#region Fields
|
||||||
|
private static Logger _logger = NLog.LogManager.GetCurrentClassLogger();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public bool VerifyPassword(User user, string password)
|
||||||
{
|
{
|
||||||
#region Fields
|
try
|
||||||
private static Logger _logger = NLog.LogManager.GetCurrentClassLogger();
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructor
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public bool VerifyPassword(User user, string password)
|
|
||||||
{
|
{
|
||||||
try
|
var result = BCrypt.Net.BCrypt.Verify(password, user.Password);
|
||||||
{
|
|
||||||
var result = BCrypt.Net.BCrypt.Verify(password, user.Password);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var msg = ex.Message;
|
var msg = ex.Message;
|
||||||
_logger.Error(msg, "An error occurred");
|
_logger.Error(msg, "An error occurred");
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string HashPassword(User user)
|
return false;
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string hashedPassword = string.Empty;
|
|
||||||
hashedPassword = BCrypt.Net.BCrypt.HashPassword(user.Password);
|
|
||||||
|
|
||||||
_logger.Info("Successfully hashed password");
|
|
||||||
|
|
||||||
return hashedPassword;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var exMsg = ex.Message;
|
|
||||||
_logger.Error(exMsg, "An error occurred");
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
string GenerateHash(string password, byte[] salt)
|
|
||||||
{
|
|
||||||
|
|
||||||
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
|
|
||||||
password: password, salt: salt,
|
|
||||||
prf: KeyDerivationPrf.HMACSHA1,
|
|
||||||
iterationCount: 10000,
|
|
||||||
numBytesRequested: 256/8));
|
|
||||||
|
|
||||||
return hashed;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] GenerateSalt()
|
|
||||||
{
|
|
||||||
byte[] salt = new byte[128/8];
|
|
||||||
|
|
||||||
using (var rng = RandomNumberGenerator.Create())
|
|
||||||
rng.GetBytes(salt);
|
|
||||||
|
|
||||||
|
|
||||||
return salt;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string HashPassword(User user)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string hashedPassword = string.Empty;
|
||||||
|
hashedPassword = BCrypt.Net.BCrypt.HashPassword(user.Password);
|
||||||
|
|
||||||
|
_logger.Info("Successfully hashed password");
|
||||||
|
|
||||||
|
return hashedPassword;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var exMsg = ex.Message;
|
||||||
|
_logger.Error(exMsg, "An error occurred");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateHash(string password, byte[] salt)
|
||||||
|
{
|
||||||
|
|
||||||
|
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
|
||||||
|
password: password, salt: salt,
|
||||||
|
prf: KeyDerivationPrf.HMACSHA1,
|
||||||
|
iterationCount: 10000,
|
||||||
|
numBytesRequested: 256/8));
|
||||||
|
|
||||||
|
return hashed;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] GenerateSalt()
|
||||||
|
{
|
||||||
|
byte[] salt = new byte[128/8];
|
||||||
|
|
||||||
|
using (var rng = RandomNumberGenerator.Create())
|
||||||
|
rng.GetBytes(salt);
|
||||||
|
|
||||||
|
|
||||||
|
return salt;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,129 +2,127 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
using Ionic.Zip;
|
using Ionic.Zip;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Controllers.Utilities
|
namespace Icarus.Controllers.Utilities;
|
||||||
|
|
||||||
|
public class SongCompression
|
||||||
{
|
{
|
||||||
public class SongCompression
|
#region Fields
|
||||||
|
string _compressedSongFilename;
|
||||||
|
string _tempDirectory;
|
||||||
|
byte[] _uncompressedSong;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Propterties
|
||||||
|
public string CompressedSongFilename
|
||||||
{
|
{
|
||||||
#region Fields
|
get => _compressedSongFilename;
|
||||||
string _compressedSongFilename;
|
set => _compressedSongFilename = value;
|
||||||
string _tempDirectory;
|
|
||||||
byte[] _uncompressedSong;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Propterties
|
|
||||||
public string CompressedSongFilename
|
|
||||||
{
|
|
||||||
get => _compressedSongFilename;
|
|
||||||
set => _compressedSongFilename = value;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
public SongCompression()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public SongCompression(string tempDirectory)
|
|
||||||
{
|
|
||||||
_tempDirectory = tempDirectory;
|
|
||||||
}
|
|
||||||
public SongCompression(byte[] uncompressedSong)
|
|
||||||
{
|
|
||||||
_uncompressedSong = uncompressedSong;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public async Task<SongData> RetrieveCompressedSong(Song song)
|
|
||||||
{
|
|
||||||
SongData songData = new SongData();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var archivePath = RetrieveCompressesSongPath(song);
|
|
||||||
Console.WriteLine($"Compressed song saved to: {archivePath}");
|
|
||||||
|
|
||||||
songData.Data = await System.IO.File.ReadAllBytesAsync(archivePath);
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
var exMsg = ex.Message;
|
|
||||||
Console.WriteLine($"An error ocurred: \n{exMsg}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return songData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string RetrieveCompressesSongPath(Song songDetails)
|
|
||||||
{
|
|
||||||
string tmpZipFilePath = _tempDirectory + songDetails.Filename;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (ZipFile zip = new ZipFile())
|
|
||||||
{
|
|
||||||
zip.AddFile(songDetails.SongPath());
|
|
||||||
zip.Save(tmpZipFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine("Successfully compressed");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var exMsg = ex.Message;
|
|
||||||
Console.WriteLine("An error ocurred");
|
|
||||||
Console.WriteLine(exMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (songDetails.Filename.Contains(".mp3"))
|
|
||||||
{
|
|
||||||
_compressedSongFilename = StripMP3Extension(songDetails.Filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmpZipFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method not being used
|
|
||||||
public byte[] CompressedSong(byte[] uncompressedSong)
|
|
||||||
{
|
|
||||||
byte[] compressedSong = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Console.WriteLine("Song has been successfully compressed");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var exMsg = ex.Message;
|
|
||||||
Console.WriteLine("An error ocurred:");
|
|
||||||
Console.WriteLine(exMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return compressedSong;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string StripMP3Extension(string filename)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Before: {filename}");
|
|
||||||
int filenameLength = filename.Length;
|
|
||||||
Console.WriteLine($"Filename length {filenameLength}");
|
|
||||||
var endIndex = filenameLength - 1;
|
|
||||||
var startIndex = endIndex - 3;
|
|
||||||
Console.WriteLine($"Starting index {startIndex} and ending index {endIndex}");
|
|
||||||
var stripped = filename.Remove(startIndex, 4);
|
|
||||||
stripped += ".zip";
|
|
||||||
Console.WriteLine($"After {stripped}");
|
|
||||||
|
|
||||||
return stripped;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
public SongCompression()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public SongCompression(string tempDirectory)
|
||||||
|
{
|
||||||
|
_tempDirectory = tempDirectory;
|
||||||
|
}
|
||||||
|
public SongCompression(byte[] uncompressedSong)
|
||||||
|
{
|
||||||
|
_uncompressedSong = uncompressedSong;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public async Task<SongData> RetrieveCompressedSong(Song song)
|
||||||
|
{
|
||||||
|
SongData songData = new SongData();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var archivePath = RetrieveCompressesSongPath(song);
|
||||||
|
Console.WriteLine($"Compressed song saved to: {archivePath}");
|
||||||
|
|
||||||
|
songData.Data = await System.IO.File.ReadAllBytesAsync(archivePath);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
var exMsg = ex.Message;
|
||||||
|
Console.WriteLine($"An error ocurred: \n{exMsg}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return songData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string RetrieveCompressesSongPath(Song songDetails)
|
||||||
|
{
|
||||||
|
string tmpZipFilePath = _tempDirectory + songDetails.Filename;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (ZipFile zip = new ZipFile())
|
||||||
|
{
|
||||||
|
zip.AddFile(songDetails.SongPath());
|
||||||
|
zip.Save(tmpZipFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Successfully compressed");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var exMsg = ex.Message;
|
||||||
|
Console.WriteLine("An error ocurred");
|
||||||
|
Console.WriteLine(exMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (songDetails.Filename.Contains(".mp3"))
|
||||||
|
{
|
||||||
|
_compressedSongFilename = StripMP3Extension(songDetails.Filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpZipFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method not being used
|
||||||
|
public byte[] CompressedSong(byte[] uncompressedSong)
|
||||||
|
{
|
||||||
|
byte[] compressedSong = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("Song has been successfully compressed");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var exMsg = ex.Message;
|
||||||
|
Console.WriteLine("An error ocurred:");
|
||||||
|
Console.WriteLine(exMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return compressedSong;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string StripMP3Extension(string filename)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Before: {filename}");
|
||||||
|
int filenameLength = filename.Length;
|
||||||
|
Console.WriteLine($"Filename length {filenameLength}");
|
||||||
|
var endIndex = filenameLength - 1;
|
||||||
|
var startIndex = endIndex - 3;
|
||||||
|
Console.WriteLine($"Starting index {startIndex} and ending index {endIndex}");
|
||||||
|
var stripped = filename.Remove(startIndex, 4);
|
||||||
|
stripped += ".zip";
|
||||||
|
Console.WriteLine($"After {stripped}");
|
||||||
|
|
||||||
|
return stripped;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,68 +10,67 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/album")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class AlbumController : BaseController
|
||||||
{
|
{
|
||||||
[Route("api/v1/album")]
|
#region Fields
|
||||||
[ApiController]
|
private readonly ILogger<AlbumController> _logger;
|
||||||
[Authorize]
|
private string _connectionString;
|
||||||
public class AlbumController : BaseController
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
public AlbumController(ILogger<AlbumController> logger, IConfiguration config)
|
||||||
{
|
{
|
||||||
#region Fields
|
_logger = logger;
|
||||||
private readonly ILogger<AlbumController> _logger;
|
_config = config;
|
||||||
private string _connectionString;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
public AlbumController(ILogger<AlbumController> logger, IConfiguration config)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_config = config;
|
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region HTTP Routes
|
|
||||||
[HttpGet]
|
|
||||||
public IActionResult GetAlbums()
|
|
||||||
{
|
|
||||||
List<Album> albums = new List<Album>();
|
|
||||||
|
|
||||||
var albumContext = new AlbumContext(_connectionString);
|
|
||||||
|
|
||||||
albums = albumContext.Albums.ToList();
|
|
||||||
|
|
||||||
if (albums.Count > 0)
|
|
||||||
return Ok(albums);
|
|
||||||
else
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public IActionResult GetAlbum(int id)
|
|
||||||
{
|
|
||||||
Album album = new Album
|
|
||||||
{
|
|
||||||
AlbumID = id
|
|
||||||
};
|
|
||||||
|
|
||||||
var albumContext = new AlbumContext(_connectionString);
|
|
||||||
|
|
||||||
if (albumContext.DoesRecordExist(album))
|
|
||||||
{
|
|
||||||
album = albumContext.RetrieveRecord(album);
|
|
||||||
|
|
||||||
return Ok(album);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region HTTP Routes
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetAlbums()
|
||||||
|
{
|
||||||
|
List<Album> albums = new List<Album>();
|
||||||
|
|
||||||
|
var albumContext = new AlbumContext(_connectionString);
|
||||||
|
|
||||||
|
albums = albumContext.Albums.ToList();
|
||||||
|
|
||||||
|
if (albums.Count > 0)
|
||||||
|
return Ok(albums);
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public IActionResult GetAlbum(int id)
|
||||||
|
{
|
||||||
|
Album album = new Album
|
||||||
|
{
|
||||||
|
AlbumID = id
|
||||||
|
};
|
||||||
|
|
||||||
|
var albumContext = new AlbumContext(_connectionString);
|
||||||
|
|
||||||
|
if (albumContext.DoesRecordExist(album))
|
||||||
|
{
|
||||||
|
album = albumContext.RetrieveRecord(album);
|
||||||
|
|
||||||
|
return Ok(album);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,66 +9,65 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/artist")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class ArtistController : BaseController
|
||||||
{
|
{
|
||||||
[Route("api/v1/artist")]
|
#region Fields
|
||||||
[ApiController]
|
private readonly ILogger<ArtistController> _logger;
|
||||||
[Authorize]
|
private string _connectionString;
|
||||||
public class ArtistController : BaseController
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
public ArtistController(ILogger<ArtistController> logger, IConfiguration config)
|
||||||
{
|
{
|
||||||
#region Fields
|
_logger = logger;
|
||||||
private readonly ILogger<ArtistController> _logger;
|
_config = config;
|
||||||
private string _connectionString;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
public ArtistController(ILogger<ArtistController> logger, IConfiguration config)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_config = config;
|
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region HTTP Routes
|
|
||||||
[HttpGet]
|
|
||||||
public IActionResult GetArtists()
|
|
||||||
{
|
|
||||||
var artistContext = new ArtistContext(_connectionString);
|
|
||||||
|
|
||||||
var artists = artistContext.Artists.ToList();
|
|
||||||
|
|
||||||
if (artists.Count > 0)
|
|
||||||
return Ok(artists);
|
|
||||||
else
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public IActionResult GetArtist(int id)
|
|
||||||
{
|
|
||||||
Artist artist = new Artist
|
|
||||||
{
|
|
||||||
ArtistID = id
|
|
||||||
};
|
|
||||||
|
|
||||||
var artistContext = new ArtistContext(_connectionString);
|
|
||||||
|
|
||||||
if (artistContext.DoesRecordExist(artist))
|
|
||||||
{
|
|
||||||
artist = artistContext.RetrieveRecord(artist);
|
|
||||||
|
|
||||||
return Ok(artist);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region HTTP Routes
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetArtists()
|
||||||
|
{
|
||||||
|
var artistContext = new ArtistContext(_connectionString);
|
||||||
|
|
||||||
|
var artists = artistContext.Artists.ToList();
|
||||||
|
|
||||||
|
if (artists.Count > 0)
|
||||||
|
return Ok(artists);
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public IActionResult GetArtist(int id)
|
||||||
|
{
|
||||||
|
Artist artist = new Artist
|
||||||
|
{
|
||||||
|
ArtistID = id
|
||||||
|
};
|
||||||
|
|
||||||
|
var artistContext = new ArtistContext(_connectionString);
|
||||||
|
|
||||||
|
if (artistContext.DoesRecordExist(artist))
|
||||||
|
{
|
||||||
|
artist = artistContext.RetrieveRecord(artist);
|
||||||
|
|
||||||
|
return Ok(artist);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,47 +7,46 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Icarus.Controllers.Managers;
|
using Icarus.Controllers.Managers;
|
||||||
|
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
public class BaseController : ControllerBase
|
||||||
{
|
{
|
||||||
public class BaseController : ControllerBase
|
#region Fiends
|
||||||
|
protected IConfiguration _config;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
|
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||||
|
protected string ParseBearerTokenFromHeader()
|
||||||
{
|
{
|
||||||
#region Fiends
|
var token = string.Empty;
|
||||||
protected IConfiguration _config;
|
const string tokenType = "Bearer";
|
||||||
#endregion
|
const string otherTokenType = "Jwt";
|
||||||
|
|
||||||
|
var req = Request;
|
||||||
|
var auth = req.Headers.Authorization;
|
||||||
|
var val = auth.ToString();
|
||||||
|
|
||||||
#region Methods
|
if ((val.Contains(tokenType) || val.Contains(otherTokenType)) && val.Split(" ").Count() > 1)
|
||||||
[ApiExplorerSettings(IgnoreApi = true)]
|
|
||||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
|
||||||
protected string ParseBearerTokenFromHeader()
|
|
||||||
{
|
{
|
||||||
var token = string.Empty;
|
var split = val.Split(" ");
|
||||||
const string tokenType = "Bearer";
|
token = split[1];
|
||||||
const string otherTokenType = "Jwt";
|
|
||||||
|
|
||||||
var req = Request;
|
|
||||||
var auth = req.Headers.Authorization;
|
|
||||||
var val = auth.ToString();
|
|
||||||
|
|
||||||
if ((val.Contains(tokenType) || val.Contains(otherTokenType)) && val.Split(" ").Count() > 1)
|
|
||||||
{
|
|
||||||
var split = val.Split(" ");
|
|
||||||
token = split[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ApiExplorerSettings(IgnoreApi = true)]
|
|
||||||
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
|
||||||
protected bool IsTokenValid(string scope)
|
|
||||||
{
|
|
||||||
var token = ParseBearerTokenFromHeader();
|
|
||||||
var tokMgr = new TokenManager(_config);
|
|
||||||
|
|
||||||
return tokMgr.IsTokenValid(scope, token);
|
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
|
[Obsolete("Asymmetric key signing for tokens have been deprecated")]
|
||||||
|
protected bool IsTokenValid(string scope)
|
||||||
|
{
|
||||||
|
var token = ParseBearerTokenFromHeader();
|
||||||
|
var tokMgr = new TokenManager(_config);
|
||||||
|
|
||||||
|
return tokMgr.IsTokenValid(scope, token);
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,73 +11,72 @@ using Icarus.Controllers.Managers;
|
|||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/coverart")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class CoverArtController : BaseController
|
||||||
{
|
{
|
||||||
[Route("api/v1/coverart")]
|
#region Fields
|
||||||
[ApiController]
|
private readonly ILogger<CoverArtController> _logger;
|
||||||
[Authorize]
|
private string _connectionString;
|
||||||
public class CoverArtController : BaseController
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
public CoverArtController(ILogger<CoverArtController> logger, IConfiguration config)
|
||||||
{
|
{
|
||||||
#region Fields
|
_logger = logger;
|
||||||
private readonly ILogger<CoverArtController> _logger;
|
_config = config;
|
||||||
private string _connectionString;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
public CoverArtController(ILogger<CoverArtController> logger, IConfiguration config)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_config = config;
|
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region HTTP Routes
|
|
||||||
[HttpGet]
|
|
||||||
public IActionResult GetCoverArts()
|
|
||||||
{
|
|
||||||
var coverArtContext = new CoverArtContext(_connectionString);
|
|
||||||
|
|
||||||
var coverArtRecords = coverArtContext.CoverArtImages.ToList();
|
|
||||||
|
|
||||||
if (coverArtRecords == null)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("No cover art records");
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Found cover art records");
|
|
||||||
return Ok(coverArtRecords);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public IActionResult GetCoverArt(int id)
|
|
||||||
{
|
|
||||||
var coverArt = new CoverArt { CoverArtID = id };
|
|
||||||
|
|
||||||
var coverArtContext = new CoverArtContext(_connectionString);
|
|
||||||
|
|
||||||
coverArt = coverArtContext.RetrieveRecord(coverArt);
|
|
||||||
|
|
||||||
if (coverArt != null)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Found cover art record");
|
|
||||||
var coverArtBytes = System.IO.File.ReadAllBytes(
|
|
||||||
coverArt.ImagePath);
|
|
||||||
|
|
||||||
return File(coverArtBytes, "application/x-msdownload",
|
|
||||||
coverArt.SongTitle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Cover art not found");
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region HTTP Routes
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetCoverArts()
|
||||||
|
{
|
||||||
|
var coverArtContext = new CoverArtContext(_connectionString);
|
||||||
|
|
||||||
|
var coverArtRecords = coverArtContext.CoverArtImages.ToList();
|
||||||
|
|
||||||
|
if (coverArtRecords == null)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("No cover art records");
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Found cover art records");
|
||||||
|
return Ok(coverArtRecords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public IActionResult GetCoverArt(int id)
|
||||||
|
{
|
||||||
|
var coverArt = new CoverArt { CoverArtID = id };
|
||||||
|
|
||||||
|
var coverArtContext = new CoverArtContext(_connectionString);
|
||||||
|
|
||||||
|
coverArt = coverArtContext.RetrieveRecord(coverArt);
|
||||||
|
|
||||||
|
if (coverArt != null)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Found cover art record");
|
||||||
|
var coverArtBytes = System.IO.File.ReadAllBytes(
|
||||||
|
coverArt.ImagePath);
|
||||||
|
|
||||||
|
return File(coverArtBytes, "application/x-msdownload",
|
||||||
|
coverArt.SongTitle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Cover art not found");
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,68 +10,67 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/genre")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class GenreController : BaseController
|
||||||
{
|
{
|
||||||
[Route("api/v1/genre")]
|
#region Fields
|
||||||
[ApiController]
|
private readonly ILogger<GenreController> _logger;
|
||||||
[Authorize]
|
private string _connectionString;
|
||||||
public class GenreController : BaseController
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
public GenreController(ILogger<GenreController> logger, IConfiguration config)
|
||||||
{
|
{
|
||||||
#region Fields
|
_logger = logger;
|
||||||
private readonly ILogger<GenreController> _logger;
|
_config = config;
|
||||||
private string _connectionString;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
public GenreController(ILogger<GenreController> logger, IConfiguration config)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_config = config;
|
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region HTTP Routes
|
|
||||||
[HttpGet]
|
|
||||||
public IActionResult GetGenres()
|
|
||||||
{
|
|
||||||
var genres = new List<Genre>();
|
|
||||||
|
|
||||||
var genreStore = new GenreContext(_connectionString);
|
|
||||||
|
|
||||||
genres = genreStore.Genres.ToList();
|
|
||||||
|
|
||||||
if (genres.Count > 0)
|
|
||||||
return Ok(genres);
|
|
||||||
else
|
|
||||||
return NotFound(new List<Genre>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public IActionResult GetGenre(int id)
|
|
||||||
{
|
|
||||||
var genre = new Genre
|
|
||||||
{
|
|
||||||
GenreID = id
|
|
||||||
};
|
|
||||||
|
|
||||||
var genreStore = new GenreContext(_connectionString);
|
|
||||||
|
|
||||||
if (genreStore.DoesRecordExist(genre))
|
|
||||||
{
|
|
||||||
genre = genreStore.RetrieveRecord(genre);
|
|
||||||
|
|
||||||
return Ok(genre);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return NotFound(new Genre());
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region HTTP Routes
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetGenres()
|
||||||
|
{
|
||||||
|
var genres = new List<Genre>();
|
||||||
|
|
||||||
|
var genreStore = new GenreContext(_connectionString);
|
||||||
|
|
||||||
|
genres = genreStore.Genres.ToList();
|
||||||
|
|
||||||
|
if (genres.Count > 0)
|
||||||
|
return Ok(genres);
|
||||||
|
else
|
||||||
|
return NotFound(new List<Genre>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public IActionResult GetGenre(int id)
|
||||||
|
{
|
||||||
|
var genre = new Genre
|
||||||
|
{
|
||||||
|
GenreID = id
|
||||||
|
};
|
||||||
|
|
||||||
|
var genreStore = new GenreContext(_connectionString);
|
||||||
|
|
||||||
|
if (genreStore.DoesRecordExist(genre))
|
||||||
|
{
|
||||||
|
genre = genreStore.RetrieveRecord(genre);
|
||||||
|
|
||||||
|
return Ok(genre);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound(new Genre());
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,88 +10,87 @@ using Icarus.Controllers.Utilities;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/login")]
|
||||||
|
[ApiController]
|
||||||
|
public class LoginController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/v1/login")]
|
#region Fields
|
||||||
[ApiController]
|
private string _connectionString;
|
||||||
public class LoginController : ControllerBase
|
private IConfiguration _config;
|
||||||
|
private ILogger<LoginController> _logger;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Contructors
|
||||||
|
public LoginController(IConfiguration config, ILogger<LoginController> logger)
|
||||||
{
|
{
|
||||||
#region Fields
|
_logger = logger;
|
||||||
private string _connectionString;
|
_config = config;
|
||||||
private IConfiguration _config;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
private ILogger<LoginController> _logger;
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
#region HTTP endpoints
|
||||||
#endregion
|
[HttpPost]
|
||||||
|
public IActionResult Login([FromBody] User user)
|
||||||
|
{
|
||||||
|
var context = new UserContext(_connectionString);
|
||||||
|
|
||||||
|
_logger.LogInformation("Starting process of validating credentials");
|
||||||
|
|
||||||
|
var message = "Invalid credentials";
|
||||||
|
var password = user.Password;
|
||||||
|
|
||||||
#region Contructors
|
var loginRes = new LoginResult
|
||||||
public LoginController(IConfiguration config, ILogger<LoginController> logger)
|
|
||||||
{
|
{
|
||||||
_logger = logger;
|
Username = user.Username
|
||||||
_config = config;
|
};
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
try
|
||||||
#region HTTP endpoints
|
|
||||||
[HttpPost]
|
|
||||||
public IActionResult Login([FromBody] User user)
|
|
||||||
{
|
{
|
||||||
var context = new UserContext(_connectionString);
|
if (context.Users.FirstOrDefault(usr => usr.Username.Equals(user.Username)) != null)
|
||||||
|
|
||||||
_logger.LogInformation("Starting process of validating credentials");
|
|
||||||
|
|
||||||
var message = "Invalid credentials";
|
|
||||||
var password = user.Password;
|
|
||||||
|
|
||||||
var loginRes = new LoginResult
|
|
||||||
{
|
{
|
||||||
Username = user.Username
|
user = context.Users.FirstOrDefault(usr => usr.Username.Equals(user.Username));
|
||||||
};
|
|
||||||
|
|
||||||
try
|
var validatePass = new PasswordEncryption();
|
||||||
{
|
var validated = validatePass.VerifyPassword(user, password);
|
||||||
if (context.Users.FirstOrDefault(usr => usr.Username.Equals(user.Username)) != null)
|
if (!validated)
|
||||||
{
|
{
|
||||||
user = context.Users.FirstOrDefault(usr => usr.Username.Equals(user.Username));
|
loginRes.Message = message;
|
||||||
|
_logger.LogInformation(message);
|
||||||
var validatePass = new PasswordEncryption();
|
|
||||||
var validated = validatePass.VerifyPassword(user, password);
|
|
||||||
if (!validated)
|
|
||||||
{
|
|
||||||
loginRes.Message = message;
|
|
||||||
_logger.LogInformation(message);
|
|
||||||
|
|
||||||
return Ok(loginRes);
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation("Successfully validated user credentials");
|
|
||||||
|
|
||||||
TokenManager tk = new TokenManager(_config);
|
|
||||||
|
|
||||||
loginRes = tk.LoginSymmetric(user);
|
|
||||||
|
|
||||||
return Ok(loginRes);
|
return Ok(loginRes);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
loginRes.Message = message;
|
|
||||||
|
|
||||||
return NotFound(loginRes);
|
_logger.LogInformation("Successfully validated user credentials");
|
||||||
}
|
|
||||||
|
TokenManager tk = new TokenManager(_config);
|
||||||
|
|
||||||
|
loginRes = tk.LoginSymmetric(user);
|
||||||
|
|
||||||
|
return Ok(loginRes);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
else
|
||||||
{
|
{
|
||||||
_logger.LogError("An error occurred: {0}", ex.Message);
|
loginRes.Message = message;
|
||||||
_logger.LogError("Inner Exception: {0}", ex.InnerException.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NotFound(loginRes);
|
return NotFound(loginRes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError("An error occurred: {0}", ex.Message);
|
||||||
|
_logger.LogError("Inner Exception: {0}", ex.InnerException.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotFound(loginRes);
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,74 +12,73 @@ using Icarus.Controllers.Utilities;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/register")]
|
||||||
|
[ApiController]
|
||||||
|
public class RegisterController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/v1/register")]
|
#region Fields
|
||||||
[ApiController]
|
private string _connectionString;
|
||||||
public class RegisterController : ControllerBase
|
private IConfiguration _config;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
public RegisterController(IConfiguration config)
|
||||||
{
|
{
|
||||||
#region Fields
|
_config = config;
|
||||||
private string _connectionString;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
private IConfiguration _config;
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult RegisterUser([FromBody] User user)
|
||||||
|
{
|
||||||
|
PasswordEncryption pe = new PasswordEncryption();
|
||||||
|
user.Password = pe.HashPassword(user);
|
||||||
|
user.EmailVerified = false;
|
||||||
|
user.Status = "Registered";
|
||||||
|
user.DateCreated = DateTime.Now;
|
||||||
|
|
||||||
#region Properties
|
UserContext context = null;
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
try
|
||||||
#region Constructor
|
|
||||||
public RegisterController(IConfiguration config)
|
|
||||||
{
|
{
|
||||||
_config = config;
|
context = new UserContext(_config.GetConnectionString("DefaultConnection"));
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
context.Add(user);
|
||||||
|
context.SaveChanges();
|
||||||
}
|
}
|
||||||
#endregion
|
catch (Exception ex)
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
public IActionResult RegisterUser([FromBody] User user)
|
|
||||||
{
|
{
|
||||||
PasswordEncryption pe = new PasswordEncryption();
|
var msg = ex.Message;
|
||||||
user.Password = pe.HashPassword(user);
|
var stackTrace = ex.StackTrace;
|
||||||
user.EmailVerified = false;
|
|
||||||
user.Status = "Registered";
|
|
||||||
user.DateCreated = DateTime.Now;
|
|
||||||
|
|
||||||
UserContext context = null;
|
Console.WriteLine($"An error occurred: {msg}");
|
||||||
|
}
|
||||||
|
|
||||||
try
|
var registerResult = new RegisterResult
|
||||||
{
|
{
|
||||||
context = new UserContext(_config.GetConnectionString("DefaultConnection"));
|
Username = user.Username
|
||||||
context.Add(user);
|
};
|
||||||
context.SaveChanges();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var msg = ex.Message;
|
|
||||||
var stackTrace = ex.StackTrace;
|
|
||||||
|
|
||||||
Console.WriteLine($"An error occurred: {msg}");
|
if (context.Users.FirstOrDefault(sng => sng.Username.Equals(user.Username)) != null)
|
||||||
}
|
{
|
||||||
|
registerResult.Message = "Successful registration";
|
||||||
|
registerResult.SuccessfullyRegistered = true;
|
||||||
|
|
||||||
var registerResult = new RegisterResult
|
return Ok(registerResult);
|
||||||
{
|
}
|
||||||
Username = user.Username
|
else
|
||||||
};
|
{
|
||||||
|
registerResult.Message = "Registration failed";
|
||||||
|
registerResult.SuccessfullyRegistered = false;
|
||||||
|
|
||||||
if (context.Users.FirstOrDefault(sng => sng.Username.Equals(user.Username)) != null)
|
return Ok(registerResult);
|
||||||
{
|
|
||||||
registerResult.Message = "Successful registration";
|
|
||||||
registerResult.SuccessfullyRegistered = true;
|
|
||||||
|
|
||||||
return Ok(registerResult);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
registerResult.Message = "Registration failed";
|
|
||||||
registerResult.SuccessfullyRegistered = false;
|
|
||||||
|
|
||||||
return Ok(registerResult);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,50 +15,49 @@ using Icarus.Controllers.Utilities;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/song/compressed/data")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class SongCompressedDataController : BaseController
|
||||||
{
|
{
|
||||||
[Route("api/v1/song/compressed/data")]
|
#region Fields
|
||||||
[ApiController]
|
private string _connectionString;
|
||||||
[Authorize]
|
private string _songTempDir;
|
||||||
public class SongCompressedDataController : BaseController
|
private string _archiveDir;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
public SongCompressedDataController(IConfiguration config)
|
||||||
{
|
{
|
||||||
#region Fields
|
_songTempDir = _config.GetValue<string>("TemporaryMusicPath");
|
||||||
private string _connectionString;
|
_archiveDir = _config.GetValue<string>("ArchivePath");
|
||||||
private string _songTempDir;
|
_config = config;
|
||||||
private string _archiveDir;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructor
|
|
||||||
public SongCompressedDataController(IConfiguration config)
|
|
||||||
{
|
|
||||||
_songTempDir = _config.GetValue<string>("TemporaryMusicPath");
|
|
||||||
_archiveDir = _config.GetValue<string>("ArchivePath");
|
|
||||||
_config = config;
|
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region API Routes
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public async Task<IActionResult> DownloadCompressedSong(int id)
|
|
||||||
{
|
|
||||||
var context = new SongContext(_connectionString);
|
|
||||||
|
|
||||||
SongCompression cmp = new SongCompression(_archiveDir);
|
|
||||||
|
|
||||||
Console.WriteLine($"Archive directory root: {_archiveDir}");
|
|
||||||
|
|
||||||
Console.WriteLine("Starting process of retrieving comrpessed song");
|
|
||||||
SongData song = await cmp.RetrieveCompressedSong(context.RetrieveRecord(new Song{ SongID = id }));
|
|
||||||
|
|
||||||
return File(song.Data, "application/x-msdownload", cmp.CompressedSongFilename);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region API Routes
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public async Task<IActionResult> DownloadCompressedSong(int id)
|
||||||
|
{
|
||||||
|
var context = new SongContext(_connectionString);
|
||||||
|
|
||||||
|
SongCompression cmp = new SongCompression(_archiveDir);
|
||||||
|
|
||||||
|
Console.WriteLine($"Archive directory root: {_archiveDir}");
|
||||||
|
|
||||||
|
Console.WriteLine("Starting process of retrieving comrpessed song");
|
||||||
|
SongData song = await cmp.RetrieveCompressedSong(context.RetrieveRecord(new Song{ SongID = id }));
|
||||||
|
|
||||||
|
return File(song.Data, "application/x-msdownload", cmp.CompressedSongFilename);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,94 +14,93 @@ using Icarus.Controllers.Utilities;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/song")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class SongController : BaseController
|
||||||
{
|
{
|
||||||
[Route("api/v1/song")]
|
#region Fields
|
||||||
[ApiController]
|
private readonly ILogger<SongController> _logger;
|
||||||
[Authorize]
|
private string _connectionString;
|
||||||
public class SongController : BaseController
|
private SongManager _songMgr;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
public SongController(IConfiguration config, ILogger<SongController> logger)
|
||||||
{
|
{
|
||||||
#region Fields
|
_config = config;
|
||||||
private readonly ILogger<SongController> _logger;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
private string _connectionString;
|
_logger = logger;
|
||||||
private SongManager _songMgr;
|
_songMgr = new SongManager(config);
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructor
|
|
||||||
public SongController(IConfiguration config, ILogger<SongController> logger)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
_logger = logger;
|
|
||||||
_songMgr = new SongManager(config);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
#region HTTP Endpoints
|
|
||||||
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public IActionResult GetSongs()
|
|
||||||
{
|
|
||||||
List<Song> songs = new List<Song>();
|
|
||||||
Console.WriteLine("Attemtping to retrieve songs");
|
|
||||||
_logger.LogInformation("Attempting to retrieve songs");
|
|
||||||
|
|
||||||
var context = new SongContext(_connectionString);
|
|
||||||
|
|
||||||
songs = context.Songs.ToList();
|
|
||||||
|
|
||||||
if (songs.Count > 0)
|
|
||||||
return Ok(songs);
|
|
||||||
else
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public IActionResult GetSong(int id)
|
|
||||||
{
|
|
||||||
var context = new SongContext(_connectionString);
|
|
||||||
|
|
||||||
Song song = new Song { SongID = id };
|
|
||||||
song = context.RetrieveRecord(song);
|
|
||||||
|
|
||||||
Console.WriteLine("Here");
|
|
||||||
|
|
||||||
if (song.SongID != 0)
|
|
||||||
return Ok(song);
|
|
||||||
else
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPut("{id}")]
|
|
||||||
public IActionResult UpdateSong(int id, [FromBody] Song song)
|
|
||||||
{
|
|
||||||
var context = new SongContext(_connectionString);
|
|
||||||
|
|
||||||
song.SongID = id;
|
|
||||||
Console.WriteLine("Retrieving filepath of song");
|
|
||||||
_logger.LogInformation("Retrieving filepath of song");
|
|
||||||
|
|
||||||
if (!_songMgr.DoesSongExist(song))
|
|
||||||
{
|
|
||||||
return NotFound(new SongResult
|
|
||||||
{
|
|
||||||
Message = "Song does not exist"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var songRes = _songMgr.UpdateSong(song);
|
|
||||||
|
|
||||||
return Ok(songRes);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
#region HTTP Endpoints
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetSongs()
|
||||||
|
{
|
||||||
|
List<Song> songs = new List<Song>();
|
||||||
|
Console.WriteLine("Attemtping to retrieve songs");
|
||||||
|
_logger.LogInformation("Attempting to retrieve songs");
|
||||||
|
|
||||||
|
var context = new SongContext(_connectionString);
|
||||||
|
|
||||||
|
songs = context.Songs.ToList();
|
||||||
|
|
||||||
|
if (songs.Count > 0)
|
||||||
|
return Ok(songs);
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public IActionResult GetSong(int id)
|
||||||
|
{
|
||||||
|
var context = new SongContext(_connectionString);
|
||||||
|
|
||||||
|
Song song = new Song { SongID = id };
|
||||||
|
song = context.RetrieveRecord(song);
|
||||||
|
|
||||||
|
Console.WriteLine("Here");
|
||||||
|
|
||||||
|
if (song.SongID != 0)
|
||||||
|
return Ok(song);
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{id}")]
|
||||||
|
public IActionResult UpdateSong(int id, [FromBody] Song song)
|
||||||
|
{
|
||||||
|
var context = new SongContext(_connectionString);
|
||||||
|
|
||||||
|
song.SongID = id;
|
||||||
|
Console.WriteLine("Retrieving filepath of song");
|
||||||
|
_logger.LogInformation("Retrieving filepath of song");
|
||||||
|
|
||||||
|
if (!_songMgr.DoesSongExist(song))
|
||||||
|
{
|
||||||
|
return NotFound(new SongResult
|
||||||
|
{
|
||||||
|
Message = "Song does not exist"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var songRes = _songMgr.UpdateSong(song);
|
||||||
|
|
||||||
|
return Ok(songRes);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,152 +16,151 @@ using Icarus.Controllers.Managers;
|
|||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/song/data")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class SongDataController : BaseController
|
||||||
{
|
{
|
||||||
[Route("api/v1/song/data")]
|
#region Fields
|
||||||
[ApiController]
|
private string _connectionString;
|
||||||
[Authorize]
|
private ILogger<SongDataController> _logger;
|
||||||
public class SongDataController : BaseController
|
private SongManager _songMgr;
|
||||||
|
private string _songTempDir;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
public SongDataController(IConfiguration config, ILogger<SongDataController> logger)
|
||||||
{
|
{
|
||||||
#region Fields
|
_config = config;
|
||||||
private string _connectionString;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
private ILogger<SongDataController> _logger;
|
_logger = logger;
|
||||||
private SongManager _songMgr;
|
_songTempDir = _config.GetValue<string>("TemporaryMusicPath");
|
||||||
private string _songTempDir;
|
_songMgr = new SongManager(config, _songTempDir);
|
||||||
#endregion
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
[HttpGet("download/{id}")]
|
||||||
#endregion
|
public IActionResult Download(int id)
|
||||||
|
{
|
||||||
|
var songContext = new SongContext(_connectionString);
|
||||||
|
var songMetaData = songContext.RetrieveRecord(new Song { SongID = id});
|
||||||
|
|
||||||
|
var song = _songMgr.RetrieveSong(songMetaData).Result;
|
||||||
|
|
||||||
|
return File(song.Data, "application/x-msdownload", songMetaData.Filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assumes that the song already has metadata such as
|
||||||
#region Constructor
|
// Title
|
||||||
public SongDataController(IConfiguration config, ILogger<SongDataController> logger)
|
// Artist
|
||||||
|
// Album
|
||||||
|
// Genre
|
||||||
|
// Year
|
||||||
|
// Track
|
||||||
|
// Track count
|
||||||
|
// Disc
|
||||||
|
// Disc count
|
||||||
|
// Cover art
|
||||||
|
//
|
||||||
|
[HttpPost("upload"), DisableRequestSizeLimit]
|
||||||
|
public IActionResult Upload([FromForm(Name = "file")] List<IFormFile> songData)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_config = config;
|
// Console.WriteLine("Uploading song...");
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
_logger.LogInformation("Uploading song...");
|
||||||
_logger = logger;
|
|
||||||
_songTempDir = _config.GetValue<string>("TemporaryMusicPath");
|
|
||||||
_songMgr = new SongManager(config, _songTempDir);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
var uploads = _songTempDir;
|
||||||
|
// Console.WriteLine($"Song Root Path {uploads}");
|
||||||
|
_logger.LogInformation($"Song root path {uploads}");
|
||||||
|
|
||||||
[HttpGet("download/{id}")]
|
foreach (var sng in songData)
|
||||||
public IActionResult Download(int id)
|
if (sng.Length > 0)
|
||||||
{
|
|
||||||
var songContext = new SongContext(_connectionString);
|
|
||||||
var songMetaData = songContext.RetrieveRecord(new Song { SongID = id});
|
|
||||||
|
|
||||||
var song = _songMgr.RetrieveSong(songMetaData).Result;
|
|
||||||
|
|
||||||
return File(song.Data, "application/x-msdownload", songMetaData.Filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assumes that the song already has metadata such as
|
|
||||||
// Title
|
|
||||||
// Artist
|
|
||||||
// Album
|
|
||||||
// Genre
|
|
||||||
// Year
|
|
||||||
// Track
|
|
||||||
// Track count
|
|
||||||
// Disc
|
|
||||||
// Disc count
|
|
||||||
// Cover art
|
|
||||||
//
|
|
||||||
[HttpPost("upload"), DisableRequestSizeLimit]
|
|
||||||
public IActionResult Upload([FromForm(Name = "file")] List<IFormFile> songData)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Console.WriteLine("Uploading song...");
|
|
||||||
_logger.LogInformation("Uploading song...");
|
|
||||||
|
|
||||||
var uploads = _songTempDir;
|
|
||||||
// Console.WriteLine($"Song Root Path {uploads}");
|
|
||||||
_logger.LogInformation($"Song root path {uploads}");
|
|
||||||
|
|
||||||
foreach (var sng in songData)
|
|
||||||
if (sng.Length > 0)
|
|
||||||
{
|
|
||||||
// Console.WriteLine($"Song filename {sng.FileName}");
|
|
||||||
_logger.LogInformation($"Song filename {sng.FileName}");
|
|
||||||
|
|
||||||
_songMgr.SaveSongToFileSystem(sng).Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var msg = ex.Message;
|
|
||||||
_logger.LogError(msg, "An error occurred");
|
|
||||||
}
|
|
||||||
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The client is expected to send the file, metadata, and cover art separately.
|
|
||||||
// Any metadata already on the file will be overwritten with values from the metadata
|
|
||||||
// as well as the cover art
|
|
||||||
//
|
|
||||||
[HttpPost("upload/with/data")]
|
|
||||||
public IActionResult UploadWithData([FromForm] UploadSongWithDataForm up)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (up.SongData.Length > 0 && up.CoverArtData.Length > 0 && !string.IsNullOrEmpty(up.SongFile))
|
|
||||||
{
|
{
|
||||||
var song = Newtonsoft.Json.JsonConvert.DeserializeObject<Song>(up.SongFile);
|
// Console.WriteLine($"Song filename {sng.FileName}");
|
||||||
_logger.LogInformation($"Song title: {song.Title}");
|
_logger.LogInformation($"Song filename {sng.FileName}");
|
||||||
|
|
||||||
_songMgr.SaveSongToFileSystem(up.SongData, up.CoverArtData, song);
|
_songMgr.SaveSongToFileSystem(sng).Wait();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
return Ok();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
_logger.LogError(msg, "An error occurred");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The client is expected to send the file, metadata, and cover art separately.
|
||||||
|
// Any metadata already on the file will be overwritten with values from the metadata
|
||||||
|
// as well as the cover art
|
||||||
|
//
|
||||||
|
[HttpPost("upload/with/data")]
|
||||||
|
public IActionResult UploadWithData([FromForm] UploadSongWithDataForm up)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (up.SongData.Length > 0 && up.CoverArtData.Length > 0 && !string.IsNullOrEmpty(up.SongFile))
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message, "An error occurred");
|
var song = Newtonsoft.Json.JsonConvert.DeserializeObject<Song>(up.SongFile);
|
||||||
|
_logger.LogInformation($"Song title: {song.Title}");
|
||||||
|
|
||||||
|
_songMgr.SaveSongToFileSystem(up.SongData, up.CoverArtData, song);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message, "An error occurred");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("delete/{id}")]
|
||||||
|
public IActionResult DeleteSong(int id)
|
||||||
|
{
|
||||||
|
var songContext = new SongContext(_connectionString);
|
||||||
|
|
||||||
|
var songMetaData = new Song{ SongID = id };
|
||||||
|
Console.WriteLine($"Id {songMetaData.SongID}");
|
||||||
|
|
||||||
|
songMetaData = songContext.RetrieveRecord(songMetaData);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(songMetaData.Title))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Song does not exist");
|
||||||
|
return NotFound("Song does not exist");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Starting process of deleting song from the filesystem and database");
|
||||||
|
|
||||||
|
_songMgr.DeleteSong(songMetaData);
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("delete/{id}")]
|
}
|
||||||
public IActionResult DeleteSong(int id)
|
|
||||||
{
|
|
||||||
var songContext = new SongContext(_connectionString);
|
|
||||||
|
|
||||||
var songMetaData = new Song{ SongID = id };
|
public class UploadSongWithDataForm
|
||||||
Console.WriteLine($"Id {songMetaData.SongID}");
|
{
|
||||||
|
[FromForm(Name = "file")]
|
||||||
songMetaData = songContext.RetrieveRecord(songMetaData);
|
public IFormFile SongData { get; set; }
|
||||||
|
// NOTE: Think about making this optional and if it is not provided, use the stock cover art
|
||||||
if (string.IsNullOrEmpty(songMetaData.Title))
|
[FromForm(Name = "cover")]
|
||||||
{
|
public IFormFile CoverArtData { get; set; }
|
||||||
_logger.LogInformation("Song does not exist");
|
[FromForm(Name = "metadata")]
|
||||||
return NotFound("Song does not exist");
|
public string SongFile { get; set; }
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Starting process of deleting song from the filesystem and database");
|
|
||||||
|
|
||||||
_songMgr.DeleteSong(songMetaData);
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UploadSongWithDataForm
|
|
||||||
{
|
|
||||||
[FromForm(Name = "file")]
|
|
||||||
public IFormFile SongData { get; set; }
|
|
||||||
// NOTE: Think about making this optional and if it is not provided, use the stock cover art
|
|
||||||
[FromForm(Name = "cover")]
|
|
||||||
public IFormFile CoverArtData { get; set; }
|
|
||||||
[FromForm(Name = "metadata")]
|
|
||||||
public string SongFile { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,54 +16,53 @@ using Icarus.Models;
|
|||||||
using Icarus.Controllers.Managers;
|
using Icarus.Controllers.Managers;
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus.Controllers.V1
|
namespace Icarus.Controllers.V1;
|
||||||
|
|
||||||
|
[Route("api/v1/song/stream")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class SongStreamController : BaseController
|
||||||
{
|
{
|
||||||
[Route("api/v1/song/stream")]
|
#region Fields
|
||||||
[ApiController]
|
private ILogger<SongStreamController> _logger;
|
||||||
[Authorize]
|
private string _connectionString;
|
||||||
public class SongStreamController : BaseController
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
public SongStreamController(ILogger<SongStreamController> logger, IConfiguration config)
|
||||||
{
|
{
|
||||||
#region Fields
|
_logger = logger;
|
||||||
private ILogger<SongStreamController> _logger;
|
_config = config;
|
||||||
private string _connectionString;
|
_connectionString = _config.GetConnectionString("DefaultConnection");
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Constructor
|
|
||||||
public SongStreamController(ILogger<SongStreamController> logger, IConfiguration config)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_config = config;
|
|
||||||
_connectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region HTTP endpoints
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public async Task<IActionResult> StreamSong(int id)
|
|
||||||
{
|
|
||||||
var context = new SongContext(_config.GetConnectionString("DefaultConnection"));
|
|
||||||
|
|
||||||
var song = context.Songs.FirstOrDefault(sng => sng.SongID == id);
|
|
||||||
|
|
||||||
var stream = new FileStream(song.SongPath(), FileMode.Open, FileAccess.Read);
|
|
||||||
stream.Position = 0;
|
|
||||||
var filename = $"{song.Title}.mp3";
|
|
||||||
|
|
||||||
_logger.LogInformation("Starting to stream song...>");
|
|
||||||
Console.WriteLine("Starting to streamsong...");
|
|
||||||
|
|
||||||
var file = await Task.Run(() => {
|
|
||||||
return File(stream, "application/octet-stream", filename);
|
|
||||||
});
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region HTTP endpoints
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public async Task<IActionResult> StreamSong(int id)
|
||||||
|
{
|
||||||
|
var context = new SongContext(_config.GetConnectionString("DefaultConnection"));
|
||||||
|
|
||||||
|
var song = context.Songs.FirstOrDefault(sng => sng.SongID == id);
|
||||||
|
|
||||||
|
var stream = new FileStream(song.SongPath(), FileMode.Open, FileAccess.Read);
|
||||||
|
stream.Position = 0;
|
||||||
|
var filename = $"{song.Title}.mp3";
|
||||||
|
|
||||||
|
_logger.LogInformation("Starting to stream song...>");
|
||||||
|
Console.WriteLine("Starting to streamsong...");
|
||||||
|
|
||||||
|
var file = await Task.Run(() => {
|
||||||
|
return File(stream, "application/octet-stream", filename);
|
||||||
|
});
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,32 +6,31 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Database.Contexts
|
namespace Icarus.Database.Contexts;
|
||||||
|
|
||||||
|
public class AlbumContext : DbContext
|
||||||
{
|
{
|
||||||
public class AlbumContext : DbContext
|
public DbSet<Album> Albums { get; set; }
|
||||||
|
|
||||||
|
public AlbumContext(DbContextOptions<AlbumContext> options) : base(options) { }
|
||||||
|
public AlbumContext(string connString) : base(new DbContextOptionsBuilder<AlbumContext>()
|
||||||
|
.UseMySQL(connString).Options)
|
||||||
{
|
{
|
||||||
public DbSet<Album> Albums { get; set; }
|
}
|
||||||
|
|
||||||
public AlbumContext(DbContextOptions<AlbumContext> options) : base(options) { }
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
public AlbumContext(string connString) : base(new DbContextOptionsBuilder<AlbumContext>()
|
{
|
||||||
.UseMySQL(connString).Options)
|
modelBuilder.Entity<Album>()
|
||||||
{
|
.ToTable("Album");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
public Album RetrieveRecord(Album album)
|
||||||
{
|
{
|
||||||
modelBuilder.Entity<Album>()
|
return Albums.FirstOrDefault(alb => alb.AlbumID == album.AlbumID);
|
||||||
.ToTable("Album");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Album RetrieveRecord(Album album)
|
public bool DoesRecordExist(Album album)
|
||||||
{
|
{
|
||||||
return Albums.FirstOrDefault(alb => alb.AlbumID == album.AlbumID);
|
return Albums.FirstOrDefault(alb => alb.AlbumID == album.AlbumID) != null ? true : false;
|
||||||
}
|
|
||||||
|
|
||||||
public bool DoesRecordExist(Album album)
|
|
||||||
{
|
|
||||||
return Albums.FirstOrDefault(alb => alb.AlbumID == album.AlbumID) != null ? true : false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,34 +6,33 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Database.Contexts
|
namespace Icarus.Database.Contexts;
|
||||||
|
|
||||||
|
public class ArtistContext : DbContext
|
||||||
{
|
{
|
||||||
public class ArtistContext : DbContext
|
public DbSet<Artist> Artists { get; set; }
|
||||||
|
|
||||||
|
public ArtistContext(DbContextOptions<ArtistContext> options) : base (options) { }
|
||||||
|
public ArtistContext(string connString) : base(new DbContextOptionsBuilder<ArtistContext>()
|
||||||
|
.UseMySQL(connString).Options)
|
||||||
{
|
{
|
||||||
public DbSet<Artist> Artists { get; set; }
|
}
|
||||||
|
|
||||||
public ArtistContext(DbContextOptions<ArtistContext> options) : base (options) { }
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
public ArtistContext(string connString) : base(new DbContextOptionsBuilder<ArtistContext>()
|
{
|
||||||
.UseMySQL(connString).Options)
|
modelBuilder.Entity<Artist>()
|
||||||
{
|
.ToTable("Artist");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
public Artist RetrieveRecord(Artist artist)
|
||||||
{
|
{
|
||||||
modelBuilder.Entity<Artist>()
|
|
||||||
.ToTable("Artist");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Artist RetrieveRecord(Artist artist)
|
return Artists.FirstOrDefault(arst => arst.ArtistID == artist.ArtistID);
|
||||||
{
|
}
|
||||||
|
|
||||||
return Artists.FirstOrDefault(arst => arst.ArtistID == artist.ArtistID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public bool DoesRecordExist(Artist artist)
|
public bool DoesRecordExist(Artist artist)
|
||||||
{
|
{
|
||||||
return Artists.FirstOrDefault(arst => arst.ArtistID == artist.ArtistID) != null ? true : false;
|
return Artists.FirstOrDefault(arst => arst.ArtistID == artist.ArtistID) != null ? true : false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,32 +6,31 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Database.Contexts
|
namespace Icarus.Database.Contexts;
|
||||||
|
|
||||||
|
public class CoverArtContext : DbContext
|
||||||
{
|
{
|
||||||
public class CoverArtContext : DbContext
|
public DbSet<CoverArt> CoverArtImages { get; set; }
|
||||||
|
|
||||||
|
public CoverArtContext(DbContextOptions<CoverArtContext> options) : base(options) { }
|
||||||
|
public CoverArtContext(string connString) : base(new DbContextOptionsBuilder<CoverArtContext>()
|
||||||
|
.UseMySQL(connString).Options)
|
||||||
{
|
{
|
||||||
public DbSet<CoverArt> CoverArtImages { get; set; }
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder.Entity<CoverArt>()
|
||||||
|
.ToTable("CoverArt");
|
||||||
|
}
|
||||||
|
|
||||||
public CoverArtContext(DbContextOptions<CoverArtContext> options) : base(options) { }
|
public CoverArt RetrieveRecord(CoverArt cover)
|
||||||
public CoverArtContext(string connString) : base(new DbContextOptionsBuilder<CoverArtContext>()
|
{
|
||||||
.UseMySQL(connString).Options)
|
return CoverArtImages.FirstOrDefault(cov => cov.CoverArtID == cover.CoverArtID);
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
modelBuilder.Entity<CoverArt>()
|
|
||||||
.ToTable("CoverArt");
|
|
||||||
}
|
|
||||||
|
|
||||||
public CoverArt RetrieveRecord(CoverArt cover)
|
public bool DoesRecordExist(CoverArt cover)
|
||||||
{
|
{
|
||||||
return CoverArtImages.FirstOrDefault(cov => cov.CoverArtID == cover.CoverArtID);
|
return CoverArtImages.FirstOrDefault(cov => cov.CoverArtID == cover.CoverArtID) != null ? true : false;
|
||||||
}
|
|
||||||
|
|
||||||
public bool DoesRecordExist(CoverArt cover)
|
|
||||||
{
|
|
||||||
return CoverArtImages.FirstOrDefault(cov => cov.CoverArtID == cover.CoverArtID) != null ? true : false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,32 +6,31 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Database.Contexts
|
namespace Icarus.Database.Contexts;
|
||||||
|
|
||||||
|
public class GenreContext : DbContext
|
||||||
{
|
{
|
||||||
public class GenreContext : DbContext
|
public DbSet<Genre> Genres { get; set; }
|
||||||
|
public GenreContext(DbContextOptions<GenreContext> options) : base(options) { }
|
||||||
|
public GenreContext(string connString) : base(new DbContextOptionsBuilder<GenreContext>()
|
||||||
|
.UseMySQL(connString).Options)
|
||||||
{
|
{
|
||||||
public DbSet<Genre> Genres { get; set; }
|
}
|
||||||
public GenreContext(DbContextOptions<GenreContext> options) : base(options) { }
|
|
||||||
public GenreContext(string connString) : base(new DbContextOptionsBuilder<GenreContext>()
|
|
||||||
.UseMySQL(connString).Options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
modelBuilder.Entity<Genre>()
|
modelBuilder.Entity<Genre>()
|
||||||
.ToTable("Genre");
|
.ToTable("Genre");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Genre RetrieveRecord(Genre genre)
|
public Genre RetrieveRecord(Genre genre)
|
||||||
{
|
{
|
||||||
return Genres.FirstOrDefault(gnr => gnr.GenreID == genre.GenreID);
|
return Genres.FirstOrDefault(gnr => gnr.GenreID == genre.GenreID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DoesRecordExist(Genre genre)
|
public bool DoesRecordExist(Genre genre)
|
||||||
{
|
{
|
||||||
return Genres.FirstOrDefault(gnr => gnr.GenreID == genre.GenreID) != null ? true : false;
|
return Genres.FirstOrDefault(gnr => gnr.GenreID == genre.GenreID) != null ? true : false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,84 +6,83 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Database.Contexts
|
namespace Icarus.Database.Contexts;
|
||||||
{
|
|
||||||
public class SongContext : DbContext
|
public class SongContext : DbContext
|
||||||
|
{
|
||||||
|
public DbSet<Song> Songs { get; set; }
|
||||||
|
|
||||||
|
public SongContext(string connString) : base(new DbContextOptionsBuilder<SongContext>()
|
||||||
|
.UseMySQL(connString).Options)
|
||||||
{
|
{
|
||||||
public DbSet<Song> Songs { get; set; }
|
}
|
||||||
|
|
||||||
public SongContext(string connString) : base(new DbContextOptionsBuilder<SongContext>()
|
|
||||||
.UseMySQL(connString).Options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public SongContext(DbContextOptions<SongContext> options) : base(options) { }
|
public SongContext(DbContextOptions<SongContext> options) : base(options) { }
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.ToTable("Song");
|
.ToTable("Song");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.HasOne(s => s.Album)
|
.HasOne(s => s.Album)
|
||||||
.WithMany(al => al.Songs)
|
.WithMany(al => al.Songs)
|
||||||
.HasForeignKey(s => s.AlbumID)
|
.HasForeignKey(s => s.AlbumID)
|
||||||
.OnDelete(DeleteBehavior.SetNull);
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.HasOne(sa => sa.SongArtist)
|
.HasOne(sa => sa.SongArtist)
|
||||||
.WithMany(ar => ar.Songs)
|
.WithMany(ar => ar.Songs)
|
||||||
.HasForeignKey(s => s.ArtistID)
|
.HasForeignKey(s => s.ArtistID)
|
||||||
.OnDelete(DeleteBehavior.SetNull);
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.HasOne(s => s.SongGenre)
|
.HasOne(s => s.SongGenre)
|
||||||
.WithMany(gnr => gnr.Songs)
|
.WithMany(gnr => gnr.Songs)
|
||||||
.HasForeignKey(s => s.GenreID)
|
.HasForeignKey(s => s.GenreID)
|
||||||
.OnDelete(DeleteBehavior.SetNull);
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.HasOne(s => s.SongYear)
|
.HasOne(s => s.SongYear)
|
||||||
.WithMany(yr => yr.Songs)
|
.WithMany(yr => yr.Songs)
|
||||||
.HasForeignKey(s => s.YearID)
|
.HasForeignKey(s => s.YearID)
|
||||||
.OnDelete(DeleteBehavior.SetNull);
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.HasOne(s => s.SongCoverArt)
|
.HasOne(s => s.SongCoverArt)
|
||||||
.WithMany(ca => ca.Songs)
|
.WithMany(ca => ca.Songs)
|
||||||
.HasForeignKey(s => s.CoverArtID)
|
.HasForeignKey(s => s.CoverArtID)
|
||||||
.OnDelete(DeleteBehavior.SetNull);
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.Property(s => s.Year)
|
.Property(s => s.Year)
|
||||||
.IsRequired(false);
|
.IsRequired(false);
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.Property(s => s.GenreID)
|
.Property(s => s.GenreID)
|
||||||
.IsRequired(false);
|
.IsRequired(false);
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.Property(s => s.ArtistID)
|
.Property(s => s.ArtistID)
|
||||||
.IsRequired(false);
|
.IsRequired(false);
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.Property(s => s.AlbumID)
|
.Property(s => s.AlbumID)
|
||||||
.IsRequired(false);
|
.IsRequired(false);
|
||||||
modelBuilder.Entity<Song>()
|
modelBuilder.Entity<Song>()
|
||||||
.Property(s => s.CoverArtID)
|
.Property(s => s.CoverArtID)
|
||||||
.IsRequired(false);
|
.IsRequired(false);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Song RetrieveRecord(Song song)
|
|
||||||
{
|
|
||||||
return Songs.FirstOrDefault(sng => sng.SongID == song.SongID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public bool DoesRecordExist(Song song)
|
|
||||||
{
|
|
||||||
return Songs.FirstOrDefault(sng => sng.SongID == song.SongID) != null ? true : false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
public Song RetrieveRecord(Song song)
|
||||||
|
{
|
||||||
|
return Songs.FirstOrDefault(sng => sng.SongID == song.SongID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool DoesRecordExist(Song song)
|
||||||
|
{
|
||||||
|
return Songs.FirstOrDefault(sng => sng.SongID == song.SongID) != null ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,42 +12,41 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
|
|
||||||
using Icarus.Models;
|
using Icarus.Models;
|
||||||
|
|
||||||
namespace Icarus.Database.Contexts
|
namespace Icarus.Database.Contexts;
|
||||||
{
|
|
||||||
public class UserContext : DbContext
|
public class UserContext : DbContext
|
||||||
|
{
|
||||||
|
public DbSet<User> Users { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
public UserContext(DbContextOptions<UserContext> options) : base(options) { }
|
||||||
|
[ActivatorUtilitiesConstructor]
|
||||||
|
public UserContext(string connString) : base(new DbContextOptionsBuilder<UserContext>()
|
||||||
|
.UseMySQL(connString).Options)
|
||||||
{
|
{
|
||||||
public DbSet<User> Users { get; set; }
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Constructors
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
public UserContext(DbContextOptions<UserContext> options) : base(options) { }
|
{
|
||||||
[ActivatorUtilitiesConstructor]
|
modelBuilder.Entity<User>()
|
||||||
public UserContext(string connString) : base(new DbContextOptionsBuilder<UserContext>()
|
.ToTable("User");
|
||||||
.UseMySQL(connString).Options)
|
modelBuilder.Entity<User>()
|
||||||
{
|
.Property(u => u.LastLogin).IsRequired(false);
|
||||||
}
|
modelBuilder.Entity<User>()
|
||||||
#endregion
|
.Property(u => u.DateCreated).HasDefaultValue(DateTime.Now);
|
||||||
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
modelBuilder.Entity<User>()
|
|
||||||
.ToTable("User");
|
|
||||||
modelBuilder.Entity<User>()
|
|
||||||
.Property(u => u.LastLogin).IsRequired(false);
|
|
||||||
modelBuilder.Entity<User>()
|
|
||||||
.Property(u => u.DateCreated).HasDefaultValue(DateTime.Now);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public User RetrieveRecord(User user)
|
|
||||||
{
|
|
||||||
return Users.FirstOrDefault(usr => usr.UserID == user.UserID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DoesRecordExist(User user)
|
|
||||||
{
|
|
||||||
return Users.FirstOrDefault(usr => usr.UserID == user.UserID) != null ? true : false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
public User RetrieveRecord(User user)
|
||||||
|
{
|
||||||
|
return Users.FirstOrDefault(usr => usr.UserID == user.UserID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DoesRecordExist(User user)
|
||||||
|
{
|
||||||
|
return Users.FirstOrDefault(usr => usr.UserID == user.UserID) != null ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+19
-20
@@ -4,25 +4,24 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
{
|
|
||||||
public class Album
|
|
||||||
{
|
|
||||||
[JsonProperty("album_id")]
|
|
||||||
public int AlbumID { get; set; }
|
|
||||||
[JsonProperty("title")]
|
|
||||||
public string Title { get; set; }
|
|
||||||
[JsonProperty("album_artist")]
|
|
||||||
[Column("Artist")]
|
|
||||||
public string AlbumArtist { get; set; }
|
|
||||||
[JsonProperty("song_count")]
|
|
||||||
[NotMapped]
|
|
||||||
public int SongCount { get; set; }
|
|
||||||
[JsonProperty("year")]
|
|
||||||
public int Year { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
public class Album
|
||||||
[NotMapped]
|
{
|
||||||
public List<Song> Songs { get; set; }
|
[JsonProperty("album_id")]
|
||||||
}
|
public int AlbumID { get; set; }
|
||||||
|
[JsonProperty("title")]
|
||||||
|
public string Title { get; set; }
|
||||||
|
[JsonProperty("album_artist")]
|
||||||
|
[Column("Artist")]
|
||||||
|
public string AlbumArtist { get; set; }
|
||||||
|
[JsonProperty("song_count")]
|
||||||
|
[NotMapped]
|
||||||
|
public int SongCount { get; set; }
|
||||||
|
[JsonProperty("year")]
|
||||||
|
public int Year { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
[NotMapped]
|
||||||
|
public List<Song> Songs { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-16
@@ -4,21 +4,19 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
{
|
|
||||||
public class Artist
|
|
||||||
{
|
|
||||||
[JsonProperty("artist_id")]
|
|
||||||
public int ArtistID { get; set; }
|
|
||||||
[JsonProperty("name")]
|
|
||||||
[Column("Artist")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
[JsonProperty("song_count")]
|
|
||||||
[NotMapped]
|
|
||||||
public int SongCount { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
public class Artist
|
||||||
[NotMapped]
|
{
|
||||||
public List<Song> Songs { get; set; }
|
[JsonProperty("artist_id")]
|
||||||
}
|
public int ArtistID { get; set; }
|
||||||
|
[JsonProperty("name")]
|
||||||
|
[Column("Artist")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
[JsonProperty("song_count")]
|
||||||
|
[NotMapped]
|
||||||
|
public int SongCount { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
[NotMapped]
|
||||||
|
public List<Song> Songs { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ using System;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class BaseResult
|
||||||
{
|
{
|
||||||
public class BaseResult
|
[JsonProperty("message")]
|
||||||
{
|
public string Message { get; set; }
|
||||||
[JsonProperty("message")]
|
|
||||||
public string Message { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-30
@@ -6,38 +6,37 @@ using System.Text;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class CoverArt
|
||||||
{
|
{
|
||||||
public class CoverArt
|
#region Properties
|
||||||
|
[JsonProperty("cover_art_id")]
|
||||||
|
public int CoverArtID { get; set; }
|
||||||
|
[JsonProperty("title")]
|
||||||
|
public string SongTitle { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public string ImagePath { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
[NotMapped]
|
||||||
|
public int SongID { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
[NotMapped]
|
||||||
|
public List<Song> Songs { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public string GenerateFilename(int flag)
|
||||||
{
|
{
|
||||||
#region Properties
|
const int length = 25;
|
||||||
[JsonProperty("cover_art_id")]
|
const string chars = "ABCDEF0123456789";
|
||||||
public int CoverArtID { get; set; }
|
var random = new Random();
|
||||||
[JsonProperty("title")]
|
var filename = new string(Enumerable.Repeat(chars, length).Select(s =>
|
||||||
public string SongTitle { get; set; }
|
s[random.Next(s.Length)]).ToArray());
|
||||||
[JsonIgnore]
|
var extension = ".mp3";
|
||||||
public string ImagePath { get; set; }
|
|
||||||
[JsonIgnore]
|
|
||||||
[NotMapped]
|
|
||||||
public int SongID { get; set; }
|
|
||||||
[JsonIgnore]
|
|
||||||
[NotMapped]
|
|
||||||
public List<Song> Songs { get; set; }
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
return (flag == 0) ? filename : $"{filename}{extension}";
|
||||||
#region Methods
|
|
||||||
public string GenerateFilename(int flag)
|
|
||||||
{
|
|
||||||
const int length = 25;
|
|
||||||
const string chars = "ABCDEF0123456789";
|
|
||||||
var random = new Random();
|
|
||||||
var filename = new string(Enumerable.Repeat(chars, length).Select(s =>
|
|
||||||
s[random.Next(s.Length)]).ToArray());
|
|
||||||
var extension = ".mp3";
|
|
||||||
|
|
||||||
return (flag == 0) ? filename : $"{filename}{extension}";
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-15
@@ -4,20 +4,19 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class Genre
|
||||||
{
|
{
|
||||||
public class Genre
|
[JsonProperty("genre_id")]
|
||||||
{
|
public int GenreID { get; set; }
|
||||||
[JsonProperty("genre_id")]
|
[JsonProperty("genre")]
|
||||||
public int GenreID { get; set; }
|
[Column("Category")]
|
||||||
[JsonProperty("genre")]
|
public string GenreName { get; set; }
|
||||||
[Column("Category")]
|
[JsonProperty("song_count")]
|
||||||
public string GenreName { get; set; }
|
[NotMapped]
|
||||||
[JsonProperty("song_count")]
|
public int SongCount { get; set; }
|
||||||
[NotMapped]
|
[JsonIgnore]
|
||||||
public int SongCount { get; set; }
|
[NotMapped]
|
||||||
[JsonIgnore]
|
public List<Song> Songs { get; set; }
|
||||||
[NotMapped]
|
|
||||||
public List<Song> Songs { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-14
@@ -2,19 +2,18 @@ using System;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class LoginResult : BaseResult
|
||||||
{
|
{
|
||||||
public class LoginResult : BaseResult
|
[JsonProperty("user_id")]
|
||||||
{
|
public int UserID { get; set; }
|
||||||
[JsonProperty("user_id")]
|
[JsonProperty("username")]
|
||||||
public int UserID { get; set; }
|
public string Username { get; set; }
|
||||||
[JsonProperty("username")]
|
[JsonProperty("token")]
|
||||||
public string Username { get; set; }
|
public string Token { get; set; }
|
||||||
[JsonProperty("token")]
|
[JsonProperty("token_type")]
|
||||||
public string Token { get; set; }
|
public string TokenType { get; set; }
|
||||||
[JsonProperty("token_type")]
|
[JsonProperty("expiration")]
|
||||||
public string TokenType { get; set; }
|
public int Expiration { get; set; }
|
||||||
[JsonProperty("expiration")]
|
|
||||||
public int Expiration { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,12 @@ using System;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class RegisterResult : BaseResult
|
||||||
{
|
{
|
||||||
public class RegisterResult : BaseResult
|
[JsonProperty("username")]
|
||||||
{
|
public string Username { get; set; }
|
||||||
[JsonProperty("username")]
|
[JsonProperty("successfully_registered")]
|
||||||
public string Username { get; set; }
|
public bool SuccessfullyRegistered { get; set; }
|
||||||
[JsonProperty("successfully_registered")]
|
|
||||||
public bool SuccessfullyRegistered { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+85
-86
@@ -5,98 +5,97 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class Song
|
||||||
{
|
{
|
||||||
public class Song
|
#region Properties
|
||||||
|
[JsonProperty("song_id")]
|
||||||
|
public int SongID { get; set; }
|
||||||
|
[JsonProperty("title")]
|
||||||
|
public string Title { get; set; }
|
||||||
|
[JsonProperty("album")]
|
||||||
|
[Column("Album")]
|
||||||
|
public string AlbumTitle { get; set; }
|
||||||
|
[JsonProperty("artist")]
|
||||||
|
public string Artist { get; set; }
|
||||||
|
[JsonProperty("album_artist")]
|
||||||
|
public string AlbumArtist { get; set; }
|
||||||
|
[JsonProperty("year")]
|
||||||
|
public int? Year { get; set; }
|
||||||
|
[JsonProperty("genre")]
|
||||||
|
public string Genre { get; set; }
|
||||||
|
[JsonProperty("duration")]
|
||||||
|
public int Duration { get; set; }
|
||||||
|
[JsonProperty("filename")]
|
||||||
|
public string Filename { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public string SongDirectory { get; set; }
|
||||||
|
[JsonProperty("track")]
|
||||||
|
public int Track { get; set; } = 0;
|
||||||
|
[JsonProperty("track_count")]
|
||||||
|
public int TrackCount { get; set; } = 0;
|
||||||
|
[JsonProperty("disc")]
|
||||||
|
public int Disc { get; set; } = 0;
|
||||||
|
[JsonProperty("disc_count")]
|
||||||
|
public int DiscCount { get; set; } = 0;
|
||||||
|
[JsonIgnore]
|
||||||
|
public int? AlbumID { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public int? ArtistID { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public int? GenreID { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public int? CoverArtID { get; set; }
|
||||||
|
[JsonProperty("date_created")]
|
||||||
|
public DateTime DateCreated { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public string SongPath()
|
||||||
{
|
{
|
||||||
#region Properties
|
var fullPath = SongDirectory;
|
||||||
[JsonProperty("song_id")]
|
|
||||||
public int SongID { get; set; }
|
|
||||||
[JsonProperty("title")]
|
|
||||||
public string Title { get; set; }
|
|
||||||
[JsonProperty("album")]
|
|
||||||
[Column("Album")]
|
|
||||||
public string AlbumTitle { get; set; }
|
|
||||||
[JsonProperty("artist")]
|
|
||||||
public string Artist { get; set; }
|
|
||||||
[JsonProperty("album_artist")]
|
|
||||||
public string AlbumArtist { get; set; }
|
|
||||||
[JsonProperty("year")]
|
|
||||||
public int? Year { get; set; }
|
|
||||||
[JsonProperty("genre")]
|
|
||||||
public string Genre { get; set; }
|
|
||||||
[JsonProperty("duration")]
|
|
||||||
public int Duration { get; set; }
|
|
||||||
[JsonProperty("filename")]
|
|
||||||
public string Filename { get; set; }
|
|
||||||
[JsonIgnore]
|
|
||||||
public string SongDirectory { get; set; }
|
|
||||||
[JsonProperty("track")]
|
|
||||||
public int Track { get; set; } = 0;
|
|
||||||
[JsonProperty("track_count")]
|
|
||||||
public int TrackCount { get; set; } = 0;
|
|
||||||
[JsonProperty("disc")]
|
|
||||||
public int Disc { get; set; } = 0;
|
|
||||||
[JsonProperty("disc_count")]
|
|
||||||
public int DiscCount { get; set; } = 0;
|
|
||||||
[JsonIgnore]
|
|
||||||
public int? AlbumID { get; set; }
|
|
||||||
[JsonIgnore]
|
|
||||||
public int? ArtistID { get; set; }
|
|
||||||
[JsonIgnore]
|
|
||||||
public int? GenreID { get; set; }
|
|
||||||
[JsonIgnore]
|
|
||||||
public int? CoverArtID { get; set; }
|
|
||||||
[JsonProperty("date_created")]
|
|
||||||
public DateTime DateCreated { get; set; }
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
if (fullPath[fullPath.Length -1] != '/')
|
||||||
#region Constructors
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public string SongPath()
|
|
||||||
{
|
{
|
||||||
var fullPath = SongDirectory;
|
fullPath += "/";
|
||||||
|
|
||||||
if (fullPath[fullPath.Length -1] != '/')
|
|
||||||
{
|
|
||||||
fullPath += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
fullPath += Filename;
|
|
||||||
|
|
||||||
return fullPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateFilename(int flag = 0)
|
fullPath += Filename;
|
||||||
{
|
|
||||||
const int length = 25;
|
|
||||||
const string chars = "ABCDEF0123456789";
|
|
||||||
var random = new Random();
|
|
||||||
var filename = new string(Enumerable.Repeat(chars, length).Select(s =>
|
|
||||||
s[random.Next(s.Length)]).ToArray());
|
|
||||||
var extension = ".mp3";
|
|
||||||
|
|
||||||
return flag == 0 ? filename : $"{filename}{extension}";
|
return fullPath;
|
||||||
}
|
|
||||||
public async Task<string> GenerateFilenameAsync(int flag = 0)
|
|
||||||
{
|
|
||||||
const int length = 25;
|
|
||||||
const string chars = "ABCDEF0123456789";
|
|
||||||
var extension = ".mp3";
|
|
||||||
var random = new Random();
|
|
||||||
var filename = await Task.Run(() =>
|
|
||||||
{
|
|
||||||
return new string(Enumerable.Repeat(chars, length).Select(s =>
|
|
||||||
s[random.Next(s.Length)]).ToArray());
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
return flag == 0 ? filename : $"{filename}{extension}";
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GenerateFilename(int flag = 0)
|
||||||
|
{
|
||||||
|
const int length = 25;
|
||||||
|
const string chars = "ABCDEF0123456789";
|
||||||
|
var random = new Random();
|
||||||
|
var filename = new string(Enumerable.Repeat(chars, length).Select(s =>
|
||||||
|
s[random.Next(s.Length)]).ToArray());
|
||||||
|
var extension = ".mp3";
|
||||||
|
|
||||||
|
return flag == 0 ? filename : $"{filename}{extension}";
|
||||||
|
}
|
||||||
|
public async Task<string> GenerateFilenameAsync(int flag = 0)
|
||||||
|
{
|
||||||
|
const int length = 25;
|
||||||
|
const string chars = "ABCDEF0123456789";
|
||||||
|
var extension = ".mp3";
|
||||||
|
var random = new Random();
|
||||||
|
var filename = await Task.Run(() =>
|
||||||
|
{
|
||||||
|
return new string(Enumerable.Repeat(chars, length).Select(s =>
|
||||||
|
s[random.Next(s.Length)]).ToArray());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return flag == 0 ? filename : $"{filename}{extension}";
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-7
@@ -1,12 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class SongData
|
||||||
{
|
{
|
||||||
public class SongData
|
public int ID { get; set; }
|
||||||
{
|
public byte[] Data { get; set; }
|
||||||
public int ID { get; set; }
|
public int SongID { get; set; }
|
||||||
public byte[] Data { get; set; }
|
|
||||||
public int SongID { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,12 @@ using System;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class SongResult
|
||||||
{
|
{
|
||||||
public class SongResult
|
[JsonProperty("message")]
|
||||||
{
|
public string Message { get; set; }
|
||||||
[JsonProperty("message")]
|
[JsonProperty("song_title")]
|
||||||
public string Message { get; set; }
|
public string SongTitle { get; set; }
|
||||||
[JsonProperty("song_title")]
|
|
||||||
public string SongTitle { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-44
@@ -4,53 +4,52 @@ using System.Linq;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
public class Token
|
||||||
{
|
{
|
||||||
public class Token
|
#region Properties
|
||||||
|
[JsonProperty("scope")]
|
||||||
|
public string Scope { get; set; }
|
||||||
|
[JsonProperty("exp")]
|
||||||
|
public int Expiration { get; set; }
|
||||||
|
[JsonProperty("aud")]
|
||||||
|
public string Audience { get; set; }
|
||||||
|
[JsonProperty("iss")]
|
||||||
|
public string Issuer { get; set; }
|
||||||
|
[JsonProperty("iat")]
|
||||||
|
public int Issued { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public bool TokenExpired()
|
||||||
{
|
{
|
||||||
#region Properties
|
var result = false;
|
||||||
[JsonProperty("scope")]
|
var currentDate = DateTime.Now;
|
||||||
public string Scope { get; set; }
|
|
||||||
[JsonProperty("exp")]
|
|
||||||
public int Expiration { get; set; }
|
|
||||||
[JsonProperty("aud")]
|
|
||||||
public string Audience { get; set; }
|
|
||||||
[JsonProperty("iss")]
|
|
||||||
public string Issuer { get; set; }
|
|
||||||
[JsonProperty("iat")]
|
|
||||||
public int Issued { get; set; }
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public bool TokenExpired()
|
|
||||||
{
|
|
||||||
var result = false;
|
|
||||||
var currentDate = DateTime.Now;
|
|
||||||
|
|
||||||
var currentDateInSeconds = Math.Floor((currentDate - DateTime.UnixEpoch).TotalSeconds);
|
var currentDateInSeconds = Math.Floor((currentDate - DateTime.UnixEpoch).TotalSeconds);
|
||||||
|
|
||||||
result = (currentDateInSeconds >= Expiration) ? true : false;
|
result = (currentDateInSeconds >= Expiration) ? true : false;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
public bool ContainsScope(string desiredScope)
|
|
||||||
{
|
|
||||||
var result = false;
|
|
||||||
result = Scope.Contains(desiredScope);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Erroneous()
|
|
||||||
{
|
|
||||||
var result = true;
|
|
||||||
Func<string, bool> isEmpty = a => string.IsNullOrEmpty(a);
|
|
||||||
result = (!isEmpty(Scope) && !isEmpty(Audience) && !isEmpty(Issuer) &&
|
|
||||||
Expiration > 0 && Issued > 0) ? false : true;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public bool ContainsScope(string desiredScope)
|
||||||
|
{
|
||||||
|
var result = false;
|
||||||
|
result = Scope.Contains(desiredScope);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Erroneous()
|
||||||
|
{
|
||||||
|
var result = true;
|
||||||
|
Func<string, bool> isEmpty = a => string.IsNullOrEmpty(a);
|
||||||
|
result = (!isEmpty(Scope) && !isEmpty(Audience) && !isEmpty(Issuer) &&
|
||||||
|
Expiration > 0 && Issued > 0) ? false : true;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|||||||
+44
-45
@@ -5,53 +5,52 @@ using System.Linq;
|
|||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Icarus.Models
|
namespace Icarus.Models;
|
||||||
|
|
||||||
|
[Table("User")]
|
||||||
|
public class User
|
||||||
{
|
{
|
||||||
[Table("User")]
|
#region Properties
|
||||||
public class User
|
[JsonProperty("user_id")]
|
||||||
|
[Column("UserID")]
|
||||||
|
[Key]
|
||||||
|
public int UserID { get; set; }
|
||||||
|
[JsonProperty("username")]
|
||||||
|
public string Username { get; set; }
|
||||||
|
[JsonProperty("password")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
[JsonProperty("email")]
|
||||||
|
public string Email { get; set; }
|
||||||
|
[JsonProperty("phone")]
|
||||||
|
[Column("Phone")]
|
||||||
|
public string Phone { get; set; }
|
||||||
|
[JsonProperty("firstname")]
|
||||||
|
public string Firstname { get; set; }
|
||||||
|
[JsonProperty("lastname")]
|
||||||
|
public string Lastname { get; set; }
|
||||||
|
[JsonProperty("email_verified")]
|
||||||
|
[NotMapped]
|
||||||
|
public bool EmailVerified { get; set; }
|
||||||
|
[JsonProperty("date_created")]
|
||||||
|
public DateTime DateCreated { get; set; }
|
||||||
|
[JsonProperty("status")]
|
||||||
|
public string Status { get; set; }
|
||||||
|
[JsonProperty("last_login")]
|
||||||
|
public DateTime? LastLogin { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
[NotMapped]
|
||||||
|
public System.Collections.Generic.IEnumerable<string> Roles { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> Claims()
|
||||||
{
|
{
|
||||||
#region Properties
|
var claims = new System.Collections.Generic.List<System.Security.Claims.Claim> { new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name, Username) };
|
||||||
[JsonProperty("user_id")]
|
claims.AddRange(Roles.Select(role => new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Role, role)));
|
||||||
[Column("UserID")]
|
|
||||||
[Key]
|
|
||||||
public int UserID { get; set; }
|
|
||||||
[JsonProperty("username")]
|
|
||||||
public string Username { get; set; }
|
|
||||||
[JsonProperty("password")]
|
|
||||||
public string Password { get; set; }
|
|
||||||
[JsonProperty("email")]
|
|
||||||
public string Email { get; set; }
|
|
||||||
[JsonProperty("phone")]
|
|
||||||
[Column("Phone")]
|
|
||||||
public string Phone { get; set; }
|
|
||||||
[JsonProperty("firstname")]
|
|
||||||
public string Firstname { get; set; }
|
|
||||||
[JsonProperty("lastname")]
|
|
||||||
public string Lastname { get; set; }
|
|
||||||
[JsonProperty("email_verified")]
|
|
||||||
[NotMapped]
|
|
||||||
public bool EmailVerified { get; set; }
|
|
||||||
[JsonProperty("date_created")]
|
|
||||||
public DateTime DateCreated { get; set; }
|
|
||||||
[JsonProperty("status")]
|
|
||||||
public string Status { get; set; }
|
|
||||||
[JsonProperty("last_login")]
|
|
||||||
public DateTime? LastLogin { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
return claims;
|
||||||
[NotMapped]
|
|
||||||
public System.Collections.Generic.IEnumerable<string> Roles { get; set; }
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> Claims()
|
|
||||||
{
|
|
||||||
var claims = new System.Collections.Generic.List<System.Security.Claims.Claim> { new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name, Username) };
|
|
||||||
claims.AddRange(Roles.Select(role => new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Role, role)));
|
|
||||||
|
|
||||||
return claims;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-26
@@ -11,36 +11,35 @@ using Microsoft.Extensions.Hosting;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using NLog.Web;
|
using NLog.Web;
|
||||||
|
|
||||||
namespace Icarus
|
namespace Icarus;
|
||||||
|
|
||||||
|
public class Program
|
||||||
{
|
{
|
||||||
public class Program
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
logger.Debug("init main");
|
||||||
|
|
||||||
try
|
CreateHostBuilder(args).Build().Run();
|
||||||
{
|
}
|
||||||
logger.Debug("init main");
|
catch (Exception ex)
|
||||||
|
{
|
||||||
CreateHostBuilder(args).Build().Run();
|
logger.Error(ex, "An error occurred");
|
||||||
}
|
throw;
|
||||||
catch (Exception ex)
|
}
|
||||||
{
|
finally
|
||||||
logger.Error(ex, "An error occurred");
|
{
|
||||||
throw;
|
NLog.LogManager.Shutdown();
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
NLog.LogManager.Shutdown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
|
||||||
Host.CreateDefaultBuilder(args)
|
|
||||||
.ConfigureWebHostDefaults(webBuilder =>
|
|
||||||
{
|
|
||||||
webBuilder.UseStartup<Startup>();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+99
-101
@@ -20,108 +20,106 @@ using NLog.Web.AspNetCore;
|
|||||||
|
|
||||||
using Icarus.Database.Contexts;
|
using Icarus.Database.Contexts;
|
||||||
|
|
||||||
namespace Icarus
|
namespace Icarus;
|
||||||
|
public class Startup
|
||||||
{
|
{
|
||||||
public class Startup
|
#region Constructors
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
{
|
{
|
||||||
#region Constructors
|
Configuration = configuration;
|
||||||
public Startup(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
Configuration = configuration;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
public IConfiguration Configuration { get; }
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddControllers();
|
|
||||||
|
|
||||||
var auth_id = Configuration["Auth0:Domain"];
|
|
||||||
var domain = $"https://{auth_id}/";
|
|
||||||
var audience = Configuration["Auth0:ApiIdentifier"];
|
|
||||||
|
|
||||||
var connString = Configuration.GetConnectionString("DefaultConnection");
|
|
||||||
|
|
||||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
|
|
||||||
{
|
|
||||||
options.RequireHttpsMetadata = false;
|
|
||||||
options.SaveToken = true;
|
|
||||||
options.TokenValidationParameters = new TokenValidationParameters()
|
|
||||||
{
|
|
||||||
ValidateIssuer = true,
|
|
||||||
ValidateAudience = true,
|
|
||||||
ValidAudience = Configuration["JWT:Audience"],
|
|
||||||
ValidIssuer = Configuration["JWT:Issuer"],
|
|
||||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]))
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
services.AddDbContext<SongContext>(options => options.UseMySQL(connString));
|
|
||||||
services.AddDbContext<AlbumContext>(options => options.UseMySQL(connString));
|
|
||||||
services.AddDbContext<ArtistContext>(options => options.UseMySQL(connString));
|
|
||||||
services.AddDbContext<UserContext>(options => options.UseMySQL(connString));
|
|
||||||
services.AddDbContext<GenreContext>(options => options.UseMySQL(connString));
|
|
||||||
services.AddDbContext<CoverArtContext>(options => options.UseMySQL(connString));
|
|
||||||
|
|
||||||
services.AddControllers()
|
|
||||||
.AddNewtonsoftJson();
|
|
||||||
|
|
||||||
services.AddEndpointsApiExplorer();
|
|
||||||
services.AddSwaggerGen(c =>
|
|
||||||
{
|
|
||||||
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
|
|
||||||
|
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Icarus", Version = "v1" });
|
|
||||||
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
|
|
||||||
{
|
|
||||||
Name = "Authorization",
|
|
||||||
Scheme = "Bearer",
|
|
||||||
BearerFormat = "JWT",
|
|
||||||
Type = SecuritySchemeType.ApiKey,
|
|
||||||
In = ParameterLocation.Header,
|
|
||||||
Description = "Bearer *Auth Token*",
|
|
||||||
});
|
|
||||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
|
||||||
{
|
|
||||||
{
|
|
||||||
new OpenApiSecurityScheme
|
|
||||||
{
|
|
||||||
Reference = new OpenApiReference
|
|
||||||
{
|
|
||||||
Type = ReferenceType.SecurityScheme,
|
|
||||||
Id = "Bearer"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new string[] {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called by the runtime. Use this method to configure the HTTP request pipeline.
|
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
|
||||||
{
|
|
||||||
// NOTE: Dev-related configuration can be done when env.IsDevelopment() evaluated to true
|
|
||||||
if (env.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseSwagger();
|
|
||||||
app.UseSwaggerUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseRouting();
|
|
||||||
app.UseAuthentication();
|
|
||||||
app.UseAuthorization();
|
|
||||||
app.UseEndpoints(endpoints =>
|
|
||||||
{
|
|
||||||
endpoints.MapControllers();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public IConfiguration Configuration { get; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddControllers();
|
||||||
|
|
||||||
|
var auth_id = Configuration["Auth0:Domain"];
|
||||||
|
var domain = $"https://{auth_id}/";
|
||||||
|
var audience = Configuration["Auth0:ApiIdentifier"];
|
||||||
|
|
||||||
|
var connString = Configuration.GetConnectionString("DefaultConnection");
|
||||||
|
|
||||||
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
|
||||||
|
{
|
||||||
|
options.RequireHttpsMetadata = false;
|
||||||
|
options.SaveToken = true;
|
||||||
|
options.TokenValidationParameters = new TokenValidationParameters()
|
||||||
|
{
|
||||||
|
ValidateIssuer = true,
|
||||||
|
ValidateAudience = true,
|
||||||
|
ValidAudience = Configuration["JWT:Audience"],
|
||||||
|
ValidIssuer = Configuration["JWT:Issuer"],
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]))
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
services.AddDbContext<SongContext>(options => options.UseMySQL(connString));
|
||||||
|
services.AddDbContext<AlbumContext>(options => options.UseMySQL(connString));
|
||||||
|
services.AddDbContext<ArtistContext>(options => options.UseMySQL(connString));
|
||||||
|
services.AddDbContext<UserContext>(options => options.UseMySQL(connString));
|
||||||
|
services.AddDbContext<GenreContext>(options => options.UseMySQL(connString));
|
||||||
|
services.AddDbContext<CoverArtContext>(options => options.UseMySQL(connString));
|
||||||
|
|
||||||
|
services.AddControllers()
|
||||||
|
.AddNewtonsoftJson();
|
||||||
|
|
||||||
|
services.AddEndpointsApiExplorer();
|
||||||
|
services.AddSwaggerGen(c =>
|
||||||
|
{
|
||||||
|
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
|
||||||
|
|
||||||
|
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Icarus", Version = "v1" });
|
||||||
|
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
|
||||||
|
{
|
||||||
|
Name = "Authorization",
|
||||||
|
Scheme = "Bearer",
|
||||||
|
BearerFormat = "JWT",
|
||||||
|
Type = SecuritySchemeType.ApiKey,
|
||||||
|
In = ParameterLocation.Header,
|
||||||
|
Description = "Bearer *Auth Token*",
|
||||||
|
});
|
||||||
|
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Reference = new OpenApiReference
|
||||||
|
{
|
||||||
|
Type = ReferenceType.SecurityScheme,
|
||||||
|
Id = "Bearer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new string[] {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
// NOTE: Dev-related configuration can be done when env.IsDevelopment() evaluated to true
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.UseAuthorization();
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Icarus.Types
|
namespace Icarus.Types;
|
||||||
|
|
||||||
|
public enum CoverArtField
|
||||||
{
|
{
|
||||||
public enum CoverArtField
|
SongTitle = 0,
|
||||||
{
|
ImagePath
|
||||||
SongTitle = 0,
|
};
|
||||||
ImagePath
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Icarus.Types
|
namespace Icarus.Types;
|
||||||
|
|
||||||
|
public enum DirectoryType
|
||||||
{
|
{
|
||||||
public enum DirectoryType
|
Music = 0,
|
||||||
{
|
CoverArt
|
||||||
Music = 0,
|
};
|
||||||
CoverArt
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user