#103: Remove WAV support #105
@@ -18,3 +18,7 @@ Icarus/bin
|
||||
Icarus/obj
|
||||
Models/bin
|
||||
Models/obj
|
||||
Migrations
|
||||
Icarus.txt
|
||||
Storage
|
||||
.DS_Store
|
||||
|
||||
@@ -100,13 +100,13 @@ public class DirectoryManager : BaseManager
|
||||
var artistDirectory = ArtistDirectory();
|
||||
if (IsDirectoryEmpty(albumDirectory))
|
||||
{
|
||||
Directory.Delete(albumDirectory);
|
||||
Console.WriteLine($"directory {albumDirectory} deleted");
|
||||
Directory.Delete(albumDirectory);
|
||||
Console.WriteLine($"directory {albumDirectory} deleted");
|
||||
}
|
||||
if (IsDirectoryEmpty(artistDirectory))
|
||||
{
|
||||
Directory.Delete(artistDirectory);
|
||||
Console.WriteLine($"directory {artistDirectory} deleted");
|
||||
Directory.Delete(artistDirectory);
|
||||
Console.WriteLine($"directory {artistDirectory} deleted");
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
try
|
||||
@@ -125,12 +157,12 @@ public class DirectoryManager : BaseManager
|
||||
|
||||
if (IsDirectoryEmpty(albumDirectory))
|
||||
{
|
||||
Directory.Delete(albumDirectory);
|
||||
Directory.Delete(albumDirectory);
|
||||
_logger.Info("Album directory deleted");
|
||||
}
|
||||
if (IsDirectoryEmpty(artistDirectory))
|
||||
{
|
||||
Directory.Delete(artistDirectory);
|
||||
Directory.Delete(artistDirectory);
|
||||
_logger.Info("Artist directory deleted");
|
||||
}
|
||||
}
|
||||
@@ -187,7 +219,7 @@ public class DirectoryManager : BaseManager
|
||||
|
||||
private class DirEnt
|
||||
{
|
||||
public string? Pre { get; set;}
|
||||
public string? Pre { get; set; }
|
||||
public string? Path { get; set; }
|
||||
public string? Post { get; set; }
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ using NLog;
|
||||
using Icarus.Controllers.Utilities;
|
||||
using Icarus.Models;
|
||||
using Icarus.Database.Contexts;
|
||||
using TagLib.Mpeg4;
|
||||
|
||||
namespace Icarus.Controllers.Managers;
|
||||
|
||||
|
||||
public class SongManager : BaseManager
|
||||
{
|
||||
#region Fields
|
||||
@@ -107,11 +109,18 @@ public class SongManager : BaseManager
|
||||
try
|
||||
{
|
||||
var songPath = songMetaData.SongPath();
|
||||
File.Delete(songPath);
|
||||
successful = true;
|
||||
System.IO.File.Delete(songPath);
|
||||
successful = !System.IO.File.Exists(songPath);
|
||||
if (successful)
|
||||
{
|
||||
Console.WriteLine("Song successfully deleted");
|
||||
}
|
||||
DirectoryManager dirMgr = new DirectoryManager(_config!, songMetaData);
|
||||
dirMgr.DeleteEmptyDirectories();
|
||||
Console.WriteLine("Song successfully deleted");
|
||||
var deletedAmount = dirMgr.DeleteEmptyDirectories(songMetaData.SongDirectory, 1);
|
||||
if (deletedAmount > 0)
|
||||
{
|
||||
Console.WriteLine($"{deletedAmount} directories deleted");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -196,6 +205,7 @@ public class SongManager : BaseManager
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
if (string.IsNullOrEmpty(song.SongDirectory))
|
||||
@@ -252,8 +262,8 @@ public class SongManager : BaseManager
|
||||
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 cover art
|
||||
// Update the song's metadata with the song object
|
||||
@@ -283,10 +293,10 @@ public class SongManager : BaseManager
|
||||
SaveSongToDatabase(song, coverArt);
|
||||
|
||||
return song;
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveSongToFinalDestination(string sourcePath, string targetPath)
|
||||
{
|
||||
private void MoveSongToFinalDestination(string sourcePath, string targetPath)
|
||||
{
|
||||
using (var fileStream = new FileStream(targetPath, FileMode.Create))
|
||||
{
|
||||
var songBytes = System.IO.File.ReadAllBytes(sourcePath);
|
||||
@@ -315,7 +325,7 @@ public class SongManager : BaseManager
|
||||
|
||||
_logger.Info("Song successfully saved to filesystem");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<SongData> RetrieveSong(Song songMetaData)
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
var currentTitle = currentSong.Title;
|
||||
@@ -439,7 +471,7 @@ public class SongManager : BaseManager
|
||||
|
||||
DeleteEmptyDirectories(ref song, ref song);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
_logger.Error(msg, "An error occurred when attempting to delete the song from the filesystem");
|
||||
|
||||
@@ -74,7 +74,7 @@ public class TokenManager : BaseManager
|
||||
|
||||
public LoginResult LoginSymmetric(User user)
|
||||
{
|
||||
var tokenResult = new TokenTierOne{ TokenType = "JWT" };
|
||||
var tokenResult = new TokenTierOne { TokenType = "JWT" };
|
||||
|
||||
var payload = Payload();
|
||||
payload.Add(new Claim("user_id", user.Id.ToString(), ClaimValueTypes.Integer));
|
||||
@@ -112,8 +112,11 @@ public class TokenManager : BaseManager
|
||||
{
|
||||
return new LoginResult
|
||||
{
|
||||
UserId = user.Id, Username = user.Username, Token = token.AccessToken,
|
||||
TokenType = token.TokenType, Expiration = token.Expiration,
|
||||
UserId = user.Id,
|
||||
Username = user.Username,
|
||||
Token = token.AccessToken,
|
||||
TokenType = token.TokenType,
|
||||
Expiration = token.Expiration,
|
||||
Message = SUCCESSFUL_TOKEN_MESSAGE
|
||||
};
|
||||
}
|
||||
@@ -224,8 +227,10 @@ public class TokenManager : BaseManager
|
||||
|
||||
return new TokenRequest
|
||||
{
|
||||
ClientId = _clientId, ClientSecret = _clientSecret,
|
||||
Audience = _audience, GrantType = _grantType
|
||||
ClientId = _clientId,
|
||||
ClientSecret = _clientSecret,
|
||||
Audience = _audience,
|
||||
GrantType = _grantType
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ public class MetadataRetriever
|
||||
{
|
||||
#region Fields
|
||||
private static NLog.Logger? _logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
||||
private List<string>? _supportedAudioFileTypes = new List<string> {"wav", "flac"};
|
||||
private List<string>? _supportedImageFileTypes = new List<string> {"jpeg", "jpg", "png"};
|
||||
private List<string>? _supportedAudioFileTypes = new List<string> { "wav", "flac" };
|
||||
private List<string>? _supportedImageFileTypes = new List<string> { "jpeg", "jpg", "png" };
|
||||
private Song? _updatedSong;
|
||||
private string? _message;
|
||||
private string? _title;
|
||||
@@ -267,7 +267,7 @@ public class MetadataRetriever
|
||||
break;
|
||||
case "artists":
|
||||
_updatedSong!.Artist = artist;
|
||||
fileTag.Tag.Performers = new []{artist};
|
||||
fileTag.Tag.Performers = new[] { artist };
|
||||
break;
|
||||
case "album":
|
||||
_updatedSong!.AlbumTitle = album;
|
||||
@@ -275,7 +275,7 @@ public class MetadataRetriever
|
||||
break;
|
||||
case "genre":
|
||||
_updatedSong!.Genre = genre;
|
||||
fileTag.Tag.Genres = new []{genre};
|
||||
fileTag.Tag.Genres = new[] { genre };
|
||||
break;
|
||||
case "year":
|
||||
_updatedSong!.Year = year;
|
||||
@@ -283,7 +283,7 @@ public class MetadataRetriever
|
||||
break;
|
||||
case "albumartist":
|
||||
_updatedSong!.AlbumArtist = albumArtist;
|
||||
fileTag.Tag.AlbumArtists = new []{albumArtist};
|
||||
fileTag.Tag.AlbumArtists = new[] { albumArtist };
|
||||
break;
|
||||
case "track":
|
||||
_updatedSong!.Track = track;
|
||||
|
||||
@@ -70,14 +70,14 @@ public class PasswordEncryption
|
||||
password: password, salt: salt,
|
||||
prf: KeyDerivationPrf.HMACSHA1,
|
||||
iterationCount: 10000,
|
||||
numBytesRequested: 256/8));
|
||||
numBytesRequested: 256 / 8));
|
||||
|
||||
return hashed;
|
||||
}
|
||||
|
||||
byte[] GenerateSalt()
|
||||
{
|
||||
byte[] salt = new byte[128/8];
|
||||
byte[] salt = new byte[128 / 8];
|
||||
|
||||
using (var rng = RandomNumberGenerator.Create())
|
||||
rng.GetBytes(salt);
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SongCompression
|
||||
|
||||
songData.Data = await System.IO.File.ReadAllBytesAsync(archivePath);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error ocurred: \n{exMsg}");
|
||||
|
||||
@@ -48,7 +48,7 @@ public class AlbumController : BaseController
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult GetAlbum(int id)
|
||||
{
|
||||
Album album = new Album{ Id = id };
|
||||
Album album = new Album { Id = id };
|
||||
|
||||
var albumContext = new AlbumContext(_connectionString!);
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public class CoverArtController : BaseController
|
||||
var songContext = new SongContext(_connectionString!);
|
||||
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 filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.JPG_EXTENSION, songMetaData.Title!, randomizeFilename);
|
||||
|
||||
@@ -58,7 +58,7 @@ public class GenreController : BaseController
|
||||
|
||||
if (genreStore.DoesRecordExist(genre))
|
||||
{
|
||||
genre = genreStore.RetrieveRecord(genre);
|
||||
genre = genreStore.RetrieveRecord(genre);
|
||||
|
||||
return Ok(genre);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SongCompressedDataController : BaseController
|
||||
Console.WriteLine($"Archive directory root: {_archiveDir}");
|
||||
|
||||
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);
|
||||
|
||||
var filename = DirectoryManager.GenerateDownloadFilename(10, Constants.FileExtensions.ZIP_EXTENSION, sng.Title!, randomizeFilename);
|
||||
|
||||
@@ -61,7 +61,7 @@ public class SongController : BaseController
|
||||
{
|
||||
var context = new SongContext(_connectionString!);
|
||||
|
||||
var song = context.RetrieveRecord(new Song{ Id = id });
|
||||
var song = context.RetrieveRecord(new Song { Id = id });
|
||||
|
||||
Console.WriteLine("Here");
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ using Icarus.Database.Contexts;
|
||||
|
||||
namespace Icarus.Controllers.V1;
|
||||
|
||||
|
||||
|
||||
[Route("api/v1/song/data")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
@@ -40,7 +42,7 @@ public class SongDataController : BaseController
|
||||
public IActionResult Download(int id, [FromQuery] bool? randomizeFilename)
|
||||
{
|
||||
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;
|
||||
string filename;
|
||||
@@ -151,8 +153,13 @@ public class SongDataController : BaseController
|
||||
switch (song.AudioType)
|
||||
{
|
||||
case "wav":
|
||||
song = _songMgr.SaveSongToFileSystem(up.SongData, up.CoverArtData, song);
|
||||
break;
|
||||
var _ = _songMgr.DeleteSongFromFileSystem(tmpSong);
|
||||
return BadRequest(new UploadSongWithDataResponse
|
||||
{
|
||||
Subject = "No longer supported",
|
||||
Message = "No support for .wav files",
|
||||
Songs = new List<Song>()
|
||||
});
|
||||
case "flac":
|
||||
song = _songMgr.SaveFlacSongToFileSystem(up.SongData, up.CoverArtData, song);
|
||||
break;
|
||||
@@ -176,7 +183,7 @@ public class SongDataController : BaseController
|
||||
{
|
||||
var songContext = new SongContext(_connectionString!);
|
||||
|
||||
var songMetaData = new Song{ Id = id };
|
||||
var songMetaData = new Song { Id = id };
|
||||
Console.WriteLine($"Id {songMetaData.Id}");
|
||||
|
||||
songMetaData = songContext.RetrieveRecord(songMetaData);
|
||||
@@ -207,4 +214,16 @@ public class SongDataController : BaseController
|
||||
[FromForm(Name = "metadata")]
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,8 @@ public class SongStreamController : BaseController
|
||||
_logger!.LogInformation("Starting to stream song...>");
|
||||
Console.WriteLine("Starting to streamsong...");
|
||||
|
||||
return await Task.Run(() => {
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
return File(stream, "application/octet-stream", filename);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ public class ArtistContext : DbContext
|
||||
{
|
||||
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>()
|
||||
.UseMySQL(connString).Options)
|
||||
{
|
||||
|
||||
@@ -34,9 +34,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Models\Models.csproj" />
|
||||
<ProjectReference Include="..\Models\Models.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="nlog.config" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="Images/Stock/*.*" CopyToOutputDirectory="PreserveNewest" />
|
||||
|
||||
+4
-2
@@ -56,14 +56,16 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJw
|
||||
{
|
||||
options.RequireHttpsMetadata = false;
|
||||
options.SaveToken = true;
|
||||
var audience = Configuration["JWT:Audience"];
|
||||
var issuer = Configuration["JWT:Issuer"];
|
||||
options.TokenValidationParameters = new TokenValidationParameters()
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidateLifetime = true,
|
||||
ValidAudience = Configuration["JWT:Audience"],
|
||||
ValidIssuer = Configuration["JWT:Issuer"],
|
||||
ValidAudience = audience,
|
||||
ValidIssuer = issuer,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]!))
|
||||
};
|
||||
});
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ public class CoverArt
|
||||
{
|
||||
var fullPath = this.Directory;
|
||||
|
||||
if (fullPath![fullPath.Length -1] != '/')
|
||||
if (fullPath![fullPath.Length - 1] != '/')
|
||||
{
|
||||
fullPath += "/";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
|
||||
namespace Icarus.Models;
|
||||
|
||||
public enum CreateFileResult
|
||||
{
|
||||
Unknwon = 0,
|
||||
AlreadyExists = 1,
|
||||
FileCreatedAndExists = 2
|
||||
}
|
||||
@@ -12,4 +12,8 @@
|
||||
<PackageReference Include="newtonsoft.json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
+33
-1
@@ -80,7 +80,7 @@ public class Song
|
||||
{
|
||||
var fullPath = SongDirectory;
|
||||
|
||||
if (fullPath![fullPath.Length -1] != '/')
|
||||
if (fullPath![fullPath.Length - 1] != '/')
|
||||
{
|
||||
fullPath += "/";
|
||||
}
|
||||
@@ -112,6 +112,27 @@ public class Song
|
||||
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)
|
||||
{
|
||||
switch (flag)
|
||||
@@ -135,11 +156,22 @@ public class Song
|
||||
return filename;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#region Enums
|
||||
public enum AudioFileExtensionsType
|
||||
{
|
||||
Default = 0,
|
||||
WAV = 1,
|
||||
FLAC = 2
|
||||
}
|
||||
|
||||
public enum CreateSongResult
|
||||
{
|
||||
NotCreated = 0,
|
||||
AlreadyExists = 1,
|
||||
Created = 2
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user