#103: Remove WAV support #105

Merged
kdeng00 merged 12 commits from tsk-103 into master 2025-02-16 17:24:50 -05:00
33 changed files with 242 additions and 99 deletions
+4
View File
@@ -18,3 +18,7 @@ Icarus/bin
Icarus/obj Icarus/obj
Models/bin Models/bin
Models/obj Models/obj
Migrations
Icarus.txt
Storage
.DS_Store
+1 -1
View File
@@ -85,7 +85,7 @@ public class AlbumManager : BaseManager
if (string.IsNullOrEmpty(newAlbumTitle)) if (string.IsNullOrEmpty(newAlbumTitle))
newAlbumTitle = oldAlbumTitle; newAlbumTitle = oldAlbumTitle;
if ((string.IsNullOrEmpty(newAlbumTitle) && string.IsNullOrEmpty(newAlbumArtist) || if ((string.IsNullOrEmpty(newAlbumTitle) && string.IsNullOrEmpty(newAlbumArtist) ||
oldAlbumTitle!.Equals(newAlbumTitle) && oldAlbumArtist!.Equals(newAlbumArtist))) oldAlbumTitle!.Equals(newAlbumTitle) && oldAlbumArtist!.Equals(newAlbumArtist)))
{ {
_logger.Info("No change to the song's album"); _logger.Info("No change to the song's album");
+1 -1
View File
@@ -84,7 +84,7 @@ public class ArtistManager : BaseManager
_artistContext.Add(newArtistRecord); _artistContext.Add(newArtistRecord);
_artistContext.SaveChanges(); _artistContext.SaveChanges();
return newArtistRecord; return newArtistRecord;
} }
else else
@@ -48,7 +48,7 @@ public class CoverArtManager : BaseManager
try try
{ {
var stockCoverArtPath = _rootCoverArtPath + _filename; var stockCoverArtPath = _rootCoverArtPath + _filename;
if (!string.Equals(stockCoverArtPath, coverArt.ImagePath(), if (!string.Equals(stockCoverArtPath, coverArt.ImagePath(),
StringComparison.CurrentCultureIgnoreCase)) StringComparison.CurrentCultureIgnoreCase))
{ {
_logger.Info("Song does not contain the stock cover art"); _logger.Info("Song does not contain the stock cover art");
@@ -87,7 +87,7 @@ public class CoverArtManager : BaseManager
var metaData = new MetadataRetriever(); var metaData = new MetadataRetriever();
var imgBytes = metaData.RetrieveCoverArtBytes(song); var imgBytes = metaData.RetrieveCoverArtBytes(song);
if (imgBytes != null) if (imgBytes != null)
{ {
_logger.Info("Saving cover art to the filesystem"); _logger.Info("Saving cover art to the filesystem");
@@ -121,7 +121,7 @@ public class CoverArtManager : BaseManager
var msg = ex.Message; var msg = ex.Message;
_logger.Error(msg, "An error occurred"); _logger.Error(msg, "An error occurred");
} }
return null; return null;
} }
@@ -173,7 +173,7 @@ public class CoverArtManager : BaseManager
if (!File.Exists(_rootCoverArtPath + _filename)) if (!File.Exists(_rootCoverArtPath + _filename))
{ {
File.WriteAllBytes(_rootCoverArtPath + _filename, File.WriteAllBytes(_rootCoverArtPath + _filename,
_stockCoverArt!); _stockCoverArt!);
Console.WriteLine("Copied Stock Cover Art"); Console.WriteLine("Copied Stock Cover Art");
} }
@@ -53,7 +53,7 @@ public class DirectoryManager : BaseManager
public static string GenerateDownloadFilename(int length, string extension, string title, bool? randomize) public static string GenerateDownloadFilename(int length, string extension, string title, bool? randomize)
{ {
if (randomize.HasValue && randomize.Value) if (randomize.HasValue && randomize.Value)
{ {
return GenerateFilename(length) + extension; return GenerateFilename(length) + extension;
} }
@@ -100,13 +100,13 @@ public class DirectoryManager : BaseManager
var artistDirectory = ArtistDirectory(); var artistDirectory = ArtistDirectory();
if (IsDirectoryEmpty(albumDirectory)) if (IsDirectoryEmpty(albumDirectory))
{ {
Directory.Delete(albumDirectory); Directory.Delete(albumDirectory);
Console.WriteLine($"directory {albumDirectory} deleted"); Console.WriteLine($"directory {albumDirectory} deleted");
} }
if (IsDirectoryEmpty(artistDirectory)) if (IsDirectoryEmpty(artistDirectory))
{ {
Directory.Delete(artistDirectory); Directory.Delete(artistDirectory);
Console.WriteLine($"directory {artistDirectory} deleted"); Console.WriteLine($"directory {artistDirectory} deleted");
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -116,6 +116,38 @@ public class DirectoryManager : BaseManager
} }
} }
public int DeleteEmptyDirectories(string? directory, int level)
{
var deleted = 0;
try
{
var curDir = directory;
for (var i = 0; i < level; i++)
{
if (!System.IO.Directory.Exists(curDir))
{
continue;
}
if (this.IsDirectoryEmpty(curDir))
{
System.IO.Directory.Delete(curDir);
deleted++;
}
curDir = System.IO.Directory.GetParent(curDir).ToString();
}
}
catch (Exception ex)
{
var exMsg = ex.Message;
Console.WriteLine($"An error occurred {exMsg}");
}
return deleted;
}
public void DeleteEmptyDirectories(Song song) public void DeleteEmptyDirectories(Song song)
{ {
try try
@@ -125,12 +157,12 @@ public class DirectoryManager : BaseManager
if (IsDirectoryEmpty(albumDirectory)) if (IsDirectoryEmpty(albumDirectory))
{ {
Directory.Delete(albumDirectory); Directory.Delete(albumDirectory);
_logger.Info("Album directory deleted"); _logger.Info("Album directory deleted");
} }
if (IsDirectoryEmpty(artistDirectory)) if (IsDirectoryEmpty(artistDirectory))
{ {
Directory.Delete(artistDirectory); Directory.Delete(artistDirectory);
_logger.Info("Artist directory deleted"); _logger.Info("Artist directory deleted");
} }
} }
@@ -187,7 +219,7 @@ public class DirectoryManager : BaseManager
private class DirEnt private class DirEnt
{ {
public string? Pre { get; set;} public string? Pre { get; set; }
public string? Path { get; set; } public string? Path { get; set; }
public string? Post { get; set; } public string? Post { get; set; }
} }
+49 -17
View File
@@ -3,9 +3,11 @@ using NLog;
using Icarus.Controllers.Utilities; using Icarus.Controllers.Utilities;
using Icarus.Models; using Icarus.Models;
using Icarus.Database.Contexts; using Icarus.Database.Contexts;
using TagLib.Mpeg4;
namespace Icarus.Controllers.Managers; namespace Icarus.Controllers.Managers;
public class SongManager : BaseManager public class SongManager : BaseManager
{ {
#region Fields #region Fields
@@ -107,11 +109,18 @@ public class SongManager : BaseManager
try try
{ {
var songPath = songMetaData.SongPath(); var songPath = songMetaData.SongPath();
File.Delete(songPath); System.IO.File.Delete(songPath);
successful = true; successful = !System.IO.File.Exists(songPath);
if (successful)
{
Console.WriteLine("Song successfully deleted");
}
DirectoryManager dirMgr = new DirectoryManager(_config!, songMetaData); DirectoryManager dirMgr = new DirectoryManager(_config!, songMetaData);
dirMgr.DeleteEmptyDirectories(); var deletedAmount = dirMgr.DeleteEmptyDirectories(songMetaData.SongDirectory, 1);
Console.WriteLine("Song successfully deleted"); if (deletedAmount > 0)
{
Console.WriteLine($"{deletedAmount} directories deleted");
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -196,6 +205,7 @@ public class SongManager : BaseManager
} }
// Change the name of this method to only focus on wav files // Change the name of this method to only focus on wav files
[Obsolete("Support for uplodaing wav files will end. Use the flac alternative instead - SaveFlacSongToFileSystem(..)")]
public Song SaveSongToFileSystem(IFormFile songFile, IFormFile coverArtData, Song song) public Song SaveSongToFileSystem(IFormFile songFile, IFormFile coverArtData, Song song)
{ {
if (string.IsNullOrEmpty(song.SongDirectory)) if (string.IsNullOrEmpty(song.SongDirectory))
@@ -252,8 +262,8 @@ public class SongManager : BaseManager
return song; return song;
} }
public Song SaveFlacSongToFileSystem(IFormFile songFile, IFormFile coverArtData, Song song) public Song SaveFlacSongToFileSystem(IFormFile songFile, IFormFile coverArtData, Song song)
{ {
// Save temp song (Should already be saved to the filesystem by the time it gets to this method) // Save temp song (Should already be saved to the filesystem by the time it gets to this method)
// Save cover art // Save cover art
// Update the song's metadata with the song object // Update the song's metadata with the song object
@@ -283,10 +293,10 @@ public class SongManager : BaseManager
SaveSongToDatabase(song, coverArt); SaveSongToDatabase(song, coverArt);
return song; return song;
} }
private void MoveSongToFinalDestination(string sourcePath, string targetPath) private void MoveSongToFinalDestination(string sourcePath, string targetPath)
{ {
using (var fileStream = new FileStream(targetPath, FileMode.Create)) using (var fileStream = new FileStream(targetPath, FileMode.Create))
{ {
var songBytes = System.IO.File.ReadAllBytes(sourcePath); var songBytes = System.IO.File.ReadAllBytes(sourcePath);
@@ -315,8 +325,8 @@ public class SongManager : BaseManager
_logger.Info("Song successfully saved to filesystem"); _logger.Info("Song successfully saved to filesystem");
} }
} }
public async Task<SongData> RetrieveSong(Song songMetaData) public async Task<SongData> RetrieveSong(Song songMetaData)
{ {
var song = new SongData(); var song = new SongData();
@@ -340,7 +350,7 @@ public class SongManager : BaseManager
private async Task<SongData> RetrieveSongFromFileSystem(Song details) private async Task<SongData> RetrieveSongFromFileSystem(Song details)
{ {
byte[] uncompressedSong = await System.IO.File.ReadAllBytesAsync(details.SongPath()); byte[] uncompressedSong = await System.IO.File.ReadAllBytesAsync(details.SongPath());
return new SongData return new SongData
{ {
Data = uncompressedSong Data = uncompressedSong
@@ -366,6 +376,28 @@ public class SongManager : BaseManager
} }
public Icarus.Models.CreateFileResult Create(IFormFile file, string filePath, string prompt)
{
if (System.IO.File.Exists(filePath))
{
return CreateFileResult.AlreadyExists;
}
using (var filestream = new FileStream(filePath, FileMode.Create))
{
Console.WriteLine(prompt);
file.CopyTo(filestream);
if (System.IO.File.Exists(filePath))
{
return CreateFileResult.FileCreatedAndExists;
}
}
return 0;
}
private bool SongRecordChanged(Song currentSong, Song songUpdates) private bool SongRecordChanged(Song currentSong, Song songUpdates)
{ {
var currentTitle = currentSong.Title; var currentTitle = currentSong.Title;
@@ -402,9 +434,9 @@ public class SongManager : BaseManager
Console.WriteLine($"Error Occurred: {ex.Message}"); Console.WriteLine($"Error Occurred: {ex.Message}");
} }
} }
private void SaveSongToDatabase(Song song, CoverArt? cover) private void SaveSongToDatabase(Song song, CoverArt? cover)
{ {
_logger.Info("Starting process to save the song to the database"); _logger.Info("Starting process to save the song to the database");
@@ -425,7 +457,7 @@ public class SongManager : BaseManager
coverMgr.SaveCoverArtToDatabase(ref song, ref cover!); coverMgr.SaveCoverArtToDatabase(ref song, ref cover!);
} }
private bool DeleteSongFromFilesystem(Song song, bool deleteDirectory = false) private bool DeleteSongFromFilesystem(Song song, bool deleteDirectory = false)
{ {
@@ -439,7 +471,7 @@ public class SongManager : BaseManager
DeleteEmptyDirectories(ref song, ref song); DeleteEmptyDirectories(ref song, ref song);
} }
catch(Exception ex) catch (Exception ex)
{ {
var msg = ex.Message; var msg = ex.Message;
_logger.Error(msg, "An error occurred when attempting to delete the song from the filesystem"); _logger.Error(msg, "An error occurred when attempting to delete the song from the filesystem");
@@ -463,7 +495,7 @@ public class SongManager : BaseManager
return true; return true;
} }
private void UpdateSongInDatabase(ref Song oldSongRecord, ref Song newSongRecord, ref SongResult result) private void UpdateSongInDatabase(ref Song oldSongRecord, ref Song newSongRecord, ref SongResult result)
{ {
var updatedSongRecord = oldSongRecord; var updatedSongRecord = oldSongRecord;
+19 -14
View File
@@ -53,7 +53,7 @@ public class TokenManager : BaseManager
_logger.Info("Serializing token object into JSON"); _logger.Info("Serializing token object into JSON");
var tokenObject = JsonConvert.SerializeObject(tokenRequest); var tokenObject = JsonConvert.SerializeObject(tokenRequest);
request.AddParameter("application/json; charset=utf-8", request.AddParameter("application/json; charset=utf-8",
tokenObject, ParameterType.RequestBody); tokenObject, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json; request.RequestFormat = DataFormat.Json;
@@ -74,7 +74,7 @@ public class TokenManager : BaseManager
public LoginResult LoginSymmetric(User user) public LoginResult LoginSymmetric(User user)
{ {
var tokenResult = new TokenTierOne{ TokenType = "JWT" }; var tokenResult = new TokenTierOne { TokenType = "JWT" };
var payload = Payload(); var payload = Payload();
payload.Add(new Claim("user_id", user.Id.ToString(), ClaimValueTypes.Integer)); payload.Add(new Claim("user_id", user.Id.ToString(), ClaimValueTypes.Integer));
@@ -91,7 +91,7 @@ public class TokenManager : BaseManager
Expires = DateTime.UtcNow.AddHours(1), Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
Issuer = _config["Jwt:Issuer"], // Add this line Issuer = _config["Jwt:Issuer"], // Add this line
Audience = _config["Jwt:Audience"] Audience = _config["Jwt:Audience"]
}; };
tokenResult.AccessToken = tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDescriptor)); tokenResult.AccessToken = tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDescriptor));
@@ -112,8 +112,11 @@ public class TokenManager : BaseManager
{ {
return new LoginResult return new LoginResult
{ {
UserId = user.Id, Username = user.Username, Token = token.AccessToken, UserId = user.Id,
TokenType = token.TokenType, Expiration = token.Expiration, Username = user.Username,
Token = token.AccessToken,
TokenType = token.TokenType,
Expiration = token.Expiration,
Message = SUCCESSFUL_TOKEN_MESSAGE Message = SUCCESSFUL_TOKEN_MESSAGE
}; };
} }
@@ -162,13 +165,13 @@ public class TokenManager : BaseManager
"download:songs", "download:songs",
"read:song_details", "read:song_details",
"upload:songs", "upload:songs",
"delete:songs", "delete:songs",
"read:albums", "read:albums",
"read:artists", "read:artists",
"update:songs", "update:songs",
"stream:songs", "stream:songs",
"read:genre", "read:genre",
"read:year", "read:year",
"download:cover_art" "download:cover_art"
}; };
@@ -217,15 +220,17 @@ public class TokenManager : BaseManager
{ {
return await System.IO.File.ReadAllTextAsync(filepath); return await System.IO.File.ReadAllTextAsync(filepath);
} }
private TokenRequest RetrieveTokenRequest() private TokenRequest RetrieveTokenRequest()
{ {
_logger.Info("Retrieving token object"); _logger.Info("Retrieving token object");
return new TokenRequest return new TokenRequest
{ {
ClientId = _clientId, ClientSecret = _clientSecret, ClientId = _clientId,
Audience = _audience, GrantType = _grantType ClientSecret = _clientSecret,
Audience = _audience,
GrantType = _grantType
}; };
} }
@@ -9,8 +9,8 @@ public class MetadataRetriever
{ {
#region Fields #region Fields
private static NLog.Logger? _logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); private static NLog.Logger? _logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
private List<string>? _supportedAudioFileTypes = new List<string> {"wav", "flac"}; private List<string>? _supportedAudioFileTypes = new List<string> { "wav", "flac" };
private List<string>? _supportedImageFileTypes = new List<string> {"jpeg", "jpg", "png"}; private List<string>? _supportedImageFileTypes = new List<string> { "jpeg", "jpg", "png" };
private Song? _updatedSong; private Song? _updatedSong;
private string? _message; private string? _message;
private string? _title; private string? _title;
@@ -99,7 +99,7 @@ public class MetadataRetriever
public bool IsSupportedFile(IFormFile file) public bool IsSupportedFile(IFormFile file)
{ {
var supportedTypes = this._supportedAudioFileTypes; var supportedTypes = this._supportedAudioFileTypes;
this._supportedImageFileTypes!.ForEach(t => this._supportedImageFileTypes!.ForEach(t =>
{ {
if (!supportedTypes!.Contains(t)) if (!supportedTypes!.Contains(t))
{ {
@@ -115,7 +115,7 @@ public class MetadataRetriever
public bool IsSupportedFile(string path) public bool IsSupportedFile(string path)
{ {
var supportedTypes = this._supportedAudioFileTypes; var supportedTypes = this._supportedAudioFileTypes;
this._supportedImageFileTypes!.ForEach(t => this._supportedImageFileTypes!.ForEach(t =>
{ {
if (!supportedTypes!.Contains(t)) if (!supportedTypes!.Contains(t))
{ {
@@ -199,7 +199,7 @@ public class MetadataRetriever
return []; return [];
} }
public void UpdateMetadata(Song updatedSong, Song oldSong) public void UpdateMetadata(Song updatedSong, Song oldSong)
{ {
try try
@@ -267,7 +267,7 @@ public class MetadataRetriever
break; break;
case "artists": case "artists":
_updatedSong!.Artist = artist; _updatedSong!.Artist = artist;
fileTag.Tag.Performers = new []{artist}; fileTag.Tag.Performers = new[] { artist };
break; break;
case "album": case "album":
_updatedSong!.AlbumTitle = album; _updatedSong!.AlbumTitle = album;
@@ -275,7 +275,7 @@ public class MetadataRetriever
break; break;
case "genre": case "genre":
_updatedSong!.Genre = genre; _updatedSong!.Genre = genre;
fileTag.Tag.Genres = new []{genre}; fileTag.Tag.Genres = new[] { genre };
break; break;
case "year": case "year":
_updatedSong!.Year = year; _updatedSong!.Year = year;
@@ -283,7 +283,7 @@ public class MetadataRetriever
break; break;
case "albumartist": case "albumartist":
_updatedSong!.AlbumArtist = albumArtist; _updatedSong!.AlbumArtist = albumArtist;
fileTag.Tag.AlbumArtists = new []{albumArtist}; fileTag.Tag.AlbumArtists = new[] { albumArtist };
break; break;
case "track": case "track":
_updatedSong!.Track = track; _updatedSong!.Track = track;
@@ -352,7 +352,7 @@ public class MetadataRetriever
} }
return songValues; return songValues;
} }
private bool CheckIntField(int? value) private bool CheckIntField(int? value)
{ {
@@ -70,14 +70,14 @@ public class PasswordEncryption
password: password, salt: salt, password: password, salt: salt,
prf: KeyDerivationPrf.HMACSHA1, prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000, iterationCount: 10000,
numBytesRequested: 256/8)); numBytesRequested: 256 / 8));
return hashed; return hashed;
} }
byte[] GenerateSalt() byte[] GenerateSalt()
{ {
byte[] salt = new byte[128/8]; byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create()) using (var rng = RandomNumberGenerator.Create())
rng.GetBytes(salt); rng.GetBytes(salt);
@@ -43,10 +43,10 @@ public class SongCompression
{ {
var archivePath = RetrieveCompressesSongPath(song); var archivePath = RetrieveCompressesSongPath(song);
Console.WriteLine($"Compressed song saved to: {archivePath}"); Console.WriteLine($"Compressed song saved to: {archivePath}");
songData.Data = await System.IO.File.ReadAllBytesAsync(archivePath); songData.Data = await System.IO.File.ReadAllBytesAsync(archivePath);
} }
catch(Exception ex) catch (Exception ex)
{ {
var exMsg = ex.Message; var exMsg = ex.Message;
Console.WriteLine($"An error ocurred: \n{exMsg}"); Console.WriteLine($"An error ocurred: \n{exMsg}");
+1 -1
View File
@@ -48,7 +48,7 @@ public class AlbumController : BaseController
[HttpGet("{id}")] [HttpGet("{id}")]
public IActionResult GetAlbum(int id) public IActionResult GetAlbum(int id)
{ {
Album album = new Album{ Id = id }; Album album = new Album { Id = id };
var albumContext = new AlbumContext(_connectionString!); var albumContext = new AlbumContext(_connectionString!);
+1 -1
View File
@@ -49,7 +49,7 @@ public class ArtistController : BaseController
public IActionResult GetArtist(int id) public IActionResult GetArtist(int id)
{ {
Artist artist = new Artist { Id = id }; Artist artist = new Artist { Id = id };
var artistContext = new ArtistContext(_connectionString!); var artistContext = new ArtistContext(_connectionString!);
if (artistContext.DoesRecordExist(artist)) if (artistContext.DoesRecordExist(artist))
+2 -2
View File
@@ -20,7 +20,7 @@ public class BaseController : ControllerBase
const string otherTokenType = "Jwt"; const string otherTokenType = "Jwt";
var req = Request; var req = Request;
var auth = req.Headers.Authorization; var auth = req.Headers.Authorization;
var val = auth.ToString(); var val = auth.ToString();
if ((val.Contains(tokenType) || val.Contains(otherTokenType)) && val.Split(" ").Count() > 1) if ((val.Contains(tokenType) || val.Contains(otherTokenType)) && val.Split(" ").Count() > 1)
@@ -31,7 +31,7 @@ public class BaseController : ControllerBase
return token; return token;
} }
#endregion #endregion
} }
+4 -4
View File
@@ -63,7 +63,7 @@ public class CoverArtController : BaseController
var coverArtBytes = System.IO.File.ReadAllBytes( var coverArtBytes = System.IO.File.ReadAllBytes(
coverArt.ImagePath()); coverArt.ImagePath());
return File(coverArtBytes, "application/x-msdownload", return File(coverArtBytes, "application/x-msdownload",
coverArt.SongTitle); coverArt.SongTitle);
} }
else else
@@ -78,14 +78,14 @@ public class CoverArtController : BaseController
{ {
var songContext = new SongContext(_connectionString!); var songContext = new SongContext(_connectionString!);
var covMgr = new CoverArtManager(this._config!); var covMgr = new CoverArtManager(this._config!);
var songMetaData = songContext.RetrieveRecord(new Song { Id = id}); var songMetaData = songContext.RetrieveRecord(new Song { Id = id });
var c = covMgr.GetCoverArt(songMetaData); var c = covMgr.GetCoverArt(songMetaData);
var filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.JPG_EXTENSION, songMetaData.Title!, randomizeFilename); var filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.JPG_EXTENSION, songMetaData.Title!, randomizeFilename);
var data = await c.GetData(); var data = await c.GetData();
return File(data, "application/x-msdownload", filename); return File(data, "application/x-msdownload", filename);
} }
#endregion #endregion
+1 -1
View File
@@ -58,7 +58,7 @@ public class GenreController : BaseController
if (genreStore.DoesRecordExist(genre)) if (genreStore.DoesRecordExist(genre))
{ {
genre = genreStore.RetrieveRecord(genre); genre = genreStore.RetrieveRecord(genre);
return Ok(genre); return Ok(genre);
} }
+1 -1
View File
@@ -44,7 +44,7 @@ public class LoginController : ControllerBase
var context = new UserContext(_connectionString!); var context = new UserContext(_connectionString!);
_logger.LogInformation("Starting process of validating credentials"); _logger.LogInformation("Starting process of validating credentials");
var message = "Invalid credentials"; var message = "Invalid credentials";
var password = user.Password; var password = user.Password;
@@ -42,11 +42,11 @@ public class SongCompressedDataController : BaseController
var context = new SongContext(_connectionString!); var context = new SongContext(_connectionString!);
SongCompression cmp = new SongCompression(_archiveDir!); SongCompression cmp = new SongCompression(_archiveDir!);
Console.WriteLine($"Archive directory root: {_archiveDir}"); Console.WriteLine($"Archive directory root: {_archiveDir}");
Console.WriteLine("Starting process of retrieving comrpessed song"); Console.WriteLine("Starting process of retrieving comrpessed song");
var sng = context.RetrieveRecord(new Song{ Id = id }); var sng = context.RetrieveRecord(new Song { Id = id });
SongData song = await cmp.RetrieveCompressedSong(sng); SongData song = await cmp.RetrieveCompressedSong(sng);
var filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.ZIP_EXTENSION, sng.Title!, randomizeFilename); var filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.ZIP_EXTENSION, sng.Title!, randomizeFilename);
+3 -3
View File
@@ -41,7 +41,7 @@ public class SongController : BaseController
{ {
Console.WriteLine("Attemtping to retrieve songs"); Console.WriteLine("Attemtping to retrieve songs");
_logger!.LogInformation("Attempting to retrieve songs"); _logger!.LogInformation("Attempting to retrieve songs");
var context = new SongContext(_connectionString!); var context = new SongContext(_connectionString!);
var songs = context.Songs!.ToList(); var songs = context.Songs!.ToList();
@@ -60,8 +60,8 @@ public class SongController : BaseController
public IActionResult GetSong(int id) public IActionResult GetSong(int id)
{ {
var context = new SongContext(_connectionString!); var context = new SongContext(_connectionString!);
var song = context.RetrieveRecord(new Song{ Id = id }); var song = context.RetrieveRecord(new Song { Id = id });
Console.WriteLine("Here"); Console.WriteLine("Here");
+27 -8
View File
@@ -7,6 +7,8 @@ using Icarus.Database.Contexts;
namespace Icarus.Controllers.V1; namespace Icarus.Controllers.V1;
[Route("api/v1/song/data")] [Route("api/v1/song/data")]
[ApiController] [ApiController]
[Authorize] [Authorize]
@@ -40,23 +42,23 @@ public class SongDataController : BaseController
public IActionResult Download(int id, [FromQuery] bool? randomizeFilename) public IActionResult Download(int id, [FromQuery] bool? randomizeFilename)
{ {
var songContext = new SongContext(_connectionString!); var songContext = new SongContext(_connectionString!);
var songMetaData = songContext.RetrieveRecord(new Song { Id = id}); var songMetaData = songContext.RetrieveRecord(new Song { Id = id });
var song = _songMgr!.RetrieveSong(songMetaData).Result; var song = _songMgr!.RetrieveSong(songMetaData).Result;
string filename; string filename;
switch (songMetaData.AudioType) switch (songMetaData.AudioType)
{ {
case "wav": case "wav":
filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.WAV_EXTENSION, filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.WAV_EXTENSION,
songMetaData.Title!, randomizeFilename); songMetaData.Title!, randomizeFilename);
break; break;
case "flac": case "flac":
filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.FLAC_EXTENSION, filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.FLAC_EXTENSION,
songMetaData.Title!, randomizeFilename); songMetaData.Title!, randomizeFilename);
break; break;
default: default:
filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.DEFAULT_AUDIO_EXTENSION, filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.DEFAULT_AUDIO_EXTENSION,
songMetaData.Title!, randomizeFilename); songMetaData.Title!, randomizeFilename);
break; break;
} }
@@ -151,8 +153,13 @@ public class SongDataController : BaseController
switch (song.AudioType) switch (song.AudioType)
{ {
case "wav": case "wav":
song = _songMgr.SaveSongToFileSystem(up.SongData, up.CoverArtData, song); var _ = _songMgr.DeleteSongFromFileSystem(tmpSong);
break; return BadRequest(new UploadSongWithDataResponse
{
Subject = "No longer supported",
Message = "No support for .wav files",
Songs = new List<Song>()
});
case "flac": case "flac":
song = _songMgr.SaveFlacSongToFileSystem(up.SongData, up.CoverArtData, song); song = _songMgr.SaveFlacSongToFileSystem(up.SongData, up.CoverArtData, song);
break; break;
@@ -176,7 +183,7 @@ public class SongDataController : BaseController
{ {
var songContext = new SongContext(_connectionString!); var songContext = new SongContext(_connectionString!);
var songMetaData = new Song{ Id = id }; var songMetaData = new Song { Id = id };
Console.WriteLine($"Id {songMetaData.Id}"); Console.WriteLine($"Id {songMetaData.Id}");
songMetaData = songContext.RetrieveRecord(songMetaData); songMetaData = songContext.RetrieveRecord(songMetaData);
@@ -207,4 +214,16 @@ public class SongDataController : BaseController
[FromForm(Name = "metadata")] [FromForm(Name = "metadata")]
public string? SongFile { get; set; } public string? SongFile { get; set; }
} }
public class UploadSongWithDataResponse
{
#region Properties
[Newtonsoft.Json.JsonProperty("message")]
public string Message { get; set; }
[Newtonsoft.Json.JsonProperty("subject")]
public string Subject { get; set; }
[Newtonsoft.Json.JsonProperty("data")]
public List<Song> Songs { get; set; }
#endregion
}
} }
@@ -39,7 +39,7 @@ public class SongStreamController : BaseController
var stream = new FileStream(song!.SongPath(), FileMode.Open, FileAccess.Read); var stream = new FileStream(song!.SongPath(), FileMode.Open, FileAccess.Read);
stream.Position = 0; stream.Position = 0;
var filename = song.Filename; var filename = song.Filename;
if (string.IsNullOrEmpty(song.Filename)) if (string.IsNullOrEmpty(song.Filename))
{ {
filename = song.GenerateFilename(); filename = song.GenerateFilename();
@@ -48,7 +48,8 @@ public class SongStreamController : BaseController
_logger!.LogInformation("Starting to stream song...>"); _logger!.LogInformation("Starting to stream song...>");
Console.WriteLine("Starting to streamsong..."); Console.WriteLine("Starting to streamsong...");
return await Task.Run(() => { return await Task.Run(() =>
{
return File(stream, "application/octet-stream", filename); return File(stream, "application/octet-stream", filename);
}); });
} }
+1 -1
View File
@@ -12,7 +12,7 @@ public class AlbumContext : DbContext
public AlbumContext(string connString) : base(new DbContextOptionsBuilder<AlbumContext>() public AlbumContext(string connString) : base(new DbContextOptionsBuilder<AlbumContext>()
.UseMySQL(connString).Options) .UseMySQL(connString).Options)
{ {
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
+2 -2
View File
@@ -8,11 +8,11 @@ public class ArtistContext : DbContext
{ {
public DbSet<Artist> Artists { get; set; } public DbSet<Artist> Artists { get; set; }
public ArtistContext(DbContextOptions<ArtistContext> options) : base (options) { } public ArtistContext(DbContextOptions<ArtistContext> options) : base(options) { }
public ArtistContext(string connString) : base(new DbContextOptionsBuilder<ArtistContext>() public ArtistContext(string connString) : base(new DbContextOptionsBuilder<ArtistContext>()
.UseMySQL(connString).Options) .UseMySQL(connString).Options)
{ {
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
+2 -2
View File
@@ -14,8 +14,8 @@ public class CoverArtContext : DbContext
public CoverArtContext(string connString) : base(new DbContextOptionsBuilder<CoverArtContext>() public CoverArtContext(string connString) : base(new DbContextOptionsBuilder<CoverArtContext>()
.UseMySQL(connString).Options) .UseMySQL(connString).Options)
{ {
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
modelBuilder.Entity<CoverArt>() modelBuilder.Entity<CoverArt>()
+1 -1
View File
@@ -14,7 +14,7 @@ public class GenreContext : DbContext
public GenreContext(string connString) : base(new DbContextOptionsBuilder<GenreContext>() public GenreContext(string connString) : base(new DbContextOptionsBuilder<GenreContext>()
.UseMySQL(connString).Options) .UseMySQL(connString).Options)
{ {
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
+2 -2
View File
@@ -1,7 +1,7 @@
using Microsoft.EntityFrameworkCore; 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
@@ -11,7 +11,7 @@ public class SongContext : DbContext
public SongContext(string connString) : base(new DbContextOptionsBuilder<SongContext>() public SongContext(string connString) : base(new DbContextOptionsBuilder<SongContext>()
.UseMySQL(connString).Options) .UseMySQL(connString).Options)
{ {
} }
public SongContext(DbContextOptions<SongContext> options) : base(options) { } public SongContext(DbContextOptions<SongContext> options) : base(options) { }
+3 -3
View File
@@ -1,7 +1,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Icarus.Models; using Icarus.Models;
namespace Icarus.Database.Contexts; namespace Icarus.Database.Contexts;
public class UserContext : DbContext public class UserContext : DbContext
@@ -15,7 +15,7 @@ public class UserContext : DbContext
public UserContext(string connString) : base(new DbContextOptionsBuilder<UserContext>() public UserContext(string connString) : base(new DbContextOptionsBuilder<UserContext>()
.UseMySQL(connString).Options) .UseMySQL(connString).Options)
{ {
} }
#endregion #endregion
@@ -29,7 +29,7 @@ public class UserContext : DbContext
.Property(u => u.DateCreated).HasDefaultValue(DateTime.Now); .Property(u => u.DateCreated).HasDefaultValue(DateTime.Now);
} }
public User RetrieveRecord(User user) public User RetrieveRecord(User user)
{ {
return Users.FirstOrDefault(usr => usr.Id == user.Id)!; return Users.FirstOrDefault(usr => usr.Id == user.Id)!;
+2 -1
View File
@@ -34,9 +34,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Models\Models.csproj" /> <ProjectReference Include="..\Models\Models.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Update="nlog.config" CopyToOutputDirectory="PreserveNewest" /> <Content Update="nlog.config" CopyToOutputDirectory="PreserveNewest" />
<Content Include="Images/Stock/*.*" CopyToOutputDirectory="PreserveNewest" /> <Content Include="Images/Stock/*.*" CopyToOutputDirectory="PreserveNewest" />
+4 -2
View File
@@ -56,14 +56,16 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJw
{ {
options.RequireHttpsMetadata = false; options.RequireHttpsMetadata = false;
options.SaveToken = true; options.SaveToken = true;
var audience = Configuration["JWT:Audience"];
var issuer = Configuration["JWT:Issuer"];
options.TokenValidationParameters = new TokenValidationParameters() options.TokenValidationParameters = new TokenValidationParameters()
{ {
ValidateIssuer = true, ValidateIssuer = true,
ValidateAudience = true, ValidateAudience = true,
ValidateIssuerSigningKey = true, ValidateIssuerSigningKey = true,
ValidateLifetime = true, ValidateLifetime = true,
ValidAudience = Configuration["JWT:Audience"], ValidAudience = audience,
ValidIssuer = Configuration["JWT:Issuer"], ValidIssuer = issuer,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]!)) IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]!))
}; };
}); });
View File
+1 -1
View File
@@ -23,7 +23,7 @@ public class CoverArt
{ {
var fullPath = this.Directory; var fullPath = this.Directory;
if (fullPath![fullPath.Length -1] != '/') if (fullPath![fullPath.Length - 1] != '/')
{ {
fullPath += "/"; fullPath += "/";
} }
+11
View File
@@ -0,0 +1,11 @@
namespace Icarus.Models;
public enum CreateFileResult
{
Unknwon = 0,
AlreadyExists = 1,
FileCreatedAndExists = 2
}
+4
View File
@@ -12,4 +12,8 @@
<PackageReference Include="newtonsoft.json" Version="13.0.3" /> <PackageReference Include="newtonsoft.json" Version="13.0.3" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project> </Project>
+33 -1
View File
@@ -80,7 +80,7 @@ public class Song
{ {
var fullPath = SongDirectory; var fullPath = SongDirectory;
if (fullPath![fullPath.Length -1] != '/') if (fullPath![fullPath.Length - 1] != '/')
{ {
fullPath += "/"; fullPath += "/";
} }
@@ -112,6 +112,27 @@ public class Song
return includeExtension ? $"{filename}{extension}" : filename; return includeExtension ? $"{filename}{extension}" : filename;
} }
public CreateSongResult Create(Microsoft.AspNetCore.Http.IFormFile file, string filePath, string prompt)
{
if (System.IO.File.Exists(filePath))
{
return CreateSongResult.AlreadyExists;
}
using (var filestream = new FileStream(filePath, FileMode.Create))
{
Console.WriteLine(prompt);
file.CopyTo(filestream);
if (System.IO.File.Exists(filePath))
{
return CreateSongResult.Created;
}
}
return CreateSongResult.NotCreated;
}
private string DetermineFileExtension(AudioFileExtensionsType flag) private string DetermineFileExtension(AudioFileExtensionsType flag)
{ {
switch (flag) switch (flag)
@@ -135,11 +156,22 @@ public class Song
return filename; return filename;
} }
#endregion #endregion
} }
#region Enums
public enum AudioFileExtensionsType public enum AudioFileExtensionsType
{ {
Default = 0, Default = 0,
WAV = 1, WAV = 1,
FLAC = 2 FLAC = 2
} }
public enum CreateSongResult
{
NotCreated = 0,
AlreadyExists = 1,
Created = 2
}
#endregion