diff --git a/Inspector/appsettings.json b/Inspector/appsettings.json index e5cf16a..fceed60 100644 --- a/Inspector/appsettings.json +++ b/Inspector/appsettings.json @@ -20,7 +20,6 @@ "DontDoMetaDataProvidersSearchArtists": [ "Various Artists", "Sound Tracks" ], "FileExtenionsToDelete": [ ".cue", ".db", ".gif", ".html", ".ini", ".jpg", ".jpeg", ".log", ".mpg", ".m3u", ".png", ".nfo", ".nzb", ".sfv", ".srr", ".txt", ".url" ], "RecordNoResultSearches": true, - "SingleArtistHoldingFolder": "C:\\roadie_dev_root\\single_holding", "ArtistNameReplace": { "AC/DC": [ "AC; DC", "AC;DC", "AC/ DC", "AC DC" ], "Love/Hate": [ "Love; Hate", "Love;Hate", "Love/ Hate", "Love Hate" ] diff --git a/Roadie.Api.Library.Tests/appsettings.test.json b/Roadie.Api.Library.Tests/appsettings.test.json index 652ab24..1ac44d4 100644 --- a/Roadie.Api.Library.Tests/appsettings.test.json +++ b/Roadie.Api.Library.Tests/appsettings.test.json @@ -20,7 +20,6 @@ "DontDoMetaDataProvidersSearchArtists": [ "Various Artists", "Sound Tracks" ], "FileExtenionsToDelete": [ ".cue", ".db", ".gif", ".html", ".ini", ".jpg", ".jpeg", ".log", ".mpg", ".m3u", ".png", ".nfo", ".nzb", ".sfv", ".srr", ".txt", ".url" ], "RecordNoResultSearches": true, - "SingleArtistHoldingFolder": "C:\\roadie_dev_root\\single_holding", "ArtistNameReplace": { "AC/DC": [ "AC; DC", "AC;DC", "AC/ DC", "AC DC" ], "Love/Hate": [ "Love; Hate", "Love;Hate", "Love/ Hate", "Love Hate" ] diff --git a/Roadie.Api.Library/Configuration/Converting.cs b/Roadie.Api.Library/Configuration/Converting.cs index b506b48..98f5a1f 100644 --- a/Roadie.Api.Library/Configuration/Converting.cs +++ b/Roadie.Api.Library/Configuration/Converting.cs @@ -6,8 +6,10 @@ namespace Roadie.Library.Configuration public class Converting : IConverting { public string APEConvertCommand { get; set; } + public bool ConvertingEnabled { get; set; } public bool DoDeleteAfter { get; set; } public string M4AConvertCommand { get; set; } public string OGGConvertCommand { get; set; } + public string FLACConvertCommand { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Configuration/IConverting.cs b/Roadie.Api.Library/Configuration/IConverting.cs index 9aecfcf..3367228 100644 --- a/Roadie.Api.Library/Configuration/IConverting.cs +++ b/Roadie.Api.Library/Configuration/IConverting.cs @@ -2,6 +2,7 @@ { public interface IConverting { + bool ConvertingEnabled { get; set; } string APEConvertCommand { get; set; } bool DoDeleteAfter { get; set; } string M4AConvertCommand { get; set; } diff --git a/Roadie.Api.Library/Configuration/IRoadieSettings.cs b/Roadie.Api.Library/Configuration/IRoadieSettings.cs index dbe6a4c..e3e6b84 100644 --- a/Roadie.Api.Library/Configuration/IRoadieSettings.cs +++ b/Roadie.Api.Library/Configuration/IRoadieSettings.cs @@ -24,7 +24,6 @@ namespace Roadie.Library.Configuration bool RecordNoResultSearches { get; set; } RedisCache Redis { get; set; } string SecretKey { get; set; } - string SingleArtistHoldingFolder { get; set; } string SiteName { get; set; } ImageSize SmallImageSize { get; set; } string SmtpFromAddress { get; set; } diff --git a/Roadie.Api.Library/Configuration/RoadieSettings.cs b/Roadie.Api.Library/Configuration/RoadieSettings.cs index 81ef9e3..31e8f20 100644 --- a/Roadie.Api.Library/Configuration/RoadieSettings.cs +++ b/Roadie.Api.Library/Configuration/RoadieSettings.cs @@ -40,7 +40,6 @@ namespace Roadie.Library.Configuration public RedisCache Redis { get; set; } public ImageSize SmallImageSize { get; set; } public string SecretKey { get; set; } - public string SingleArtistHoldingFolder { get; set; } public string SiteName { get; set; } public string SmtpFromAddress { get; set; } public string SmtpHost { get; set; } diff --git a/Roadie.Api.Library/Models/Releases/Release.cs b/Roadie.Api.Library/Models/Releases/Release.cs index 6b578e3..34bfa50 100644 --- a/Roadie.Api.Library/Models/Releases/Release.cs +++ b/Roadie.Api.Library/Models/Releases/Release.cs @@ -70,6 +70,10 @@ namespace Roadie.Library.Models.Releases // When populated a "data:image" base64 byte array of an image to use as new Thumbnail public string NewThumbnailData { get; set; } + /// + /// When populated a "data:image" base64 byte array of an image to use as secondary Release images. + /// + public List NewSecondaryImagesData { get; set; } [MaxLength(250)] [Required] diff --git a/Roadie.Api.Library/SearchEngines/MetaData/LastFm/LastFmHelper.cs b/Roadie.Api.Library/SearchEngines/MetaData/LastFm/LastFmHelper.cs index 43bf6bd..fa105d4 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/LastFm/LastFmHelper.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/LastFm/LastFmHelper.cs @@ -390,9 +390,15 @@ namespace Roadie.Library.MetaData.LastFm { parameters = new Dictionary(); } - parameters.Add("method", method); - parameters.Add("api_key", this._apiKey.Key); - if (!string.IsNullOrEmpty(sk)) + if (!parameters.ContainsKey("method")) + { + parameters.Add("method", method); + } + if (!parameters.ContainsKey("api_key")) + { + parameters.Add("api_key", this._apiKey.Key); + } + if (!string.IsNullOrEmpty(sk) && !parameters.ContainsKey("sk")) { parameters.Add("sk", sk); } diff --git a/Roadie.Api.Services/AdminService.cs b/Roadie.Api.Services/AdminService.cs index 7d9366e..4becc92 100644 --- a/Roadie.Api.Services/AdminService.cs +++ b/Roadie.Api.Services/AdminService.cs @@ -234,6 +234,45 @@ namespace Roadie.Api.Services }; } + public async Task> DeleteReleaseSecondaryImage(ApplicationUser user, Guid releaseId, int index) + { + var sw = new Stopwatch(); + sw.Start(); + var errors = new List(); + var release = this.DbContext.Releases.Include(x => x.Artist).FirstOrDefault(x => x.RoadieId == releaseId); + if (release == null) + { + await this.LogAndPublish($"DeleteReleaseSecondaryImage Unknown Release [{ releaseId}]", LogLevel.Warning); + return new OperationResult(true, $"Release Not Found [{ releaseId }]"); + } + try + { + var releaseFolder = release.ReleaseFileFolder(release.Artist.ArtistFileFolder(this.Configuration, this.Configuration.LibraryFolder)); + var releaseImagesInFolder = ImageHelper.FindImageTypeInDirectory(new DirectoryInfo(releaseFolder), ImageType.ReleaseSecondary, SearchOption.TopDirectoryOnly); + var releaseImageFilename = releaseImagesInFolder.Skip(index).FirstOrDefault(); + if (releaseImageFilename.Exists) + { + releaseImageFilename.Delete(); + } + this.CacheManager.ClearRegion(release.CacheRegion); + } + catch (Exception ex) + { + this.Logger.LogError(ex); + await this.LogAndPublish("Error deleting release secondary image."); + errors.Add(ex); + } + sw.Stop(); + await this.LogAndPublish($"DeleteReleaseSecondaryImage `{ release }` Index [{ index }], By User `{user }`", LogLevel.Information); + return new OperationResult + { + IsSuccess = !errors.Any(), + Data = true, + OperationTime = sw.ElapsedMilliseconds, + Errors = errors + }; + } + public async Task> DeleteTrack(ApplicationUser user, Guid trackId, bool? doDeleteFile) { var sw = new Stopwatch(); diff --git a/Roadie.Api.Services/IAdminService.cs b/Roadie.Api.Services/IAdminService.cs index c9803d2..b88fce8 100644 --- a/Roadie.Api.Services/IAdminService.cs +++ b/Roadie.Api.Services/IAdminService.cs @@ -17,6 +17,8 @@ namespace Roadie.Api.Services Task> DeleteRelease(ApplicationUser user, Guid releaseId, bool? doDeleteFiles); + Task> DeleteReleaseSecondaryImage(ApplicationUser user, Guid releaseId, int index); + Task> DeleteTrack(ApplicationUser user, Guid trackId, bool? doDeleteFile); Task> DeleteUser(ApplicationUser applicationUser, Guid id); diff --git a/Roadie.Api.Services/ReleaseService.cs b/Roadie.Api.Services/ReleaseService.cs index f429492..6dea200 100644 --- a/Roadie.Api.Services/ReleaseService.cs +++ b/Roadie.Api.Services/ReleaseService.cs @@ -657,6 +657,32 @@ namespace Roadie.Api.Services didChangeThumbnail = true; } + if (model.NewSecondaryImagesData != null && model.NewSecondaryImagesData.Any()) + { + var releaseFolder = release.ReleaseFileFolder(release.Artist.ArtistFileFolder(this.Configuration, this.Configuration.LibraryFolder)); + // Additional images to add to artist + var looper = 0; + foreach (var newSecondaryImageData in model.NewSecondaryImagesData) + { + var releaseSecondaryImage = ImageHelper.ImageDataFromUrl(newSecondaryImageData); + if (releaseSecondaryImage != null) + { + // Ensure is jpeg first + releaseSecondaryImage = ImageHelper.ConvertToJpegFormat(releaseSecondaryImage); + + var releaseImageFilename = Path.Combine(releaseFolder, string.Format(ImageHelper.ReleaseSecondaryImageFilename, looper.ToString("00"))); + while (File.Exists(releaseImageFilename)) + { + looper++; + releaseImageFilename = Path.Combine(releaseFolder, string.Format(ImageHelper.ReleaseSecondaryImageFilename, looper.ToString("00"))); + } + File.WriteAllBytes(releaseImageFilename, releaseSecondaryImage); + } + looper++; + } + } + + if (model.Genres != null && model.Genres.Any()) { // Remove existing Genres not in model list diff --git a/Roadie.Api/Controllers/AdminController.cs b/Roadie.Api/Controllers/AdminController.cs index 122692c..ed6be97 100644 --- a/Roadie.Api/Controllers/AdminController.cs +++ b/Roadie.Api/Controllers/AdminController.cs @@ -85,6 +85,19 @@ namespace Roadie.Api.Controllers return Ok(result); } + [HttpPost("delete/releasesecondaryimage/{id}/{index}")] + [ProducesResponseType(200)] + public async Task DeleteReleaseSecondaryImage(Guid id, int index) + { + var result = await this.AdminService.DeleteReleaseSecondaryImage(await this.UserManager.GetUserAsync(User), id, index); + if (!result.IsSuccess) + { + return StatusCode((int)HttpStatusCode.InternalServerError); + } + return Ok(result); + } + + [HttpPost("delete/track/{id}")] [ProducesResponseType(200)] public async Task DeleteTrack(Guid id, bool? doDeleteFile) diff --git a/Roadie.Api/Properties/launchSettings.json b/Roadie.Api/Properties/launchSettings.json index e942ed4..4da01d5 100644 --- a/Roadie.Api/Properties/launchSettings.json +++ b/Roadie.Api/Properties/launchSettings.json @@ -3,7 +3,7 @@ "Roadie.Api": { "commandName": "Project", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Production" + "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:5123/" } diff --git a/Roadie.Api/appsettings.Development.json b/Roadie.Api/appsettings.Development.json index e6c7042..ad87520 100644 --- a/Roadie.Api/appsettings.Development.json +++ b/Roadie.Api/appsettings.Development.json @@ -72,7 +72,6 @@ "DontDoMetaDataProvidersSearchArtists": [ "Various Artists", "Sound Tracks" ], "FileExtenionsToDelete": [ ".cue", ".db", ".gif", ".html", ".ini", ".jpg", ".jpeg", ".log", ".mpg", ".m3u", ".png", ".nfo", ".nzb", ".sfv", ".srr", ".txt", ".url" ], "RecordNoResultSearches": true, - "SingleArtistHoldingFolder": "C:\\roadie_dev_root\\single_holding", "ArtistNameReplace": { "AC/DC": [ "AC; DC", "AC;DC", "AC/ DC", "AC DC" ], "Love/Hate": [ "Love; Hate", "Love;Hate", "Love/ Hate", "Love Hate" ] diff --git a/Roadie.Api/appsettings.json b/Roadie.Api/appsettings.json index 7594fbc..eefaa9c 100644 --- a/Roadie.Api/appsettings.json +++ b/Roadie.Api/appsettings.json @@ -72,16 +72,17 @@ "DontDoMetaDataProvidersSearchArtists": [ "Various Artists", "Sound Tracks" ], "FileExtenionsToDelete": [ ".cue", ".db", ".gif", ".html", ".ini", ".jpg", ".jpeg", ".log", ".mpg", ".m3u", ".png", ".nfo", ".nzb", ".sfv", ".srr", ".txt", ".url" ], "RecordNoResultSearches": true, - "SingleArtistHoldingFolder": "M:/single_holding/", "ArtistNameReplace": { "AC/DC": [ "AC; DC", "AC;DC", "AC/ DC", "AC DC" ], "Love/Hate": [ "Love; Hate", "Love;Hate", "Love/ Hate", "Love Hate" ] }, "Converting": { + "ConvertingEnabled": true, "DoDeleteAfter": true, "M4AConvertCommand": "ffmpeg -i \"{0}\" -acodec libmp3lame -q:a 0 \"{1}\"", "OGGConvertCommand": "ffmpeg -i \"{0}\" -acodec libmp3lame -q:a 0 \"{1}\"\"", - "APEConvertCommand": "ffmpeg -i \"{0}\" \"{1}\"" + "APEConvertCommand": "ffmpeg -i \"{0}\" \"{1}\"", + "FLACConvertCommand": "ffmpeg -i \"{0}\" -q:a 0 \"{1}\"" }, "SmtpFromAddress": "roadie@roadie.rocks", "SmtpPort": 2525,