diff --git a/src/MusicCatalogue.Api/Controllers/SearchController.cs b/src/MusicCatalogue.Api/Controllers/SearchController.cs index ce076e6..93eb8c8 100644 --- a/src/MusicCatalogue.Api/Controllers/SearchController.cs +++ b/src/MusicCatalogue.Api/Controllers/SearchController.cs @@ -19,16 +19,24 @@ public SearchController(IAlbumLookupManager manager) _manager = manager; } + /// + /// Look up an album given the album title and artist name. Store the album and its tracks either + /// in the wish list or the main catalogue + /// + /// + /// + /// + /// [HttpGet] - [Route("{artistName}/{albumTitle}")] - public async Task> Search(string artistName, string albumTitle) + [Route("{artistName}/{albumTitle}/{storeInWishList}")] + public async Task> Search(string artistName, string albumTitle, bool storeInWishList) { // Decode the search criteria var decodedArtistName = HttpUtility.UrlDecode(artistName); var decodedAlbumTitle = HttpUtility.UrlDecode(albumTitle); // Perform the lookup - var album = await _manager.LookupAlbum(decodedArtistName, decodedAlbumTitle); + var album = await _manager.LookupAlbum(decodedArtistName, decodedAlbumTitle, storeInWishList); if (album == null) { return NotFound(); diff --git a/src/MusicCatalogue.Entities/Interfaces/IAlbumLookupManager.cs b/src/MusicCatalogue.Entities/Interfaces/IAlbumLookupManager.cs index a795dfb..7986207 100644 --- a/src/MusicCatalogue.Entities/Interfaces/IAlbumLookupManager.cs +++ b/src/MusicCatalogue.Entities/Interfaces/IAlbumLookupManager.cs @@ -4,6 +4,6 @@ namespace MusicCatalogue.Entities.Interfaces { public interface IAlbumLookupManager { - Task LookupAlbum(string artistName, string albumTitle); + Task LookupAlbum(string artistName, string albumTitle, bool storeAlbumInWishlist); } } \ No newline at end of file diff --git a/src/MusicCatalogue.Logic/Collection/AlbumLookupManager.cs b/src/MusicCatalogue.Logic/Collection/AlbumLookupManager.cs index 226aa1a..9aff6d2 100644 --- a/src/MusicCatalogue.Logic/Collection/AlbumLookupManager.cs +++ b/src/MusicCatalogue.Logic/Collection/AlbumLookupManager.cs @@ -30,8 +30,9 @@ public AlbumLookupManager( /// /// /// + /// /// - public async Task LookupAlbum(string artistName, string albumTitle) + public async Task LookupAlbum(string artistName, string albumTitle, bool storeAlbumInWishlist) { // Convert the parameters to title case to match the case used to persist data artistName = StringCleaner.Clean(artistName)!; @@ -53,7 +54,7 @@ public AlbumLookupManager( if (numberOfTracks > 0) { // Got valid details from the API so store them locally - album = await StoreAlbumLocally(artistName!, album!); + album = await StoreAlbumLocally(artistName!, album!, storeAlbumInWishlist); } else { @@ -71,15 +72,16 @@ public AlbumLookupManager( /// /// /// + /// /// - private async Task StoreAlbumLocally(string artistName, Album template) + private async Task StoreAlbumLocally(string artistName, Album template, bool storeAlbumInWishlist) { // Save the artist details, first. As with all the database calls in this method, the // logic to prevent duplication of artists is in the management class var artist = await _factory.Artists.AddAsync(artistName); // Save the album details - var album = await _factory.Albums.AddAsync(artist.Id, template.Title, template.Released, template.Genre, template.CoverUrl, false); + var album = await _factory.Albums.AddAsync(artist.Id, template.Title, template.Released, template.Genre, template.CoverUrl, storeAlbumInWishlist); // Save the track details foreach (var track in template.Tracks!) diff --git a/src/MusicCatalogue.LookupTool/Entities/TargetType.cs b/src/MusicCatalogue.LookupTool/Entities/TargetType.cs new file mode 100644 index 0000000..f14c6c3 --- /dev/null +++ b/src/MusicCatalogue.LookupTool/Entities/TargetType.cs @@ -0,0 +1,8 @@ +namespace MusicCatalogue.LookupTool.Entities +{ + internal enum TargetType + { + catalogue, + wishlist + } +} diff --git a/src/MusicCatalogue.LookupTool/Logic/AlbumLookup.cs b/src/MusicCatalogue.LookupTool/Logic/AlbumLookup.cs index 5d3f669..38bf378 100644 --- a/src/MusicCatalogue.LookupTool/Logic/AlbumLookup.cs +++ b/src/MusicCatalogue.LookupTool/Logic/AlbumLookup.cs @@ -25,7 +25,8 @@ public AlbumLookup(IMusicLogger logger, IMusicCatalogueFactory factory, MusicApp /// /// /// - public async Task LookupAlbum(string artistName, string albumTitle) + /// + public async Task LookupAlbum(string artistName, string albumTitle, bool storeInWishList) { // Get the API key and the URLs for the album and track lookup endpoints var key = _settings!.ApiServiceKeys.Find(x => x.Service == ApiServiceType.TheAudioDB)!.Key; @@ -47,7 +48,7 @@ public async Task LookupAlbum(string artistName, string albumTitle) var lookupManager = new AlbumLookupManager(_logger, albumsApi, tracksApi, _factory); // Lookup the album and its tracks - var album = await lookupManager.LookupAlbum(artistName, albumTitle); + var album = await lookupManager.LookupAlbum(artistName, albumTitle, storeInWishList); if (album != null) { // Dump the album details diff --git a/src/MusicCatalogue.LookupTool/Program.cs b/src/MusicCatalogue.LookupTool/Program.cs index d3cbdd9..6854ca3 100644 --- a/src/MusicCatalogue.LookupTool/Program.cs +++ b/src/MusicCatalogue.LookupTool/Program.cs @@ -6,6 +6,7 @@ using MusicCatalogue.Logic.Config; using MusicCatalogue.Logic.Factory; using MusicCatalogue.Logic.Logging; +using MusicCatalogue.LookupTool.Entities; using MusicCatalogue.LookupTool.Logic; using System.Diagnostics; using System.Reflection; @@ -21,13 +22,6 @@ public static class Program /// public static async Task Main(string[] args) { - // Parse the command line - CommandLineParser parser = new(); - parser.Add(CommandLineOptionType.Lookup, true, "--lookup", "-l", "Lookup an album and display its details", 2, 2); - parser.Add(CommandLineOptionType.Import, true, "--import", "-i", "Import data from a CSV format file", 1, 1); - parser.Add(CommandLineOptionType.Export, true, "--export", "-e", "Export the collection to a CSV file or Excel Workbook", 1, 1); - parser.Parse(args); - // Read the application settings MusicApplicationSettings? settings = new MusicCatalogueConfigReader().Read("appsettings.json"); @@ -45,29 +39,46 @@ public static async Task Main(string[] args) logger.LogMessage(Severity.Info, new string('=', 80)); logger.LogMessage(Severity.Info, title); - // Configure the business logic factory - var context = new MusicCatalogueDbContextFactory().CreateDbContext(Array.Empty()); - MusicCatalogueFactory factory = new MusicCatalogueFactory(context); - - // If this is a lookup, look up the album details - var values = parser.GetValues(CommandLineOptionType.Lookup); - if (values != null) + try { - await new AlbumLookup(logger, factory, settings!).LookupAlbum(values[0], values[1]); - } + // Parse the command line + CommandLineParser parser = new(); + parser.Add(CommandLineOptionType.Lookup, true, "--lookup", "-l", "Lookup an album and display its details", 3, 3); + parser.Add(CommandLineOptionType.Import, true, "--import", "-i", "Import data from a CSV format file", 1, 1); + parser.Add(CommandLineOptionType.Export, true, "--export", "-e", "Export the collection to a CSV file or Excel Workbook", 1, 1); + parser.Parse(args); - // If this is an import, import data from the specified CSV file - values = parser.GetValues(CommandLineOptionType.Import); - if (values != null) - { - new DataImport(logger, factory).Import(values[0]); - } + // Configure the business logic factory + var context = new MusicCatalogueDbContextFactory().CreateDbContext(Array.Empty()); + MusicCatalogueFactory factory = new MusicCatalogueFactory(context); + + // If this is a lookup, look up the album details + var values = parser.GetValues(CommandLineOptionType.Lookup); + if (values != null) + { + // Determine the target for new albums (catalogue or wish list) and lookup the album + var targetType = (TargetType)Enum.Parse(typeof(TargetType), values[2]); + var storeInWishList = targetType == TargetType.wishlist; + await new AlbumLookup(logger, factory, settings!).LookupAlbum(values[0], values[1], storeInWishList); + } - // If this is an export, export the collection to the specified file - values = parser.GetValues(CommandLineOptionType.Export); - if (values != null) + // If this is an import, import data from the specified CSV file + values = parser.GetValues(CommandLineOptionType.Import); + if (values != null) + { + new DataImport(logger, factory).Import(values[0]); + } + + // If this is an export, export the collection to the specified file + values = parser.GetValues(CommandLineOptionType.Export); + if (values != null) + { + new DataExport(logger, factory).Export(values[0]); + } + } + catch (Exception ex) { - new DataExport(logger, factory).Export(values[0]); + Console.WriteLine(ex.Message); } } diff --git a/src/MusicCatalogue.LookupTool/Properties/launchSettings.json b/src/MusicCatalogue.LookupTool/Properties/launchSettings.json index 8ae112a..7af4502 100644 --- a/src/MusicCatalogue.LookupTool/Properties/launchSettings.json +++ b/src/MusicCatalogue.LookupTool/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "MusicCatalogue.LookupTool": { "commandName": "Project", - "commandLineArgs": "--import C:\\Projects\\2023-10-28.csv" + "commandLineArgs": "--lookup Rush \"Permanent Waves\" wishlist" } } } \ No newline at end of file diff --git a/src/MusicCatalogue.Tests/AlbumLookupManagerTest.cs b/src/MusicCatalogue.Tests/AlbumLookupManagerTest.cs index a02b6e7..ef76e9f 100644 --- a/src/MusicCatalogue.Tests/AlbumLookupManagerTest.cs +++ b/src/MusicCatalogue.Tests/AlbumLookupManagerTest.cs @@ -53,7 +53,7 @@ public void Initialise() public void AlbumNotFoundTest() { _client!.AddResponse(AlbumNotFoundResponse); - var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle)).Result; + var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle, false)).Result; Assert.IsNull(album); } @@ -61,7 +61,7 @@ public void AlbumNotFoundTest() public void AlbumRequestNetworkErrorTest() { _client!.AddResponse(null); - var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle)).Result; + var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle, false)).Result; Assert.IsNull(album); } @@ -70,7 +70,7 @@ public void TracksNotFoundTest() { _client!.AddResponse(AlbumResponse); _client.AddResponse(TracksNotFoundResponse); - var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle)).Result; + var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle, false)).Result; Assert.IsNull(album); } @@ -80,7 +80,7 @@ public void MalformedTracksResponseTest() { _client!.AddResponse(AlbumResponse); _client!.AddResponse(MalformedTracksResponse); - var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle)).Result; + var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle, false)).Result; Assert.IsNull(album); } @@ -90,7 +90,7 @@ public void AlbumWithTracksTest() { _client!.AddResponse(AlbumResponse); _client.AddResponse(TracksResponse); - var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle)).Result; + var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle, false)).Result; Assert.IsNotNull(album); Assert.AreEqual(AlbumTitle, album.Title); @@ -113,7 +113,7 @@ public void ArtistInDbButAlbumNotInDbTest() _client!.AddResponse(AlbumResponse); _client.AddResponse(TracksResponse); - var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle)).Result; + var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle, false)).Result; Assert.IsNotNull(album); Assert.AreEqual(AlbumTitle, album.Title); @@ -134,7 +134,7 @@ public void ArtistAndAlbumInDbTest() { var artistId = Task.Run(() => _factory!.Artists.AddAsync(ArtistName)).Result.Id; Task.Run(() => _factory!.Albums.AddAsync(artistId, AlbumTitle, Released, Genre, CoverUrl, false)).Wait(); - var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle)).Result; + var album = Task.Run(() => _manager!.LookupAlbum(ArtistName, AlbumTitle, false)).Result; Assert.IsNotNull(album); Assert.AreEqual(AlbumTitle, album.Title);