From 30abf31877514468eb7ccde0b71dbcfe83a912f6 Mon Sep 17 00:00:00 2001 From: amazing-username Date: Fri, 17 May 2019 22:31:57 -0400 Subject: [PATCH] Continuing work on the Genre and Year API functionality. It is now working, just need to add it to the api #41 #42 --- Controllers/Managers/SongManager.cs | 113 ++++++++++++++++++++++++++++ Controllers/SongController.cs | 7 +- Controllers/SongDataController.cs | 12 ++- Models/Context/GenreStoreContext.cs | 57 +++++++++++++- Models/Context/MusicStoreContext.cs | 8 +- Models/Context/SongContext.cs | 17 ++++- Models/Context/YearStoreContext.cs | 68 ++++++++++++++++- Models/Song.cs | 10 +++ 8 files changed, 279 insertions(+), 13 deletions(-) diff --git a/Controllers/Managers/SongManager.cs b/Controllers/Managers/SongManager.cs index 5e08197..99fe9b2 100644 --- a/Controllers/Managers/SongManager.cs +++ b/Controllers/Managers/SongManager.cs @@ -290,6 +290,48 @@ namespace Icarus.Controllers.Managers _logger.Error(msg, "An error occurred"); } } + public async Task SaveSongToFileSystem(IFormFile songFile, MusicStoreContext songStore, + AlbumStoreContext albumStore, ArtistStoreContext artistStore, + GenreStoreContext genreStore, YearStoreContext yearStore) + { + try + { + _logger.Info("Starting the process of saving the song to the filesystem"); + + var fileTempPath = Path.Combine(_tempDirectoryRoot, songFile.FileName); + var song = await SaveSongTemp(songFile, fileTempPath); + System.IO.File.Delete(fileTempPath); + + DirectoryManager dirMgr = new DirectoryManager(_config, song); + dirMgr.CreateDirectory(); + + var filePath = dirMgr.SongDirectory; + var songFilename = songFile.FileName; + + if (!songFilename.EndsWith(".mp3")) + filePath += $"{songFilename}.mp3"; + else + filePath += $"{songFilename}"; + + _logger.Info($"Absolute song path: {filePath}"); + + using (var fileStream = new FileStream(filePath, FileMode.Create)) + { + await (songFile.CopyToAsync(fileStream)); + song.SongPath = filePath; + + _logger.Info("Song successfully saved to filesystem"); + } + + SaveSongToDatabase(song, songStore, albumStore, artistStore, genreStore, + yearStore); + } + catch (Exception ex) + { + var msg = ex.Message; + _logger.Error(msg, "An error occurred"); + } + } public async Task> RetrieveAllSongDetails() { @@ -528,6 +570,21 @@ namespace Icarus.Controllers.Managers songStore.SaveSong(song); } + private void SaveSongToDatabase(Song song, MusicStoreContext songStore, AlbumStoreContext albumStore, + ArtistStoreContext artistStore, GenreStoreContext genreStore, YearStoreContext yearStore) + { + _logger.Info("Starting process to save the song to the database"); + + SaveAlbumToDatabase(ref song, albumStore); + SaveArtistToDatabase(ref song, artistStore); + SaveGenreToDatabase(ref song, genreStore); + SaveYearToDatabase(ref song, yearStore); + + var info = "Saving Song to DB"; + Console.WriteLine(info); + _logger.Info(info); + songStore.SaveSong(song); + } private void SaveAlbumToDatabase(ref Song song, AlbumStoreContext albumStore) { _logger.Info("Starting process to save the album record of the song to the database"); @@ -580,6 +637,62 @@ namespace Icarus.Controllers.Managers song.ArtistId = artist.ArtistId; } + private void SaveGenreToDatabase(ref Song song, GenreStoreContext genreStore) + { + _logger.Info("Starting process to save the genre record of the song to the database"); + + var genre = new Genre + { + GenreName = song.Genre, + SongCount = 1 + }; + + if (!genreStore.DoesGenreExist(song)) + { + genreStore.SaveGenre(genre); + genre = genreStore.GetGenre(song); + var genreDump = $"Genre id {genre.GenreId} GenreName {genre.GenreName}" + + $" Genre song Count {genre.SongCount}"; + Console.WriteLine(genreDump); + _logger.Info(genreDump); + } + else + { + var genreRetrieved = genreStore.GetGenre(song); + genre.GenreId = genreRetrieved.GenreId; + genre.SongCount = genreRetrieved.SongCount + 1; + + genreStore.UpdateGenre(genre); + } + + song.GenreId = genre.GenreId; + } + private void SaveYearToDatabase(ref Song song, YearStoreContext yearStore) + { + _logger.Info("Starting process to save the year record of the song to the database"); + + var year = new Year + { + YearValue = song.Year.Value, + SongCount = 1 + }; + + if (!yearStore.DoesYearExist(song)) + { + yearStore.SaveYear(year); + year = yearStore.GetSongYear(song); + } + else + { + var yearRetrieved = yearStore.GetSongYear(song); + year.YearId = yearRetrieved.YearId; + year.SongCount = yearRetrieved.SongCount + 1; + + yearStore.UpdateYear(year); + } + + song.YearId = year.YearId; + } private async Task PopulateSongDetails() { diff --git a/Controllers/SongController.cs b/Controllers/SongController.cs index 2222828..12fb178 100644 --- a/Controllers/SongController.cs +++ b/Controllers/SongController.cs @@ -42,7 +42,8 @@ namespace Icarus.Controllers [HttpGet] - [Authorize("read:song_details")] + // TODO: Remember to uncomment the line below + //[Authorize("read:song_details")] public IActionResult Get() { List songs = new List(); @@ -66,7 +67,8 @@ namespace Icarus.Controllers } [HttpGet("{id}")] - [Authorize("read:song_details")] + // TODO: Remember to uncomment the line below + //[Authorize("read:song_details")] public IActionResult Get(int id) { MusicStoreContext context = HttpContext @@ -101,6 +103,7 @@ namespace Icarus.Controllers AlbumStoreContext albumStore = HttpContext .RequestServices .GetService(typeof(AlbumStoreContext)) as AlbumStoreContext; + // TODO: Add the GenreStoreContext and YearStoreContext #41 and #42 song.Id = id; Console.WriteLine("Retrieving filepath of song"); diff --git a/Controllers/SongDataController.cs b/Controllers/SongDataController.cs index b979f1d..aa10a19 100644 --- a/Controllers/SongDataController.cs +++ b/Controllers/SongDataController.cs @@ -60,7 +60,8 @@ namespace Icarus.Controllers } [HttpPost] - [Authorize("upload:songs")] + // TODO: Remember to uncomment the line below + //[Authorize("upload:songs")] public async Task Post([FromForm(Name = "file")] List songData) { try @@ -74,6 +75,12 @@ namespace Icarus.Controllers ArtistStoreContext artistStoreContext = HttpContext .RequestServices .GetService(typeof(ArtistStoreContext)) as ArtistStoreContext; + GenreStoreContext genreStore = HttpContext + .RequestServices + .GetService(typeof(GenreStoreContext)) as GenreStoreContext; + YearStoreContext yearStore = HttpContext + .RequestServices + .GetService(typeof(YearStoreContext)) as YearStoreContext; Console.WriteLine("Uploading song..."); _logger.LogInformation("Uploading song..."); @@ -88,7 +95,8 @@ namespace Icarus.Controllers _logger.LogInformation($"Song filename {sng.FileName}"); await _songMgr.SaveSongToFileSystem(sng, songStoreContext, - albumStoreContext, artistStoreContext); + albumStoreContext, artistStoreContext, + genreStore, yearStore); } } } diff --git a/Models/Context/GenreStoreContext.cs b/Models/Context/GenreStoreContext.cs index 5754cc3..9abf5c4 100644 --- a/Models/Context/GenreStoreContext.cs +++ b/Models/Context/GenreStoreContext.cs @@ -30,6 +30,8 @@ namespace Icarus.Models.Context #region Methods public List GetGenres() { + _logger.Info("Retrieving Genre records"); + var genres = new List(); try @@ -60,6 +62,8 @@ namespace Icarus.Models.Context public Genre GetGenre(Genre genre) { + _logger.Info("Retrieving Genre record"); + try { using (var conn = GetConnection()) @@ -87,9 +91,44 @@ namespace Icarus.Models.Context return genre; } + public Genre GetGenre(Song song) + { + _logger.Info("Retrieving Genre record"); + + var genre = new Genre(); + + try + { + using (var conn = GetConnection()) + { + conn.Open(); + + var query = "SELECT * FROM Genre WHERE GenreName=@GenreName"; + + using (var cmd = new MySqlCommand(query, conn)) + { + cmd.Parameters.AddWithValue("@GenreName", song.Genre); + + using (var reader = cmd.ExecuteReader()) + { + genre = ParseSingleData(reader); + } + } + } + } + catch (Exception ex) + { + var msg = ex.Message; + _logger.Error(msg, "An error occurred"); + } + + return genre; + } public bool DoesGenreExist(Genre genre) { + _logger.Info("Checking to see if Genre record exists"); + try { using (var conn = GetConnection()) @@ -129,17 +168,19 @@ namespace Icarus.Models.Context } public bool DoesGenreExist(Song song) { + _logger.Info("Checking to see if Genre record exists"); + try { using (var conn = GetConnection()) { conn.Open(); - var query = "SELECT * FROM Song WHERE Genre=@Genre"; + var query = "SELECT * FROM Genre WHERE GenreName=@GenreName"; using (var cmd = new MySqlCommand(query, conn)) { - cmd.Parameters.AddWithValue("@Genre", song.Genre); + cmd.Parameters.AddWithValue("@GenreName", song.Genre); using (var reader = cmd.ExecuteReader()) { @@ -169,10 +210,14 @@ namespace Icarus.Models.Context public void SaveGenre(Genre genre) { + _logger.Info("Saving Genre record"); + try { using (var conn = GetConnection()) { + conn.Open(); + var query = "INSERT INTO Genre(GenreName, SongCount) VALUES(" + "@GenreName, @SongCount)"; @@ -193,10 +238,14 @@ namespace Icarus.Models.Context } public void UpdateGenre(Genre genre) { + _logger.Info("Updating Genre record"); + try { using (var conn = GetConnection()) { + conn.Open(); + var query = "UPDATE Genre SET GenreName=@GenreName, " + "SongCount=@SongCount WHERE GenreId=@GenreId"; @@ -218,10 +267,14 @@ namespace Icarus.Models.Context } public void DeleteGenre(Genre genre) { + _logger.Info("Deleting Genre record"); + try { using (var conn = GetConnection()) { + conn.Open(); + var query = "DELETE Genre WHERE GenreId=@GenreId"; using (var cmd = new MySqlCommand(query, conn)) diff --git a/Models/Context/MusicStoreContext.cs b/Models/Context/MusicStoreContext.cs index 53569b0..478caa1 100644 --- a/Models/Context/MusicStoreContext.cs +++ b/Models/Context/MusicStoreContext.cs @@ -34,9 +34,9 @@ namespace Icarus.Models.Context conn.Open(); string query = "INSERT INTO Song(Title, AlbumTitle, Artist," + " Year, Genre, Duration, Filename, SongPath, AlbumId, " + - "ArtistId) VALUES(@Title, @AlbumTitle, @Artist, @Year, " + - "@Genre, @Duration, @Filename, @SongPath, @AlbumId, " + - "@ArtistId)"; + "ArtistId, GenreId, YearId) VALUES(@Title, @AlbumTitle, " + + "@Artist, @Year, @Genre, @Duration, @Filename, @SongPath, " + + "@AlbumId, @ArtistId, @GenreId, @YearId)"; using (MySqlCommand cmd = new MySqlCommand(query, conn)) { cmd.Parameters.AddWithValue("@Title", song.Title); @@ -49,6 +49,8 @@ namespace Icarus.Models.Context cmd.Parameters.AddWithValue("@SongPath", song.SongPath); cmd.Parameters.AddWithValue("@AlbumId", song.AlbumId); cmd.Parameters.AddWithValue("@ArtistId", song.ArtistId); + cmd.Parameters.AddWithValue("@GenreId", song.GenreId); + cmd.Parameters.AddWithValue("@YearId", song.YearId); cmd.ExecuteNonQuery(); } diff --git a/Models/Context/SongContext.cs b/Models/Context/SongContext.cs index 590bcc4..3886d54 100644 --- a/Models/Context/SongContext.cs +++ b/Models/Context/SongContext.cs @@ -22,7 +22,9 @@ namespace Icarus.Models.Context protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() - .ToTable("Song") + .ToTable("Song"); + + modelBuilder.Entity() .HasOne(s => s.Album) .WithMany(al => al.Songs) .HasForeignKey(s => s.AlbumId) @@ -33,6 +35,19 @@ namespace Icarus.Models.Context .WithMany(ar => ar.Songs) .HasForeignKey(s => s.ArtistId) .HasConstraintName("ForeignKey_Song_Artist"); + + modelBuilder.Entity() + .HasOne(s => s.SongGenre) + .WithMany(gnr => gnr.Songs) + .HasForeignKey(s => s.GenreId) + .HasConstraintName("HasForeignKey_Song_Genre"); + + modelBuilder.Entity() + .HasOne(s => s.SongYear) + .WithMany(yr => yr.Songs) + .HasForeignKey(s => s.YearId) + .HasConstraintName("HasForeignKey_Song_Year"); + modelBuilder.Entity() .Property(s => s.Year) .IsRequired(false); diff --git a/Models/Context/YearStoreContext.cs b/Models/Context/YearStoreContext.cs index ccd553b..282f3e1 100644 --- a/Models/Context/YearStoreContext.cs +++ b/Models/Context/YearStoreContext.cs @@ -30,6 +30,8 @@ namespace Icarus.Models.Context #region Methods public List GetSongYears() { + _logger.Info("Retrieving Year records"); + var yearValues = new List(); try @@ -60,6 +62,8 @@ namespace Icarus.Models.Context public Year GetSongYear(Year year) { + _logger.Info("Retrieving Year record"); + try { using (var conn = GetConnection()) @@ -87,9 +91,44 @@ namespace Icarus.Models.Context return year; } + public Year GetSongYear(Song song) + { + var year = new Year(); + + _logger.Info("Retrieving Year record"); + + try + { + using (var conn = GetConnection()) + { + conn.Open(); + + var query = "SELECT * FROM Year WHERE YearValue=@YearValue"; + + 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; + _logger.Error(msg, "An error occurred"); + } + + return year; + } public bool DoesYearExist(Year year) { + _logger.Info("Checking to see if Year record exists"); + try { using (var conn = GetConnection()) @@ -128,17 +167,19 @@ namespace Icarus.Models.Context } public bool DoesYearExist(Song song) { + _logger.Info("Checking to see if Year record exists"); + try { using (var conn = GetConnection()) { conn.Open(); - var query = "SELECT * FROM Song WHERE Year=@Year"; + var query = "SELECT * FROM Year WHERE YearValue=@YearValue"; using (var cmd = new MySqlCommand(query, conn)) { - cmd.Parameters.AddWithValue("@Year", song.Year); + cmd.Parameters.AddWithValue("@YearValue", song.Year); using (var reader = cmd.ExecuteReader()) { @@ -167,6 +208,8 @@ namespace Icarus.Models.Context public void SaveYear(Year year) { + _logger.Info("Saving Year record"); + try { using (var conn = GetConnection()) @@ -193,9 +236,26 @@ namespace Icarus.Models.Context } public void UpdateYear(Year year) { + _logger.Info("Deleting Year record"); + try { - // TODO: Add functionality for updating the Year record + using (var conn = GetConnection()) + { + conn.Open(); + + var query = "UPDATE Year SET YearValue=@YearValue, SongCount=@SongCount " + + "WHERE YearId=@YearId"; + + using (var cmd = new MySqlCommand(query, conn)) + { + cmd.Parameters.AddWithValue("@YearId", year.YearId); + cmd.Parameters.AddWithValue("@YearValue", year.YearValue); + cmd.Parameters.AddWithValue("@SongCount", year.SongCount); + + cmd.ExecuteNonQuery(); + } + } } catch (Exception ex) { @@ -205,6 +265,8 @@ namespace Icarus.Models.Context } public void DeleteYear(Year year) { + _logger.Info("Deleting Year record"); + try { using (var conn = GetConnection()) diff --git a/Models/Song.cs b/Models/Song.cs index 729a919..9df17f8 100644 --- a/Models/Song.cs +++ b/Models/Song.cs @@ -37,5 +37,15 @@ namespace Icarus.Models public Artist SongArtist { get; set; } [JsonIgnore] public int ArtistId { get; set; } + + [JsonIgnore] + public Genre SongGenre { get; set; } + [JsonIgnore] + public int GenreId { get; set; } + + [JsonIgnore] + public Year SongYear { get; set; } + [JsonIgnore] + public int YearId { get; set; } } }