Compare commits

..

20 Commits

Author SHA1 Message Date
amazing-username 3948e25fc3 Incorrect method call for logging fixed 2019-07-20 01:47:16 +00:00
amazing-username a39c232c34 Added logging for cover art functionality 2019-07-17 20:15:07 -04:00
amazing-username 8ec7092272 Implemented Cover Art functionality #50 #52 2019-07-16 20:44:53 -04:00
amazing-username 84615472ef Cover art image gets deleted when the song has been deleted #50 2019-07-15 22:12:49 -04:00
amazing-username e4be56101a Added functionality to save the stock cover art to a song if the song does not contain a cover art #50 2019-07-14 22:40:49 -04:00
amazing-username 59895af3b4 Can download a cover art via the cover art's id. Just need to have a stock cover art for songs without any and update the documentation. #50 2019-07-13 16:04:39 -04:00
amazing-username 1004f6c93d Can successfully save the coverart record, now need to work on downloading the cover art #50 2019-07-13 10:13:15 -04:00
amazing-username 026a528a81 Cover art functionality added. Left TODO's on where to continue on. #50 2019-07-12 23:13:32 -04:00
amazing-username 226ca44206 Mover Cover Art work. #50 2019-07-11 23:15:45 -04:00
amazing-username 4940768d22 All the necessary functionality for the Cover Art repo added #51 2019-07-10 17:54:17 -04:00
amazing-username f7963237fd Added TODO's for checking if Cover art already exists. Added functionality in DirectoryManager to switch to the CoverArt path when explicitly request, otherwise defaults to the music root path. Added skeleton function for CoverArtRepository in the CoverArtRepository and SongManager 2019-07-09 21:03:52 -04:00
amazing-username 0ee1473639 Finished Cover art repository #51 2019-07-09 19:44:40 -04:00
amazing-username 2b59bfac32 Updates to the Cover art repository #51 2019-07-08 18:42:44 -04:00
amazing-username 0932be2f2b Added but did not complete the repository for cover art, updated migration script to create migration for CoverArt, and prepping for the cover art api 2019-07-07 15:02:38 -04:00
amazing-username 82686f5c33 Added cover art path to json files #53 2019-07-07 11:05:53 -04:00
amazing-username b5501e323f Added a cover art model. Better to do it now and not wait til later 2019-07-06 22:26:55 -04:00
amazing-username 089bd1191c Adding Cover art support #50 2019-07-05 20:37:38 -04:00
amazing-username 56fe805f80 Code cleanup and conforming to a coding covention 2019-07-04 17:19:40 -04:00
amazing-username ada8fa79d3 Cleaning up code convention inconsistencies 2019-07-04 15:57:43 -04:00
Kun Deng bc209c2363 Update README.md
#30
2019-06-23 13:11:55 -04:00
63 changed files with 5331 additions and 4897 deletions
+3 -4
View File
@@ -10,16 +10,15 @@ namespace Icarus.Authorization.Handlers
{
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))
{
return Task.CompletedTask;
}
var scopes = context.User.FindFirst(c => c.Type == "scope" &&
c.Issuer == requirement.Issuer).Value.Split(' ');
var scopes = context.User.FindFirst(c =>
c.Type == "scope" && c.Issuer == requirement.Issuer).Value.Split(' ');
if (scopes.Any(s => s == requirement.Scope))
{
+11
View File
@@ -0,0 +1,11 @@
using System;
using System.IO;
namespace Icarus.Constants
{
public class DirectoryPaths
{
public static string CoverArtPath =>
Directory.GetCurrentDirectory() + "/Images/Stock/CoverArt.png";
}
}
+127
View File
@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.IO;
using Icarus.Constants;
using Icarus.Controllers.Utilities;
using Icarus.Database.Repositories;
using Icarus.Models;
using Icarus.Types;
namespace Icarus.Controllers.Managers
{
public class CoverArtManager : BaseManager
{
#region Fields
private string _rootCoverArtPath;
private byte[] _stockCoverArt = null;
#endregion
#region Constructors
public CoverArtManager(string rootPath)
{
_rootCoverArtPath = rootPath;
Initialize();
}
#endregion
#region Methods
public void SaveCoverArtToDatabase(ref Song song, ref CoverArt coverArt,
CoverArtRepository coverArtRepository)
{
_logger.Info("Saving cover art record to the database");
coverArtRepository.SaveCoverArt(coverArt);
coverArt = coverArtRepository.GetCoverArt(CoverArtField.SongTitle,
coverArt);
song.CoverArtId = coverArt.CoverArtId;
}
public void DeleteCoverArtFromDatabase(CoverArt coverArt,
CoverArtRepository coverArtRepository)
{
_logger.Info("Attempting to delete cover art from the database");
coverArtRepository.DeleteCoverArt(coverArt);
}
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);
dirMgr.CreateDirectory(song);
var imagePath = dirMgr.SongDirectory + song.Title + ".png";
var coverArt = new CoverArt
{
SongTitle = song.Title,
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 + "CoverArt.png";
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;
}
private void Initialize()
{
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
}
}
+37 -1
View File
@@ -5,6 +5,7 @@ using System.Linq;
using Microsoft.Extensions.Configuration;
using Icarus.Models;
using Icarus.Types;
namespace Icarus.Controllers.Managers
{
@@ -39,6 +40,10 @@ namespace Icarus.Controllers.Managers
_config = config;
Initialize();
}
public DirectoryManager(string rootDirectory)
{
_rootSongDirectory = rootDirectory;
}
#endregion
@@ -64,6 +69,29 @@ namespace Icarus.Controllers.Managers
Console.WriteLine($"An error occurred {ex.Message}");
}
}
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
@@ -160,9 +188,17 @@ namespace Icarus.Controllers.Managers
return songPath;
}
private void Initialize()
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)
+26 -35
View File
@@ -96,8 +96,7 @@ namespace Icarus.Controllers.Managers
#region Methods
public SongResult UpdateSong(Song song, SongRepository songStore, AlbumRepository albumStore,
ArtistRepository artistStore, GenreRepository genreStore,
YearRepository yearStore)
ArtistRepository artistStore, GenreRepository genreStore, YearRepository yearStore)
{
var result = new SongResult();
@@ -163,17 +162,25 @@ namespace Icarus.Controllers.Managers
public void DeleteSong(Song song, SongRepository songStore,
AlbumRepository albumStore, ArtistRepository artistStore,
GenreRepository genreStore, YearRepository yearStore)
GenreRepository genreStore, YearRepository yearStore,
CoverArtRepository coverStore)
{
try
{
if (DeleteSongFromFilesystem(song))
{
_logger.Info("Failed to delete the 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.GetValue<string>(
"CoverArtPath"));
var coverArt = coverStore.GetCoverArt(song);
coverMgr.DeleteCoverArt(coverArt);
coverMgr.DeleteCoverArtFromDatabase(coverArt, coverStore);
DeleteSongFromDatabase(song, songStore, albumStore, artistStore,
genreStore, yearStore);
}
@@ -283,6 +290,7 @@ namespace Icarus.Controllers.Managers
DirectoryManager dirMgr = new DirectoryManager(_config, _song);
dirMgr.CreateDirectory();
filePath = dirMgr.SongDirectory;
if (!song.FileName.EndsWith(".mp3"))
filePath += $"{song.FileName}.mp3";
else
@@ -305,8 +313,7 @@ namespace Icarus.Controllers.Managers
}
}
public async Task SaveSongToFileSystem(IFormFile songFile, SongRepository sStoreContext,
AlbumRepository alStoreContext,
ArtistRepository arStoreContext)
AlbumRepository alStoreContext, ArtistRepository arStoreContext)
{
try
{
@@ -318,6 +325,7 @@ namespace Icarus.Controllers.Managers
DirectoryManager dirMgr = new DirectoryManager(_config, song);
dirMgr.CreateDirectory();
var filePath = dirMgr.SongDirectory;
if (!songFile.FileName.EndsWith(".mp3"))
filePath += $"{songFile.FileName}.mp3";
else
@@ -342,7 +350,8 @@ namespace Icarus.Controllers.Managers
}
public async Task SaveSongToFileSystem(IFormFile songFile, SongRepository songStore,
AlbumRepository albumStore, ArtistRepository artistStore,
GenreRepository genreStore, YearRepository yearStore)
GenreRepository genreStore, YearRepository yearStore,
CoverArtRepository coverArtStore)
{
try
{
@@ -350,11 +359,13 @@ namespace Icarus.Controllers.Managers
var fileTempPath = Path.Combine(_tempDirectoryRoot, songFile.FileName);
var song = await SaveSongTemp(songFile, fileTempPath);
System.IO.File.Delete(fileTempPath);
song.SongPath = fileTempPath;
DirectoryManager dirMgr = new DirectoryManager(_config, song);
dirMgr.CreateDirectory();
System.IO.File.Delete(fileTempPath);
var filePath = dirMgr.SongDirectory;
var songFilename = songFile.FileName;
@@ -365,6 +376,7 @@ namespace Icarus.Controllers.Managers
_logger.Info($"Absolute song path: {filePath}");
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await (songFile.CopyToAsync(fileStream));
@@ -373,6 +385,11 @@ namespace Icarus.Controllers.Managers
_logger.Info("Song successfully saved to filesystem");
}
var coverMgr = new CoverArtManager(_config.GetValue<string>("CoverArtPath"));
var coverArt = coverMgr.SaveCoverArt(song);
coverMgr.SaveCoverArtToDatabase(ref song, ref coverArt,
coverArtStore);
SaveSongToDatabase(song, songStore, albumStore, artistStore, genreStore,
yearStore);
}
@@ -599,9 +616,7 @@ namespace Icarus.Controllers.Managers
if (!currentTitle.Equals(songUpdates.Title) || !currentArtist.Equals(songUpdates.Artist) ||
!currentAlbum.Equals(songUpdates.AlbumTitle) ||
!currentGenre.Equals(songUpdates.Genre) || currentYear != songUpdates.Year)
{
return true;
}
return false;
}
@@ -793,9 +808,7 @@ namespace Icarus.Controllers.Managers
return false;
}
var result = DoesSongExistOnFilesystem(song);
return result;
return DoesSongExistOnFilesystem(song);
}
private bool DoesSongExistOnFilesystem(Song song)
{
@@ -824,13 +837,9 @@ namespace Icarus.Controllers.Managers
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)))
@@ -1032,9 +1041,7 @@ namespace Icarus.Controllers.Managers
_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;
@@ -1052,9 +1059,7 @@ namespace Icarus.Controllers.Managers
Console.WriteLine($"{updatedSongRecord.Genre} {newSongRecord.Genre}");
}
if (newSongRecord.Year != null || newSongRecord.Year > 0)
{
updatedSongRecord.Year = newSongRecord.Year;
}
_logger.Info("Applied changes to song record");
@@ -1090,21 +1095,15 @@ namespace Icarus.Controllers.Managers
System.IO.File.Delete(oldSongPath);
if (System.IO.File.Exists(oldSongPath))
{
Console.WriteLine("Old path exists when it should not");
}
}
_logger.Info("Saving song metadata to the database");
if (songStore.DoesSongExist(newSongRecord))
{
songStore.UpdateSong(updatedSongRecord);
}
else
{
songStore.SaveSong(updatedSongRecord);
}
newSongRecord = updatedSongRecord;
@@ -1135,10 +1134,8 @@ namespace Icarus.Controllers.Managers
var album = albumStore.GetAlbum(song, true);
if (album.SongCount <= 1)
{
albumStore.DeleteAlbum(album);
}
}
private void DeleteArtistFromDatabase(Song song, ArtistRepository artistStore)
{
if (!artistStore.DoesArtistExist(song))
@@ -1150,10 +1147,8 @@ namespace Icarus.Controllers.Managers
var artist = artistStore.GetArtist(song, true);
if (artist.SongCount <= 1)
{
artistStore.DeleteArtist(artist);
}
}
private void DeleteGenreFromDatabase(Song song, GenreRepository genreStore)
{
if (!genreStore.DoesGenreExist(song))
@@ -1165,10 +1160,8 @@ namespace Icarus.Controllers.Managers
var genre = genreStore.GetGenre(song, true);
if (genre.SongCount <= 1)
{
genreStore.DeleteGenre(genre);
}
}
private void DeleteYearFromDatabase(Song song, YearRepository yearStore)
{
if (!yearStore.DoesYearExist(song))
@@ -1180,10 +1173,8 @@ namespace Icarus.Controllers.Managers
var year = yearStore.GetSongYear(song, true);
if (year.SongCount <= 1)
{
yearStore.DeleteYear(year);
}
}
private async Task PopulateSongDetails()
{
+5 -12
View File
@@ -46,7 +46,7 @@ namespace Icarus.Controllers.Managers
_logger.Info("Serializing token object into JSON");
var tokenObject = JsonConvert.SerializeObject(tokenRequest);
Console.WriteLine(tokenObject);
request.AddParameter("application/json; charset=utf-8",
tokenObject, ParameterType.RequestBody);
@@ -61,15 +61,11 @@ namespace Icarus.Controllers.Managers
var tokenResult = JsonConvert
.DeserializeObject<Token>(response.Content);
_logger.Info("Response deserialized");
Console.WriteLine(response.Content);
return new LoginResult
{
UserId = user.Id,
Username = user.Username,
Token = tokenResult.AccessToken,
TokenType = tokenResult.TokenType,
Expiration = tokenResult.Expiration,
UserId = user.Id, Username = user.Username, Token = tokenResult.AccessToken,
TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration,
Message = "Successfully retrieved token"
};
}
@@ -80,10 +76,8 @@ namespace Icarus.Controllers.Managers
return new TokenRequest
{
ClientId = _clientId,
ClientSecret = _clientSecret,
Audience = _audience,
GrantType = _grantType
ClientId = _clientId, ClientSecret = _clientSecret,
Audience = _audience, GrantType = _grantType
};
}
@@ -98,7 +92,6 @@ namespace Icarus.Controllers.Managers
_url = $"https://{_config["Auth0:Domain"]}";
PrintCredentials();
}
#region Testing Methods
+37 -8
View File
@@ -101,6 +101,25 @@ namespace Icarus.Controllers.Utilities
return song;
}
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 song)
{
try
@@ -140,6 +159,22 @@ namespace Icarus.Controllers.Utilities
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)
{
@@ -161,7 +196,6 @@ namespace Icarus.Controllers.Utilities
if (!result)
{
switch (key.ToLower())
{
case "title":
@@ -186,7 +220,6 @@ namespace Icarus.Controllers.Utilities
break;
}
}
}
fileTag.Save();
@@ -263,18 +296,14 @@ namespace Icarus.Controllers.Utilities
songValues["Artists"] = String.IsNullOrEmpty(song.Artist);
songValues["Album"] = String.IsNullOrEmpty(song.AlbumTitle);
songValues["Genre"] = String.IsNullOrEmpty(song.Genre);
if (song.Year == null)
{
songValues["Year"] = true;
}
else if (song.Year==0)
{
songValues["Year"] = true;
}
else
{
songValues["Year"] = false;
}
Console.WriteLine("Checking for null data completed");
_logger.Info("Checking for null data completed");
}
+1 -4
View File
@@ -67,8 +67,7 @@ namespace Icarus.Controllers.Utilities
{
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
password: password, salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256/8));
@@ -81,9 +80,7 @@ namespace Icarus.Controllers.Utilities
byte[] salt = new byte[128/8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
return salt;
+2 -10
View File
@@ -40,21 +40,16 @@ namespace Icarus.Controllers.V1
{
List<Album> albums = new List<Album>();
AlbumRepository albumStoreContext = HttpContext
.RequestServices
AlbumRepository albumStoreContext = HttpContext.RequestServices
.GetService(typeof(AlbumRepository)) as AlbumRepository;
albums = albumStoreContext.GetAlbums();
if (albums.Count > 0)
{
return Ok(albums);
}
else
{
return NotFound();
}
}
[HttpGet("{id}")]
[Authorize("read:albums")]
@@ -65,8 +60,7 @@ namespace Icarus.Controllers.V1
AlbumId = id
};
AlbumRepository albumStoreContext = HttpContext
.RequestServices
AlbumRepository albumStoreContext = HttpContext.RequestServices
.GetService(typeof(AlbumRepository)) as AlbumRepository;
if (albumStoreContext.DoesAlbumExist(album))
@@ -76,10 +70,8 @@ namespace Icarus.Controllers.V1
return Ok(album);
}
else
{
return NotFound();
}
}
#endregion
}
}
+2 -11
View File
@@ -39,21 +39,16 @@ namespace Icarus.Controllers.V1
[Authorize("read:artists")]
public IActionResult Get()
{
ArtistRepository artistStoreContext = HttpContext
.RequestServices
ArtistRepository artistStoreContext = HttpContext.RequestServices
.GetService(typeof(ArtistRepository)) as ArtistRepository;
var artists = artistStoreContext.GetArtists();
if (artists.Count > 0)
{
return Ok(artists);
}
else
{
return NotFound();
}
}
[HttpGet("{id}")]
[Authorize("read:artists")]
@@ -64,22 +59,18 @@ namespace Icarus.Controllers.V1
ArtistId = id
};
ArtistRepository artistStoreContext = HttpContext
.RequestServices
ArtistRepository artistStoreContext = HttpContext.RequestServices
.GetService(typeof(ArtistRepository)) as ArtistRepository;
if (artistStoreContext.DoesArtistExist(artist))
{
artist = artistStoreContext.GetArtist(artist);
return Ok(artist);
}
else
{
return NotFound();
}
}
#endregion
}
}
+64
View File
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Icarus.Controllers.Managers;
using Icarus.Database.Repositories;
using Icarus.Models;
namespace Icarus.Controllers.V1
{
[Route("api/v1/coverart")]
[ApiController]
public class CoverArtController : ControllerBase
{
#region Fields
private readonly ILogger<CoverArtController> _logger;
#endregion
#region Constructors
public CoverArtController(ILogger<CoverArtController> logger)
{
_logger = logger;
}
#endregion
#region HTTP Routes
[HttpGet("{id}")]
[Authorize("download:cover_art")]
public IActionResult Get(int id)
{
var coverArt = new CoverArt { CoverArtId = id };
var coverArtRepository = HttpContext
.RequestServices
.GetService(
typeof(CoverArtRepository)) as CoverArtRepository;
coverArt = coverArtRepository.GetCoverArt(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
}
}
+2 -10
View File
@@ -39,21 +39,16 @@ namespace Icarus.Controllers.V1
{
var genres = new List<Genre>();
var genreStore = HttpContext
.RequestServices
var genreStore = HttpContext.RequestServices
.GetService(typeof(GenreRepository)) as GenreRepository;
genres = genreStore.GetGenres();
if (genres.Count > 0)
{
return Ok(genres);
}
else
{
return NotFound(new List<Genre>());
}
}
[HttpGet("{id}")]
[Authorize("read:genre")]
@@ -64,8 +59,7 @@ namespace Icarus.Controllers.V1
GenreId = id
};
var genreStore = HttpContext
.RequestServices
var genreStore = HttpContext.RequestServices
.GetService(typeof(GenreRepository)) as GenreRepository;
if (genreStore.DoesGenreExist(genre))
@@ -75,10 +69,8 @@ namespace Icarus.Controllers.V1
return Ok(genre);
}
else
{
return NotFound(new Genre());
}
}
#endregion
}
}
+1 -2
View File
@@ -41,8 +41,7 @@ namespace Icarus.Controllers.V1
#region HTTP endpoints
public IActionResult Post([FromBody] User user)
{
UserRepository context = HttpContext
.RequestServices
UserRepository context = HttpContext.RequestServices
.GetService(typeof(UserRepository)) as UserRepository;
_logger.LogInformation("Starting process of validating credentials");
+1 -2
View File
@@ -41,8 +41,7 @@ namespace Icarus.Controllers.V1
user.Password = pe.HashPassword(user);
user.EmailVerified = false;
UserRepository context = HttpContext
.RequestServices
UserRepository context = HttpContext.RequestServices
.GetService(typeof(UserRepository)) as UserRepository;
context.SaveUser(user);
@@ -47,8 +47,7 @@ namespace Icarus.Controllers.V1
[Authorize("download:songs")]
public async Task<IActionResult> Get(int id)
{
SongRepository context = HttpContext
.RequestServices
SongRepository context = HttpContext.RequestServices
.GetService(typeof(SongRepository)) as SongRepository;
SongCompression cmp = new SongCompression(_archiveDir);
+7 -24
View File
@@ -49,28 +49,22 @@ namespace Icarus.Controllers.V1
Console.WriteLine("Attemtping to retrieve songs");
_logger.LogInformation("Attempting to retrieve songs");
SongRepository context = HttpContext
.RequestServices
SongRepository context = HttpContext.RequestServices
.GetService(typeof(SongRepository)) as SongRepository;
songs = context.GetAllSongs();
if (songs.Count > 0)
{
return Ok(songs);
}
else
{
return NotFound();
}
}
[HttpGet("{id}")]
[Authorize("read:song_details")]
public IActionResult Get(int id)
{
SongRepository context = HttpContext
.RequestServices
SongRepository context = HttpContext.RequestServices
.GetService(typeof(SongRepository)) as SongRepository;
Song song = new Song { Id = id };
@@ -79,37 +73,28 @@ namespace Icarus.Controllers.V1
Console.WriteLine("Here");
if (song.Id != 0)
{
return Ok(song);
}
else
{
return NotFound();
}
}
[Authorize("update:songs")]
[HttpPut("{id}")]
public IActionResult Put(int id, [FromBody] Song song)
{
SongRepository context = HttpContext
.RequestServices
SongRepository context = HttpContext.RequestServices
.GetService(typeof(SongRepository)) as SongRepository;
ArtistRepository artistStore = HttpContext
.RequestServices
ArtistRepository artistStore = HttpContext.RequestServices
.GetService(typeof(ArtistRepository)) as ArtistRepository;
AlbumRepository albumStore = HttpContext
.RequestServices
AlbumRepository albumStore = HttpContext.RequestServices
.GetService(typeof(AlbumRepository)) as AlbumRepository;
GenreRepository genreStore = HttpContext
.RequestServices
GenreRepository genreStore = HttpContext.RequestServices
.GetService(typeof(GenreRepository)) as GenreRepository;
YearRepository yearStore = HttpContext
.RequestServices
YearRepository yearStore = HttpContext.RequestServices
.GetService(typeof(YearRepository)) as YearRepository;
song.Id = id;
@@ -117,12 +102,10 @@ namespace Icarus.Controllers.V1
_logger.LogInformation("Retrieving filepath of song");
if (!context.DoesSongExist(song))
{
return NotFound(new SongResult
{
Message = "Song does not exist"
});
}
var songRes = _songMgr.UpdateSong(song, context, albumStore, artistStore, genreStore,
yearStore);
+47 -42
View File
@@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging;
using Icarus.Controllers.Managers;
using Icarus.Models;
using Icarus.Database.Contexts;
using Icarus.Database.Repositories;
namespace Icarus.Controllers.V1
@@ -22,6 +23,12 @@ namespace Icarus.Controllers.V1
public class SongDataController : ControllerBase
{
#region Fields
private SongRepository _songRepository;
private AlbumRepository _albumRepository;
private ArtistRepository _artistRepository;
private GenreRepository _genreRepository;
private YearRepository _yearRepository;
private CoverArtRepository _coverArtRepository;
private IConfiguration _config;
private ILogger<SongDataController> _logger;
private SongManager _songMgr;
@@ -43,16 +50,42 @@ namespace Icarus.Controllers.V1
}
#endregion
private void Initialize()
{
_songRepository = HttpContext
.RequestServices
.GetService
(typeof(SongRepository)) as SongRepository;
_albumRepository = HttpContext
.RequestServices
.GetService(typeof(AlbumRepository)) as AlbumRepository;
_artistRepository = HttpContext
.RequestServices
.GetService(typeof(ArtistRepository)) as ArtistRepository;
_genreRepository = HttpContext
.RequestServices
.GetService(typeof(GenreRepository)) as GenreRepository;
_yearRepository = HttpContext
.RequestServices
.GetService(typeof(YearRepository)) as YearRepository;
_coverArtRepository = HttpContext
.RequestServices
.GetService(typeof(CoverArtRepository)) as CoverArtRepository;
}
[HttpGet("{id}")]
[Route("private-scoped")]
[Authorize("download:songs")]
public async Task<IActionResult> Get(int id)
{
SongRepository context = HttpContext
.RequestServices
.GetService(typeof(SongRepository)) as SongRepository;
var songMetaData = context.GetSong(id);
Initialize();
var songMetaData = _songRepository.GetSong(id);
SongData song = await _songMgr.RetrieveSong(songMetaData);
@@ -65,21 +98,7 @@ namespace Icarus.Controllers.V1
{
try
{
SongRepository songRepository = HttpContext
.RequestServices
.GetService(typeof(SongRepository)) as SongRepository;
AlbumRepository albumStoreContext = HttpContext
.RequestServices
.GetService(typeof(AlbumRepository)) as AlbumRepository;
ArtistRepository artistStoreContext = HttpContext
.RequestServices
.GetService(typeof(ArtistRepository)) as ArtistRepository;
GenreRepository genreStore = HttpContext
.RequestServices
.GetService(typeof(GenreRepository)) as GenreRepository;
YearRepository yearStore = HttpContext
.RequestServices
.GetService(typeof(YearRepository)) as YearRepository;
Initialize();
Console.WriteLine("Uploading song...");
_logger.LogInformation("Uploading song...");
@@ -88,15 +107,13 @@ namespace Icarus.Controllers.V1
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}");
await _songMgr.SaveSongToFileSystem(sng, songRepository,
albumStoreContext, artistStoreContext,
genreStore, yearStore);
}
await _songMgr.SaveSongToFileSystem(sng, _songRepository,
_albumRepository, _artistRepository,
_genreRepository, _yearRepository, _coverArtRepository);
}
}
catch (Exception ex)
@@ -110,25 +127,11 @@ namespace Icarus.Controllers.V1
[Authorize("delete:songs")]
public IActionResult Delete(int id)
{
SongRepository context = HttpContext
.RequestServices
.GetService(typeof(SongRepository)) as SongRepository;
AlbumRepository albumStore = HttpContext
.RequestServices
.GetService(typeof(AlbumRepository)) as AlbumRepository;
ArtistRepository artistStore = HttpContext
.RequestServices
.GetService(typeof(ArtistRepository)) as ArtistRepository;
GenreRepository genreStore = HttpContext
.RequestServices
.GetService(typeof(GenreRepository)) as GenreRepository;
YearRepository yearStore = HttpContext
.RequestServices
.GetService(typeof(YearRepository)) as YearRepository;
Initialize();
var songMetaData = new Song{ Id = id };
Console.WriteLine($"Id {songMetaData.Id}");
songMetaData = context.GetSong(songMetaData);
songMetaData = _songRepository.GetSong(songMetaData);
if (string.IsNullOrEmpty(songMetaData.Title))
{
@@ -139,8 +142,10 @@ namespace Icarus.Controllers.V1
{
_logger.LogInformation("Starting process of deleting song from the filesystem and database");
_songMgr.DeleteSong(songMetaData, context, albumStore,
artistStore, genreStore, yearStore);
_songMgr.DeleteSong(songMetaData, _songRepository,
_albumRepository, _artistRepository,
_genreRepository, _yearRepository,
_coverArtRepository);
return Ok();
}
+1 -4
View File
@@ -42,8 +42,7 @@ namespace Icarus.Controllers.V1
[Authorize("stream:songs")]
public async Task<IActionResult> Get(int id)
{
var songStore= HttpContext
.RequestServices
var songStore= HttpContext.RequestServices
.GetService(typeof(SongRepository)) as SongRepository;
var song = songStore.GetSong(new Song { Id = id });
@@ -51,9 +50,7 @@ namespace Icarus.Controllers.V1
var mem = new MemoryStream();
using (var stream = new FileStream(song.SongPath, FileMode.Open, FileAccess.Read))
{
await stream.CopyToAsync(mem);
}
mem.Position = 0;
+2 -10
View File
@@ -39,21 +39,16 @@ namespace Icarus.Controller.V1
{
var yearValues = new List<Year>();
var yearStore = HttpContext
.RequestServices
var yearStore = HttpContext.RequestServices
.GetService(typeof(YearRepository)) as YearRepository;
yearValues = yearStore.GetSongYears();
if (yearValues.Count > 0)
{
return Ok(yearValues);
}
else
{
return NotFound(new List<Year>());
}
}
[HttpGet("{id}")]
[Authorize("read:year")]
@@ -64,8 +59,7 @@ namespace Icarus.Controller.V1
YearId = id
};
var yearStore = HttpContext
.RequestServices
var yearStore = HttpContext.RequestServices
.GetService(typeof(YearRepository)) as YearRepository;
if (yearStore.DoesYearExist(year))
@@ -75,10 +69,8 @@ namespace Icarus.Controller.V1
return Ok(year);
}
else
{
return NotFound(new Year());
}
}
#endregion
}
}
+1 -3
View File
@@ -14,9 +14,7 @@ namespace Icarus.Database.Contexts
{
public DbSet<Album> Albums { get; set; }
public AlbumContext(DbContextOptions<AlbumContext> options)
: base(options)
{ }
public AlbumContext(DbContextOptions<AlbumContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
+1 -3
View File
@@ -14,9 +14,7 @@ namespace Icarus.Database.Contexts
{
public DbSet<Artist> Artists { get; set; }
public ArtistContext(DbContextOptions<ArtistContext> options)
: base (options)
{ }
public ArtistContext(DbContextOptions<ArtistContext> options) : base (options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
+25
View File
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using MySql.Data;
using MySql.Data.EntityFrameworkCore.Extensions;
using MySql.Data.MySqlClient;
using Icarus.Models;
namespace Icarus.Database.Contexts
{
public class CoverArtContext : DbContext
{
public DbSet<CoverArt> CoverArtImages { get; set; }
public CoverArtContext(DbContextOptions<CoverArtContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CoverArt>()
.ToTable("CoverArt");
}
}
}
+1 -4
View File
@@ -13,10 +13,7 @@ namespace Icarus.Database.Contexts
public class GenreContext : DbContext
{
public DbSet<Genre> Genres { get; set; }
public GenreContext(DbContextOptions<GenreContext> options)
: base(options)
{ }
public GenreContext(DbContextOptions<GenreContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
+10 -3
View File
@@ -15,9 +15,7 @@ namespace Icarus.Database.Contexts
public DbSet<Song> Songs { get; set; }
public SongContext(DbContextOptions<SongContext> options)
: base(options)
{ }
public SongContext(DbContextOptions<SongContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@@ -48,6 +46,12 @@ namespace Icarus.Database.Contexts
.HasForeignKey(s => s.YearId)
.OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity<Song>()
.HasOne(s => s.SongCoverArt)
.WithMany(ca => ca.Songs)
.HasForeignKey(s => s.CoverArtId)
.OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity<Song>()
.Property(s => s.Year)
.IsRequired(false);
@@ -63,6 +67,9 @@ namespace Icarus.Database.Contexts
modelBuilder.Entity<Song>()
.Property(s => s.AlbumId)
.IsRequired(false);
modelBuilder.Entity<Song>()
.Property(s => s.CoverArtId)
.IsRequired(false);
}
}
}
+1 -3
View File
@@ -15,9 +15,7 @@ namespace Icarus.Database.Contexts
public DbSet<User> Users { get; set; }
public UserContext(DbContextOptions<UserContext> options)
: base(options)
{ }
public UserContext(DbContextOptions<UserContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
+1 -3
View File
@@ -14,9 +14,7 @@ namespace Icarus.Database.Contexts
{
public DbSet<Year> YearValues { get; set; }
public YearContext(DbContextOptions<YearContext> options)
: base(options)
{ }
public YearContext(DbContextOptions<YearContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
-26
View File
@@ -32,7 +32,6 @@ namespace Icarus.Database.Repositories
var albums = new List<Album>();
if (AnyAlbums())
{
try
{
using (MySqlConnection conn = GetConnection())
@@ -40,20 +39,15 @@ namespace Icarus.Database.Repositories
conn.Open();
var query = "SELECT * FROM Album";
using (MySqlCommand cmd = new MySqlCommand(query, conn))
{
using (var reader = cmd.ExecuteReader())
{
albums = ParseData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred");
}
}
return albums;
}
@@ -70,14 +64,10 @@ namespace Icarus.Database.Repositories
"LEFT JOIN Song sng ON alb.AlbumId=sng.AlbumId WHERE " +
"alb.AlbumId=sng.AlbumId GROUP BY alb.AlbumId";
using (MySqlCommand cmd = new MySqlCommand(query, conn))
{
using (var reader = cmd.ExecuteReader())
{
albums = ParseData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -103,12 +93,10 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@AlbumId", album.AlbumId);
using (var reader = cmd.ExecuteReader())
{
album = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -135,12 +123,10 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@Title", song.AlbumTitle);
using (var reader = cmd.ExecuteReader())
{
album = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -160,28 +146,22 @@ namespace Icarus.Database.Repositories
conn.Open();
var query = string.Empty;
if (retrieveCount)
{
query = "SELECT alb.*, COUNT(*) AS SongCount FROM Album alb " +
"LEFT JOIN Song sng ON alb.AlbumId=sng.AlbumId WHERE " +
"alb.Title=@Title GROUP BY alb.AlbumId LIMIT 1";
}
else
{
query = "SELECT alb.*, 0 AS SongCount FROM Album alb WHERE " +
"alb.Title=@Title LIMIT 1";
}
using (MySqlCommand cmd = new MySqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("@Title", song.AlbumTitle);
using (var reader = cmd.ExecuteReader())
{
album = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -391,18 +371,12 @@ namespace Icarus.Database.Repositories
var query = "SELECT * FROM Album";
using (var cmd = new MySqlCommand(query, conn))
{
using (var reader = cmd.ExecuteReader())
{
albums = ParseData(reader);
}
}
}
if (albums.Count > 0)
{
return true;
}
return false;
}
-15
View File
@@ -42,15 +42,10 @@ namespace Icarus.Database.Repositories
"GROUP BY art.ArtistId";
using (MySqlCommand cmd = new MySqlCommand(query, conn))
{
using (var reader = cmd.ExecuteReader())
{
artists = ParseData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -78,12 +73,10 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@ArtistId", artist.ArtistId);
using (var reader = cmd.ExecuteReader())
{
artist = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -109,12 +102,10 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@Name", song.Artist);
using (var reader = cmd.ExecuteReader())
{
artist = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -137,28 +128,22 @@ namespace Icarus.Database.Repositories
var query = string.Empty;
if (retrieveCount)
{
query = "SELECT art.*, COUNT(*) AS SongCount FROM Artist " +
"art LEFT JOIN Song sng ON art.ArtistId=sng.ArtistId " +
"WHERE art.Name=@Name GROUP BY art.ArtistId LIMIT 1";
}
else
{
query = "SELECT art.*, 0 AS SongCount FROM Artist art " +
"WHERE art.Name=@Name LIMIT 1";
}
using (MySqlCommand cmd = new MySqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("@Name", song.Artist);
using (var reader = cmd.ExecuteReader())
{
artist = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
+255
View File
@@ -0,0 +1,255 @@
using System;
using System.Collections.Generic;
using MySql.Data.MySqlClient;
using Icarus.Models;
using Icarus.Types;
namespace Icarus.Database.Repositories
{
public class CoverArtRepository : BaseRepository
{
#region Constructors
public CoverArtRepository(string connectionString)
{
_connectionString = connectionString;
}
#endregion
#region Methods
public CoverArt GetCoverArt(CoverArt cover)
{
try
{
using (var conn = GetConnection())
{
conn.Open();
_logger.Info("Querying cover art record");
var query = "SELECT * FROM CoverArt WHERE " +
"CoverArtId=@CoverArtId";
using (var cmd = new MySqlCommand(query, conn))
{
cmd.Parameters
.AddWithValue("@CoverArtId", cover.CoverArtId);
using (var reader = cmd.ExecuteReader())
return ParseSingleData(reader);
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred");
}
return null;
}
public CoverArt GetCoverArt(Song song)
{
try
{
using (var conn = GetConnection())
{
conn.Open();
_logger.Info("Querying cover art record");
var query = "SELECT cov.* FROM CoverArt cov LEFT JOIN " +
"Song sng ON cov.CoverArtId=sng.CoverArtId WHERE " +
"sng.Id=@SongId";
using (var cmd = new MySqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("@SongId", song.Id);
using (var reader = cmd.ExecuteReader())
return ParseSingleData(reader);
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred");
}
return null;
}
public CoverArt GetCoverArt(CoverArtField field, CoverArt cover)
{
try
{
using (var conn = GetConnection())
{
conn.Open();
_logger.Info("Querying cover art record");
using (var cmd = new MySqlCommand(BuildQuery(field), conn))
{
switch (field)
{
case CoverArtField.SongTitle:
cmd.Parameters.AddWithValue("@SongTitle",
cover.SongTitle);
break;
case CoverArtField.ImagePath:
cmd.Parameters.AddWithValue("@ImagePath",
cover.ImagePath);
break;
}
using (var reader = cmd.ExecuteReader())
return ParseSingleData(reader);
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred");
}
return null;
}
public bool DoesCoverArtExist(CoverArt cover)
{
return GetCoverArt(cover) != null ? true : false;
}
public bool DoesCoverArtExist(Song song)
{
return GetCoverArt(song) != null ? true : false;
}
public void SaveCoverArt(CoverArt coverArt)
{
try
{
using (var conn = GetConnection())
{
conn.Open();
_logger.Info("Saving cover art record");
var query = "INSERT INTO CoverArt(SongTitle, ImagePath) " +
"VALUES(@SongTitle, @ImagePath)";
using (var cmd = new MySqlCommand(query, conn))
{
cmd.Parameters
.AddWithValue("@SongTitle", coverArt.SongTitle);
cmd.Parameters
.AddWithValue("@ImagePath", coverArt.ImagePath);
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred");
}
}
public void DeleteCoverArt(CoverArt cover)
{
try
{
using (var conn = GetConnection())
{
conn.Open();
_logger.Info("Deleting cover art record");
var query = "DELETE FROM CoverArt WHERE " +
"CoverArtId=@CoverArtId";
using (var cmd = new MySqlCommand(query, conn))
{
cmd.Parameters
.AddWithValue("@CoverArtId", cover.CoverArtId);
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
_logger.Error(msg, "An error occurred");
}
}
private List<CoverArt> ParseData(MySqlDataReader reader)
{
if (reader.HasRows)
{
var coverArtList = new List<CoverArt>();
_logger.Info("Parsing cover art records");
while (reader.Read())
coverArtList.Add(new CoverArt
{
CoverArtId = Convert.ToInt32(reader["CoverArtId"]),
SongTitle = reader["SongTitle"].ToString(),
ImagePath = reader["ImagePath"].ToString()
});
return coverArtList;
}
return null;
}
private CoverArt ParseSingleData(MySqlDataReader reader)
{
if (reader.HasRows)
{
_logger.Info("Parsing single cover art record");
reader.Read();
return new CoverArt
{
CoverArtId = Convert.ToInt32(reader["CoverArtId"]),
SongTitle = reader["SongTitle"].ToString(),
ImagePath = reader["ImagePath"].ToString()
};
}
return null;
}
private string BuildQuery(CoverArtField field)
{
switch (field)
{
case CoverArtField.SongTitle:
return "SELECT * FROM CoverArt WHERE SongTitle=@SongTitle";
case CoverArtField.ImagePath:
return "SELECT * FROM CoverArt WHERE ImagePath=" +
"@ImagePath";
}
return null;
}
private bool? AnyCoverArt()
{
using (var conn = GetConnection())
{
conn.Open();
_logger.Info("Checking to see if there are any cover art " +
"records");
var query = "SELECT * FROM CoverArt";
using (var cmd = new MySqlCommand(query, conn))
using (var reader = cmd.ExecuteReader())
return reader.HasRows;
}
}
#endregion
}
}
-22
View File
@@ -45,14 +45,10 @@ namespace Icarus.Database.Repositories
var query = "SELECT * FROM Genre";
using (var cmd = new MySqlCommand(query, conn))
{
using (var reader = cmd.ExecuteReader())
{
genres = ParseData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -82,14 +78,10 @@ namespace Icarus.Database.Repositories
"GROUP BY gnr.GenreId";
using (var cmd = new MySqlCommand(query, conn))
{
using (var reader = cmd.ExecuteReader())
{
genres = ParseData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -121,12 +113,10 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@GenreId", genre.GenreId);
using (var reader = cmd.ExecuteReader())
{
genre = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -159,12 +149,10 @@ namespace Icarus.Database.Repositories
_logger.Info($"Song genre:\n\n\n {song.Genre}");
using (var reader = cmd.ExecuteReader())
{
genre = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -191,17 +179,13 @@ namespace Icarus.Database.Repositories
var query = string.Empty;
if (retrieveCount)
{
query = "SELECT gnr.*, COUNT(*) AS SongCount FROM Genre gnr " +
"LEFT JOIN Song sng ON gnr.GenreId=sng.GenreId " +
"WHERE gnr.GenreName=@GenreName GROUP BY gnr.GenreId " +
"LIMIT 1";
}
else
{
query = "SELECT gnr.*, 0 AS SongCount FROM Genre gnr " +
"WHERE gnr.GenreName=@GenreName LIMIT 1";
}
using (var cmd = new MySqlCommand(query, conn))
{
@@ -209,12 +193,10 @@ namespace Icarus.Database.Repositories
_logger.Info($"Song genre:\n\n\n {song.Genre}");
using (var reader = cmd.ExecuteReader())
{
genre = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -446,14 +428,10 @@ namespace Icarus.Database.Repositories
var query = "SELECT * FROM Genre";
using (var cmd = new MySqlCommand(query, conn))
{
using (var reader = cmd.ExecuteReader())
{
return reader.HasRows;
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
+8 -10
View File
@@ -36,9 +36,10 @@ namespace Icarus.Database.Repositories
conn.Open();
string query = "INSERT INTO Song(Title, AlbumTitle, Artist," +
" Year, Genre, Duration, Filename, SongPath, AlbumId, " +
"ArtistId, GenreId, YearId) VALUES(@Title, @AlbumTitle, " +
"@Artist, @Year, @Genre, @Duration, @Filename, @SongPath, " +
"@AlbumId, @ArtistId, @GenreId, @YearId)";
"ArtistId, GenreId, YearId, CoverArtId) VALUES(@Title," +
" @AlbumTitle, @Artist, @Year, @Genre, @Duration, " +
"@Filename, @SongPath, @AlbumId, @ArtistId, @GenreId," +
" @YearId, @CoverArtId)";
using (MySqlCommand cmd = new MySqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("@Title", song.Title);
@@ -53,6 +54,7 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@ArtistId", song.ArtistId);
cmd.Parameters.AddWithValue("@GenreId", song.GenreId);
cmd.Parameters.AddWithValue("@YearId", song.YearId);
cmd.Parameters.AddWithValue("@CoverArtId", song.CoverArtId);
cmd.ExecuteNonQuery();
}
@@ -175,11 +177,9 @@ namespace Icarus.Database.Repositories
Console.WriteLine("ffff");
MySqlCommand cmd = new MySqlCommand(query, conn);
using (var reader = cmd.ExecuteReader())
{
songs = ParseData(reader);
}
}
}
catch (Exception ex)
{
var exMsg = ex.Message;
@@ -207,12 +207,10 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@Id", song.Id);
using (var reader = cmd.ExecuteReader())
{
song = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -237,10 +235,8 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@Id", id);
using (var reader = cmd.ExecuteReader())
{
song = ParseSingleData(reader);
}
}
_logger.Info("Song found");
}
catch(Exception ex)
@@ -290,7 +286,8 @@ namespace Icarus.Database.Repositories
AlbumId = Convert.ToInt32(reader["AlbumId"].ToString()),
ArtistId = Convert.ToInt32(reader["ArtistId"].ToString()),
GenreId = Convert.ToInt32(reader["GenreId"].ToString()),
YearId = Convert.ToInt32(reader["YearId"].ToString())
YearId = Convert.ToInt32(reader["YearId"].ToString()),
CoverArtId = Convert.ToInt32(reader["CoverArtId"].ToString())
});
}
@@ -316,6 +313,7 @@ namespace Icarus.Database.Repositories
song.ArtistId = Convert.ToInt32(reader["ArtistId"].ToString());
song.GenreId = Convert.ToInt32(reader["GenreId"].ToString());
song.YearId = Convert.ToInt32(reader["YearId"].ToString());
song.CoverArtId = Convert.ToInt32(reader["CoverArtId"].ToString());
}
return song;
-2
View File
@@ -83,11 +83,9 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@Username", user.Username);
using (var reader = cmd.ExecuteReader())
{
user = ParseSingleData(reader);
}
}
}
_logger.Info("Successfully retrieved user");
-14
View File
@@ -44,14 +44,10 @@ namespace Icarus.Database.Repositories
"GROUP BY yr.YearId";
using (var cmd = new MySqlCommand(query, conn))
{
using (var reader = cmd.ExecuteReader())
{
yearValues = ParseData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -80,12 +76,10 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@YearId", year.YearId);
using (var reader = cmd.ExecuteReader())
{
year = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -114,12 +108,10 @@ namespace Icarus.Database.Repositories
cmd.Parameters.AddWithValue("@YearValue", song.Year);
using (var reader = cmd.ExecuteReader())
{
year = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
@@ -143,28 +135,22 @@ namespace Icarus.Database.Repositories
var query = string.Empty;
if (retrieveCount)
{
query = "SELECT yr.*, COUNT(*) AS SongCount FROM Year yr " +
"LEFT JOIN Song sng ON yr.YearValue=sng.Year WHERE " +
"yr.YearValue=@YearValue GROUP BY yr.YearId LIMIT 1";
}
else
{
query = "SELECT yr.*, 0 AS SongCount FROM Year yr " +
"WHERE yr.YearValue=@YearValue LIMIT 1";
}
using(var cmd = new MySqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("@YearValue", song.Year);
using (var reader = cmd.ExecuteReader())
{
year = ParseSingleData(reader);
}
}
}
}
catch (Exception ex)
{
var msg = ex.Message;
+1
View File
@@ -30,6 +30,7 @@
</ItemGroup>
<ItemGroup>
<Content Update="nlog.config" CopyToOutputDirectory="PreserveNewest" />
<Content Include="Images/Stock/*.*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Project>
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+21
View File
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
namespace Icarus.Models
{
public class CoverArt
{
[JsonProperty("id")]
public int CoverArtId { get; set; }
[JsonProperty("title")]
public string SongTitle { get; set; }
[JsonIgnore]
public string ImagePath { get; set; }
[JsonIgnore]
public List<Song> Songs { get; set; }
}
}
+5
View File
@@ -45,5 +45,10 @@ namespace Icarus.Models
public Year SongYear { get; set; }
[JsonIgnore]
public int? YearId { get; set; }
[JsonIgnore]
public CoverArt SongCoverArt { get; set; }
[JsonIgnore]
public int? CoverArtId { get; set; }
}
}
+2 -3
View File
@@ -35,14 +35,13 @@ namespace Icarus
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
WebHost.CreateDefaultBuilder(args).UseStartup<Startup>()
.UseUrls("http://localhost:5002")
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
})
.UseNLog() ;
.UseNLog();
}
}
+1 -1
View File
@@ -150,7 +150,7 @@ Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the code of conduc
## Versioning
Currently under development. No version has been released
* [v0.1](https://github.com/amazing-username/Icarus/releases/tag/v0.1)
## Authors
+3
View File
@@ -11,6 +11,8 @@ echo "Adding Genre migration"
dotnet ef migrations add Genre --context GenreContext
echo "Adding Year migration"
dotnet ef migrations add Year --context YearContext
echo "Adding Cover art migration"
dotnet ef migrations add CoverArt --context CoverArtContext
echo "Updating migrations.."
echo "Updating User migration"
@@ -20,4 +22,5 @@ echo "Updating Album migration"
echo "Updating Artist migration"
echo "Updating Genre migration"
echo "Updating Year migration"
echo "Updating Cover art migration"
dotnet ef database update --context SongContext
+6 -3
View File
@@ -1,3 +1,6 @@
delete from Song where Id>0;
delete from Album where AlbumId>0;
delete from Artist where ArtistId>0;
delete from Song;
delete from Album;
delete from Artist;
delete from Genre;
delete from Year;
delete from CoverArt;
+27 -38
View File
@@ -59,53 +59,47 @@ namespace Icarus
services.AddAuthorization(options =>
{
options.AddPolicy("download:songs", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("download:songs", domain)));
options.AddPolicy("download:cover_art", policy =>
policy.Requirements
.Add(new HasScopeRequirement("download:cover_art", domain)));
options.AddPolicy("upload:songs", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("upload:songs", domain)));
options.AddPolicy("delete:songs", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("delete:songs", domain)));
options.AddPolicy("read:song_details", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("read:song_details", domain)));
options.AddPolicy("update:songs", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("update:songs", domain)));
options.AddPolicy("read:artists", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("read:artists", domain)));
options.AddPolicy("read:albums", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("read:albums", domain)));
options.AddPolicy("read:genre", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("read:genre", domain)));
options.AddPolicy("read:year", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("read:year", domain)));
options.AddPolicy("stream:songs", policy =>
policy
.Requirements
policy.Requirements
.Add(new HasScopeRequirement("stream:songs", domain)));
});
@@ -115,28 +109,25 @@ namespace Icarus
var connString = Configuration.GetConnectionString("DefaultConnection");
services.Add(new ServiceDescriptor(typeof(SongRepository),
new SongRepository(Configuration
.GetConnectionString("DefaultConnection"))));
new SongRepository(Configuration.GetConnectionString("DefaultConnection"))));
services.Add(new ServiceDescriptor(typeof(AlbumRepository),
new AlbumRepository(Configuration
.GetConnectionString("DefaultConnection"))));
new AlbumRepository(Configuration.GetConnectionString("DefaultConnection"))));
services.Add(new ServiceDescriptor(typeof(ArtistRepository),
new ArtistRepository(Configuration
.GetConnectionString("DefaultConnection"))));
new ArtistRepository(Configuration.GetConnectionString("DefaultConnection"))));
services.Add(new ServiceDescriptor(typeof(GenreRepository),
new GenreRepository(Configuration
.GetConnectionString("DefaultConnection"))));
new GenreRepository(Configuration.GetConnectionString("DefaultConnection"))));
services.Add(new ServiceDescriptor(typeof(YearRepository),
new YearRepository(Configuration
.GetConnectionString("DefaultConnection"))));
new YearRepository(Configuration.GetConnectionString("DefaultConnection"))));
services.Add(new ServiceDescriptor(typeof(CoverArtRepository),
new CoverArtRepository(Configuration.GetConnectionString("DefaultConnection"))));
services.Add(new ServiceDescriptor(typeof(UserRepository),
new UserRepository(Configuration
.GetConnectionString("DefaultConnection"))));
new UserRepository(Configuration.GetConnectionString("DefaultConnection"))));
services.AddDbContext<SongContext>(options => options.UseMySQL(connString));
services.AddDbContext<AlbumContext>(options => options.UseMySQL(connString));
@@ -144,20 +135,18 @@ namespace Icarus
services.AddDbContext<UserContext>(options => options.UseMySQL(connString));
services.AddDbContext<GenreContext>(options => options.UseMySQL(connString));
services.AddDbContext<YearContext>(options => options.UseMySQL(connString));
services.AddDbContext<CoverArtContext>(options => options.UseMySQL(connString));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
// Called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
// The default HSTS value is 30 days.
// You may want to change this for production scenarios
app.UseHsts();
}
app.UseAuthentication();
+10
View File
@@ -0,0 +1,10 @@
using System;
namespace Icarus.Types
{
public enum CoverArtField
{
SongTitle = 0,
ImagePath
};
}
+10
View File
@@ -0,0 +1,10 @@
using System;
namespace Icarus.Types
{
public enum DirectoryType
{
Music = 0,
CoverArt
};
}
+4 -3
View File
@@ -9,13 +9,14 @@
"Auth0": {
"Domain": "[domain].auth0.com",
"ApiIdentifier": "https://[identifier]/api",
"ClientId":"",
"ClientSecret":""
"ClientId": "",
"ClientSecret": ""
},
"ConnectionStrings": {
"DefaultConnection": "Server=;Database=;Uid=;Pwd=;"
},
"RootMusicPath": "/music/path/",
"TemporaryMusicPath": "/music/temp/path/",
"ArchivePath": "/archive/path/"
"ArchivePath": "/archive/path/",
"CoverArtPath": "/cover/art/path/"
}
+4 -3
View File
@@ -9,13 +9,14 @@
"Auth0": {
"Domain": "[domain].auth0.com",
"ApiIdentifier": "https://[identifier]/api",
"ClientId":"",
"ClientSecret":""
"ClientId": "",
"ClientSecret": ""
},
"ConnectionStrings": {
"DefaultConnection": "Server=;Database=;Uid=;Pwd=;"
},
"RootMusicPath": "/music/path/",
"TemporaryMusicPath": "/music/temp/path/",
"ArchivePath": "/archive/path/"
"ArchivePath": "/archive/path/",
"CoverArtPath": "/cover/art/path/"
}