mirror of
https://github.com/sphildreth/roadie
synced 2025-02-16 13:08:25 +00:00
Inspector enhancements
This commit is contained in:
parent
f8e97a5880
commit
114dc26ed2
27 changed files with 511 additions and 242 deletions
|
@ -7,17 +7,22 @@
|
|||
|
||||
<ItemGroup>
|
||||
<None Remove="appsettings.json" />
|
||||
<None Remove="PreInspectScript.ps1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="PreInspectScript.ps1">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.3.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.PowerShell.SDK" Version="6.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
1
Inspector/PreInspectScript.ps1
Normal file
1
Inspector/PreInspectScript.ps1
Normal file
|
@ -0,0 +1 @@
|
|||
gci -Path "N:\_complete" -r -include *.zip,*.rar,*.7z | foreach { & 'C:\Program Files\7-Zip\7z.exe' -x -y $_.FullName -o"$(' " '+$_.DirectoryName+' " ')"}
|
|
@ -2,7 +2,7 @@
|
|||
"profiles": {
|
||||
"Inspector": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "-f \"N:\\_complete\" -d \"M:\\inbound\" -r"
|
||||
"commandLineArgs": "-f \"N:\\_complete\" -d \"M:\\inbound\""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
"Width": 320
|
||||
},
|
||||
"DontDoMetaDataProvidersSearchArtists": [ "Various Artists", "Sound Tracks" ],
|
||||
"FileExtensionsToDelete": [ ".accurip", ".cue", ".db", ".gif", ".html", ".ini", ".jpg", ".jpeg", ".log", ".mpg", ".m3u", ".png", ".nfo", ".nzb", ".sfv", ".srr", ".txt", ".url" ],
|
||||
"FileExtensionsToDelete": [ ".accurip", ".cue", ".db", ".exe", ".html", ".ini", ".log", ".md5", ".mht", ".mpg", ".m3u", ".nfo", ".nzb", ".pls", ".sfv", ".srr", ".txt", ".url" ],
|
||||
"RecordNoResultSearches": true,
|
||||
"ArtistNameReplace": {
|
||||
"AC/DC": [ "AC; DC", "AC;DC", "AC/ DC", "AC DC" ],
|
||||
|
@ -57,6 +57,8 @@
|
|||
"MaximumArtistImagesToAdd": 12,
|
||||
"MaximumReleaseImagesToAdd": 12,
|
||||
"MaxImageWidth": 2048,
|
||||
"PreInspectScript": "PreInspectScript.ps1",
|
||||
"PostInspectScript": "",
|
||||
"ReleaseRemoveStringsRegex": "(\\\\s*(-\\\\s)*((CD[_\\-#\\s]*[0-9]*)))|((\\\\(|\\\\[)+([0-9]|,|self|bonus|re(leas|master|(e|d)*)*|th|anniversary|cd|disc|deluxe|dig(ipack)*|vinyl|japan(ese)*|asian|remastered|limited|ltd|expanded|edition|\\\\s)+(]|\\\\)*))",
|
||||
"TrackRemoveStringsRegex": "^([0-9]+)(\\.|-|\\s)*",
|
||||
"ReplaceStrings": [
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Configuration;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Engines;
|
||||
using Roadie.Library.Extensions;
|
||||
using Roadie.Library.Factories;
|
||||
using Roadie.Library.MetaData.ID3Tags;
|
||||
using Roadie.Library.Processors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -66,7 +69,60 @@ namespace Roadie.Library.Tests
|
|||
var a = artistLookupEngine.DatabaseQueryForArtistName("Nas");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public void Update_Releases_Special_Name()
|
||||
//{
|
||||
// var optionsBuilder = new DbContextOptionsBuilder<RoadieDbContext>();
|
||||
// optionsBuilder.UseMySql("server=viking;userid=roadie;password=MenAtW0rk668;persistsecurityinfo=True;database=roadie;ConvertZeroDateTime=true");
|
||||
|
||||
// using (var context = new RoadieDbContext(optionsBuilder.Options))
|
||||
// {
|
||||
// var now = DateTime.UtcNow;
|
||||
// foreach(var release in context.Releases)
|
||||
// {
|
||||
// var releaseModel = release.Adapt<Roadie.Library.Models.Releases.Release>();
|
||||
// var specialReleaseTitle = release.Title.ToAlphanumericName();
|
||||
// if (!releaseModel.AlternateNamesList.Contains(specialReleaseTitle, StringComparer.OrdinalIgnoreCase))
|
||||
// {
|
||||
// var alt = new List<string>(releaseModel.AlternateNamesList)
|
||||
// {
|
||||
// specialReleaseTitle
|
||||
// };
|
||||
// release.AlternateNames = alt.ToDelimitedList();
|
||||
// release.LastUpdated = now;
|
||||
// }
|
||||
// }
|
||||
// context.SaveChanges();
|
||||
// }
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void Update_Artist_Special_Name()
|
||||
//{
|
||||
// var optionsBuilder = new DbContextOptionsBuilder<RoadieDbContext>();
|
||||
// optionsBuilder.UseMySql("server=viking;userid=roadie;password=MenAtW0rk668;persistsecurityinfo=True;database=roadie;ConvertZeroDateTime=true");
|
||||
|
||||
// using (var context = new RoadieDbContext(optionsBuilder.Options))
|
||||
// {
|
||||
// var now = DateTime.UtcNow;
|
||||
// foreach (var artist in context.Artists)
|
||||
// {
|
||||
// var artistModel = artist.Adapt<Roadie.Library.Models.Artist>();
|
||||
// var specialArtistName = artist.Name.ToAlphanumericName();
|
||||
// if (!artistModel.AlternateNamesList.Contains(specialArtistName, StringComparer.OrdinalIgnoreCase))
|
||||
// {
|
||||
// var alt = new List<string>(artistModel.AlternateNamesList)
|
||||
// {
|
||||
// specialArtistName
|
||||
// };
|
||||
// artist.AlternateNames = alt.ToDelimitedList();
|
||||
// artist.LastUpdated = now;
|
||||
// }
|
||||
// }
|
||||
// context.SaveChanges();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ namespace Roadie.Library.Tests
|
|||
[InlineData("folder.JPG")]
|
||||
[InlineData("front.jpg")]
|
||||
[InlineData("FrOnt.jpg")]
|
||||
[InlineData("Art.jpg")]
|
||||
[InlineData("Art - front.jpg")]
|
||||
[InlineData("Art - Front.jpg")]
|
||||
[InlineData("Art-Front.jpg")]
|
||||
|
@ -70,6 +71,7 @@ namespace Roadie.Library.Tests
|
|||
[InlineData("F-1.jpg")]
|
||||
[InlineData("front_.jpg")]
|
||||
[InlineData("BIG.JPg")]
|
||||
[InlineData("bigart.JPg")]
|
||||
[InlineData("BIG.PNG")]
|
||||
public void Test_Should_Be_Release_Images(string input)
|
||||
{
|
||||
|
@ -191,6 +193,11 @@ namespace Roadie.Library.Tests
|
|||
[InlineData("CD3.jpg")]
|
||||
[InlineData("Scan-1.jpg")]
|
||||
[InlineData("Scan-12.jpg")]
|
||||
[InlineData("Scan 1.jpg")]
|
||||
[InlineData("sc 1.jpg")]
|
||||
[InlineData("sc01.jpg")]
|
||||
[InlineData("sc-01.jpg")]
|
||||
[InlineData("sc 01.jpg")]
|
||||
[InlineData("cover_01.jpg")]
|
||||
[InlineData("cover 03.jpg")]
|
||||
[InlineData("cover 1.jpg")]
|
||||
|
|
|
@ -66,6 +66,24 @@ namespace Roadie.Library.Tests
|
|||
Assert.Null(t);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Bob", "bob")]
|
||||
[InlineData("Bob Marley", "bobmarley")]
|
||||
[InlineData("Ringo Starr And His All-Starr Band", "ringostarrandhisallstarrband")]
|
||||
[InlineData("Leslie & Tom", "leslieandtom")]
|
||||
[InlineData(" Leslie & Tom", "leslieandtom")]
|
||||
[InlineData("Leslie And Tom", "leslieandtom")]
|
||||
[InlineData("Leslie Tom", "leslietom")]
|
||||
[InlineData("Hüsker Dü", "huskerdu")]
|
||||
[InlineData("Motörhead", "motorhead")] //
|
||||
[InlineData("Alright, Still", "alrightstill")]
|
||||
[InlineData("Something, SOMETHING & somEthing!", "somethingsomethingandsomething")]
|
||||
public void ToAlphanumericNameShouldStripAndMatch(string input, string shouldBe)
|
||||
{
|
||||
var t = input.ToAlphanumericName();
|
||||
Assert.Equal(shouldBe, t);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveFirst()
|
||||
{
|
||||
|
|
|
@ -24,7 +24,8 @@ namespace Roadie.Library.Configuration
|
|||
public string ArtistRemoveStringsRegex { get; set; }
|
||||
public string ReleaseRemoveStringsRegex { get; set; }
|
||||
public string TrackRemoveStringsRegex { get; set; }
|
||||
|
||||
public string PreInspectScript { get; set; }
|
||||
public string PostInspectScript { get; set; }
|
||||
public List<ReplacementString> ReplaceStrings { get; set; }
|
||||
public string UnknownFolder { get; set; }
|
||||
|
||||
|
|
|
@ -183,8 +183,10 @@ namespace Roadie.Library.Engines
|
|||
|
||||
return (from a in this.DbContext.Artists
|
||||
where (a.Name == searchName ||
|
||||
a.Name == specialSearchName ||
|
||||
a.SortName == searchName ||
|
||||
a.SortName == searchSortName ||
|
||||
a.SortName == specialSearchName ||
|
||||
a.AlternateNames.StartsWith(searchNameStart) ||
|
||||
a.AlternateNames.Contains(searchNameIn) ||
|
||||
a.AlternateNames.EndsWith(searchNameEnd) ||
|
||||
|
|
|
@ -112,15 +112,16 @@ namespace Roadie.Library.Engines
|
|||
|
||||
var release = (from r in this.DbContext.Releases
|
||||
where (r.ArtistId == artist.Id)
|
||||
where (r.Title.ToLower() == searchName ||
|
||||
r.AlternateNames.ToLower() == searchName ||
|
||||
r.AlternateNames.ToLower() == specialSearchName ||
|
||||
r.AlternateNames.ToLower().Contains(altStart) ||
|
||||
r.AlternateNames.ToLower().Contains(altIn) ||
|
||||
r.AlternateNames.ToLower().Contains(altEnds) ||
|
||||
r.AlternateNames.ToLower().Contains(altStartSpecial) ||
|
||||
r.AlternateNames.ToLower().Contains(altInSpecial) ||
|
||||
r.AlternateNames.ToLower().Contains(altEndsSpecial))
|
||||
where (r.Title == searchName ||
|
||||
r.Title == specialSearchName ||
|
||||
r.AlternateNames == searchName ||
|
||||
r.AlternateNames == specialSearchName ||
|
||||
r.AlternateNames.Contains(altStart) ||
|
||||
r.AlternateNames.Contains(altIn) ||
|
||||
r.AlternateNames.Contains(altEnds) ||
|
||||
r.AlternateNames.Contains(altStartSpecial) ||
|
||||
r.AlternateNames.Contains(altInSpecial) ||
|
||||
r.AlternateNames.Contains(altEndsSpecial))
|
||||
select r
|
||||
).FirstOrDefault();
|
||||
|
||||
|
|
|
@ -201,6 +201,21 @@ namespace Roadie.Library.Extensions
|
|||
return input;
|
||||
}
|
||||
|
||||
public static String RemoveDiacritics(this string s)
|
||||
{
|
||||
String normalizedString = s.Normalize(NormalizationForm.FormD);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < normalizedString.Length; i++)
|
||||
{
|
||||
Char c = normalizedString[i];
|
||||
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
|
||||
{
|
||||
stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public static string ToAlphanumericName(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
|
@ -210,7 +225,7 @@ namespace Roadie.Library.Extensions
|
|||
input = input.ToLower().Trim().Replace("&", "and");
|
||||
char[] arr = input.ToCharArray();
|
||||
arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c))));
|
||||
return new string(arr);
|
||||
return new string(arr).RemoveDiacritics();
|
||||
}
|
||||
|
||||
public static string ToContentDispositionFriendly(this string input)
|
||||
|
|
|
@ -328,6 +328,7 @@ namespace Roadie.Library.Factories
|
|||
existingReleaseMedia.TrackCount++;
|
||||
existingReleaseMedia.LastUpdated = now;
|
||||
releaseToMergeInto.TrackCount++;
|
||||
mergedTracksToMove.Add(mergeTrack);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Roadie.Library.Enums;
|
||||
using Roadie.Library.Extensions;
|
||||
using Roadie.Library.SearchEngines.Imaging;
|
||||
using Roadie.Library.Utility;
|
||||
using SixLabors.ImageSharp;
|
||||
|
@ -156,7 +157,7 @@ namespace Roadie.Library.Imaging
|
|||
{
|
||||
return false;
|
||||
}
|
||||
return Regex.IsMatch(fileinfo.Name, @"((f[-_\s]*[0-9]*)|big|cover|cvr|folder|release|front[-_\s]*)\.(jpg|jpeg|png|bmp|gif)", RegexOptions.IgnoreCase);
|
||||
return Regex.IsMatch(fileinfo.Name, @"((f[-_\s]*[0-9]*)|art|big[art]*|cover|cvr|folder|release|front[-_\s]*)\.(jpg|jpeg|png|bmp|gif)", RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
public static bool IsReleaseSecondaryImage(FileInfo fileinfo)
|
||||
|
@ -165,7 +166,7 @@ namespace Roadie.Library.Imaging
|
|||
{
|
||||
return false;
|
||||
}
|
||||
return Regex.IsMatch(fileinfo.Name, @"((img[\s-_]*[0-9]*[\s-_]*[0-9]*)|(book[let]*[#-_\s(]*[0-9]*-*[0-9]*(\))*)|(encartes[-_\s]*[(]*[0-9]*[)]*)|scan(.)?[0-9]*|matrix(.)?[0-9]*|(cover[\s_-]*[0-9]+)|back|traycard|jewel case|disc|(.*)[in]*side(.*)|in([side|lay|let|site])*[0-9]*|cd(.)?[0-9]*|(release[\s_-]+[0-9]+))\.(jpg|jpeg|png|bmp|gif)", RegexOptions.IgnoreCase);
|
||||
return Regex.IsMatch(fileinfo.Name, @"((img[\s-_]*[0-9]*[\s-_]*[0-9]*)|(book[let]*[#-_\s(]*[0-9]*-*[0-9]*(\))*)|(encartes[-_\s]*[(]*[0-9]*[)]*)|sc[an]*(.)?[0-9]*|matrix(.)?[0-9]*|(cover[\s_-]*[0-9]+)|back|traycard|jewel case|disc|(.*)[in]*side(.*)|in([side|lay|let|site])*[0-9]*|cd(.)?[0-9]*|(release[\s_-]+[0-9]+))\.(jpg|jpeg|png|bmp|gif)", RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
public static bool IsLabelImage(FileInfo fileinfo)
|
||||
|
@ -191,10 +192,13 @@ namespace Roadie.Library.Imaging
|
|||
}
|
||||
if (imageFilesInFolder.Any())
|
||||
{
|
||||
name = name.ToAlphanumericName();
|
||||
foreach (var imageFileInFolder in imageFilesInFolder)
|
||||
{
|
||||
var image = new FileInfo(imageFileInFolder);
|
||||
if(image.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
|
||||
var filenameWithoutExtension = Path.GetFileName(imageFileInFolder).ToAlphanumericName();
|
||||
var imageName = image.Name.ToAlphanumericName();
|
||||
if(imageName.Equals(name) || filenameWithoutExtension.Equals(name))
|
||||
{
|
||||
result.Add(image);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace Roadie.Library.Inspect
|
||||
{
|
||||
|
@ -53,7 +54,7 @@ namespace Roadie.Library.Inspect
|
|||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"__ Not Loading Disabled Pluging [{ plugin.Description }]");
|
||||
Console.WriteLine($"╠╣ Not Loading Disabled Plugin [{ plugin.Description }]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +94,7 @@ namespace Roadie.Library.Inspect
|
|||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"__ Not Loading Disabled Pluging [{ plugin.Description }]");
|
||||
Console.WriteLine($"╠╣ Not Loading Disabled Plugin [{ plugin.Description }]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,16 +170,27 @@ namespace Roadie.Library.Inspect
|
|||
var artistsFound = new List<string>();
|
||||
var releasesFound = new List<string>();
|
||||
var mp3FilesFoundCount = 0;
|
||||
|
||||
Console.BackgroundColor = ConsoleColor.White;
|
||||
Console.ForegroundColor = ConsoleColor.Blue;
|
||||
Console.WriteLine($"✨ Inspector Start, UTC [{ DateTime.UtcNow.ToString("s") }]");
|
||||
Console.ResetColor();
|
||||
|
||||
// Run PreInspect script
|
||||
var scriptResult = RunScript(Configuration.Processing.PreInspectScript, doCopy, isReadOnly, directoryToInspect, destination);
|
||||
if(!string.IsNullOrEmpty(scriptResult))
|
||||
{
|
||||
Console.BackgroundColor = ConsoleColor.Blue;
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine($"PreInspectScript Results: { System.Environment.NewLine + scriptResult + System.Environment.NewLine }");
|
||||
Console.ResetColor();
|
||||
}
|
||||
// Create a new destination subfolder for each Inspector run by Current timestamp
|
||||
var dest = Path.Combine(destination, DateTime.UtcNow.ToString("yyyyMMddHHmm"));
|
||||
if (isReadOnly || dontAppendSubFolder)
|
||||
{
|
||||
dest = destination;
|
||||
}
|
||||
if (!isReadOnly && !Directory.Exists(dest))
|
||||
{
|
||||
Directory.CreateDirectory(dest);
|
||||
}
|
||||
// Get all the directorys in the directory
|
||||
var directoryDirectories = Directory.GetDirectories(directoryToInspect, "*.*", SearchOption.AllDirectories);
|
||||
var directories = new List<string>
|
||||
|
@ -190,198 +202,205 @@ namespace Roadie.Library.Inspect
|
|||
var inspectedImagesInDirectories = new List<string>();
|
||||
try
|
||||
{
|
||||
var createdDestinationFolder = false;
|
||||
foreach (var directory in directories.OrderBy(x => x))
|
||||
{
|
||||
var directoryInfo = new DirectoryInfo(directory);
|
||||
|
||||
var sw = Stopwatch.StartNew();
|
||||
Console.ForegroundColor = ConsoleColor.Blue;
|
||||
Console.WriteLine($"╔ ░▒▓ Inspecting [{ directory }] ▓▒░");
|
||||
Console.WriteLine($"╔ 📂 Inspecting [{ directory }]");
|
||||
Console.ResetColor();
|
||||
Console.WriteLine("╠╦════════════════════════╣");
|
||||
|
||||
// Get all the MP3 files in 'directory'
|
||||
var files = Directory.GetFiles(directory, "*.mp3", SearchOption.TopDirectoryOnly);
|
||||
if (files == null || !files.Any())
|
||||
if (files != null && files.Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Run directory plugins against current directory
|
||||
foreach (var plugin in DirectoryPlugins.Where(x => !x.IsPostProcessingPlugin).OrderBy(x => x.Order))
|
||||
{
|
||||
Console.WriteLine($"╠╬═ Running Directory Plugin { plugin.Description }");
|
||||
var pluginResult = plugin.Process(directoryInfo);
|
||||
if (!pluginResult.IsSuccess)
|
||||
if (!isReadOnly && !createdDestinationFolder && !Directory.Exists(dest))
|
||||
{
|
||||
Console.WriteLine($"Plugin Failed: Error [{ JsonConvert.SerializeObject(pluginResult)}]");
|
||||
return;
|
||||
Directory.CreateDirectory(dest);
|
||||
createdDestinationFolder = true;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(pluginResult.Data))
|
||||
|
||||
// Run directory plugins against current directory
|
||||
foreach (var plugin in DirectoryPlugins.Where(x => !x.IsPostProcessingPlugin).OrderBy(x => x.Order))
|
||||
{
|
||||
Console.WriteLine($"╠╣ Directory Plugin Message: { pluginResult.Data }");
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"╠╝");
|
||||
Console.WriteLine($"╟─ Found [{ files.Length }] mp3 Files");
|
||||
List<AudioMetaData> fileMetaDatas = new List<AudioMetaData>();
|
||||
List<FileInfo> fileInfos = new List<FileInfo>();
|
||||
// Inspect the found MP3 files in 'directory'
|
||||
foreach (var file in files)
|
||||
{
|
||||
mp3FilesFoundCount++;
|
||||
var fileInfo = new FileInfo(file);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"╟─ Inspecting [{ fileInfo.FullName }]");
|
||||
var tagLib = TagsHelper.MetaDataForFile(fileInfo.FullName, true);
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
if (!tagLib?.IsSuccess ?? false)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
}
|
||||
Console.WriteLine($"╟ (Pre ) : { tagLib.Data }");
|
||||
Console.ResetColor();
|
||||
tagLib.Data.Filename = fileInfo.FullName;
|
||||
var originalMetaData = tagLib.Data.Adapt<AudioMetaData>();
|
||||
var pluginMetaData = tagLib.Data;
|
||||
// Run all file plugins against the MP3 file modifying the MetaData
|
||||
foreach (var plugin in FilePlugins.OrderBy(x => x.Order))
|
||||
{
|
||||
Console.WriteLine($"╟┤ Running File Plugin { plugin.Description }");
|
||||
OperationResult<AudioMetaData> pluginResult = null;
|
||||
pluginResult = plugin.Process(pluginMetaData);
|
||||
Console.WriteLine($"╠╬═ Running Directory Plugin { plugin.Description }");
|
||||
var pluginResult = plugin.Process(directoryInfo);
|
||||
if (!pluginResult.IsSuccess)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"Plugin Failed: Error [{ JsonConvert.SerializeObject(pluginResult)}]");
|
||||
Console.ResetColor();
|
||||
Console.WriteLine($"📛 Plugin Failed: Error [{ JsonConvert.SerializeObject(pluginResult)}]");
|
||||
return;
|
||||
}
|
||||
pluginMetaData = pluginResult.Data;
|
||||
}
|
||||
// See if the MetaData from the Plugins is different from the original
|
||||
if (originalMetaData != null && pluginMetaData != null)
|
||||
{
|
||||
var differences = AutoCompare.Comparer.Compare(originalMetaData, pluginMetaData);
|
||||
if (differences.Any())
|
||||
else if (!string.IsNullOrEmpty(pluginResult.Data))
|
||||
{
|
||||
var skipDifferences = new List<string> { "AudioMetaDataWeights", "FileInfo", "Images", "TrackArtists", "ValidWeight" };
|
||||
var differencesDescription = $"{ System.Environment.NewLine }";
|
||||
foreach (var difference in differences)
|
||||
{
|
||||
if (skipDifferences.Contains(difference.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
differencesDescription += $"╟ || { difference.Name } : Was [{ difference.OldValue}] Now [{ difference.NewValue}]{ System.Environment.NewLine }";
|
||||
}
|
||||
Console.Write($"╟ ≡ != ID3 Tag Modified: { differencesDescription }");
|
||||
|
||||
if (!isReadOnly)
|
||||
{
|
||||
TagsHelper.WriteTags(pluginMetaData, pluginMetaData.Filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("╟ ■ Read Only Mode: Not Modifying File ID3 Tags.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"╟ ≡ == ID3 Tag NOT Modified");
|
||||
Console.WriteLine($"╠╣ Directory Plugin Message: { pluginResult.Data }");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var oBad = originalMetaData == null;
|
||||
var pBad = pluginMetaData == null;
|
||||
Console.WriteLine($"╟ !! MetaData comparison skipped. { (oBad ? "Pre MetaData is Invalid" : "")} { (pBad ? "Post MetaData is Invalid" : "") }");
|
||||
}
|
||||
if (!pluginMetaData.IsValid)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"╟ ■■ INVALID: Missing: { ID3TagsHelper.DetermineMissingRequiredMetaData(pluginMetaData) }");
|
||||
Console.ResetColor();
|
||||
}
|
||||
else
|
||||
Console.WriteLine($"╠╝");
|
||||
Console.WriteLine($"╟─ Found [{ files.Length }] mp3 Files");
|
||||
List<AudioMetaData> fileMetaDatas = new List<AudioMetaData>();
|
||||
List<FileInfo> fileInfos = new List<FileInfo>();
|
||||
// Inspect the found MP3 files in 'directory'
|
||||
foreach (var file in files)
|
||||
{
|
||||
mp3FilesFoundCount++;
|
||||
var fileInfo = new FileInfo(file);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"╟─ 🎵 Inspecting [{ fileInfo.FullName }]");
|
||||
var tagLib = TagsHelper.MetaDataForFile(fileInfo.FullName, true);
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine($"╟ (Post) : { pluginMetaData }");
|
||||
if (!tagLib?.IsSuccess ?? false)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
}
|
||||
Console.WriteLine($"╟ (Pre ) : { tagLib.Data }");
|
||||
Console.ResetColor();
|
||||
|
||||
var artistToken = ArtistInspectorToken(tagLib.Data);
|
||||
if (!artistsFound.Contains(artistToken))
|
||||
tagLib.Data.Filename = fileInfo.FullName;
|
||||
var originalMetaData = tagLib.Data.Adapt<AudioMetaData>();
|
||||
var pluginMetaData = tagLib.Data;
|
||||
// Run all file plugins against the MP3 file modifying the MetaData
|
||||
foreach (var plugin in FilePlugins.OrderBy(x => x.Order))
|
||||
{
|
||||
artistsFound.Add(artistToken);
|
||||
}
|
||||
var releaseToken = ReleaseInspectorToken(tagLib.Data);
|
||||
if (!releasesFound.Contains(releaseToken))
|
||||
{
|
||||
releasesFound.Add(releaseToken);
|
||||
}
|
||||
var newFileName = $"CD{ (tagLib.Data.Disc ?? ID3TagsHelper.DetermineDiscNumber(tagLib.Data)).ToString("000") }_{ tagLib.Data.TrackNumber.Value.ToString("0000") }.mp3";
|
||||
// Artist sub folder is created to hold Releases for Artist and Artist Images
|
||||
var artistSubDirectory = directory == dest ? fileInfo.DirectoryName : Path.Combine(dest, artistToken);
|
||||
// Each release is put into a subfolder into the current run Inspector folder to hold MP3 Files and Release Images
|
||||
var subDirectory = directory == dest ? fileInfo.DirectoryName : Path.Combine(dest, artistToken, releaseToken);
|
||||
if (!isReadOnly && !Directory.Exists(subDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(subDirectory);
|
||||
}
|
||||
// Inspect images
|
||||
if (!inspectedImagesInDirectories.Contains(directoryInfo.FullName))
|
||||
{
|
||||
// Get all artist images and move to artist folder
|
||||
var foundArtistImages = new List<FileInfo>();
|
||||
foundArtistImages.AddRange(ImageHelper.FindImagesByName(directoryInfo.Parent, tagLib.Data.Artist, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo.Parent, Enums.ImageType.Artist, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo.Parent, Enums.ImageType.ArtistSecondary, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo, Enums.ImageType.Artist, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo, Enums.ImageType.ArtistSecondary, SearchOption.TopDirectoryOnly));
|
||||
|
||||
foreach (var artistImage in foundArtistImages)
|
||||
Console.WriteLine($"╟┤ Running File Plugin { plugin.Description }");
|
||||
OperationResult<AudioMetaData> pluginResult = null;
|
||||
pluginResult = plugin.Process(pluginMetaData);
|
||||
if (!pluginResult.IsSuccess)
|
||||
{
|
||||
InspectImage(isReadOnly, doCopy, dest, artistSubDirectory, artistImage);
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"📛 Plugin Failed: Error [{ JsonConvert.SerializeObject(pluginResult)}]");
|
||||
Console.ResetColor();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all release images and move to release folder
|
||||
var foundReleaseImages = new List<FileInfo>();
|
||||
foundReleaseImages.AddRange(ImageHelper.FindImagesByName(directoryInfo, tagLib.Data.Release, SearchOption.AllDirectories));
|
||||
foundReleaseImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo, Enums.ImageType.Release, SearchOption.AllDirectories));
|
||||
foundReleaseImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo, Enums.ImageType.ReleaseSecondary, SearchOption.AllDirectories));
|
||||
foreach (var foundReleaseImage in foundReleaseImages)
|
||||
{
|
||||
InspectImage(isReadOnly, doCopy, dest, subDirectory, foundReleaseImage);
|
||||
}
|
||||
inspectedImagesInDirectories.Add(directoryInfo.FullName);
|
||||
pluginMetaData = pluginResult.Data;
|
||||
}
|
||||
// If enabled move MP3 to new folder
|
||||
var newPath = Path.Combine(dest, subDirectory, newFileName.ToFileNameFriendly());
|
||||
if (isReadOnly)
|
||||
// See if the MetaData from the Plugins is different from the original
|
||||
if (originalMetaData != null && pluginMetaData != null)
|
||||
{
|
||||
Console.WriteLine($"╟ ■ Read Only Mode: File would be [{ (doCopy ? "Copied" : "Moved") }] to [{ newPath }]");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!doCopy)
|
||||
var differences = AutoCompare.Comparer.Compare(originalMetaData, pluginMetaData);
|
||||
if (differences.Any())
|
||||
{
|
||||
if (fileInfo.FullName != newPath)
|
||||
var skipDifferences = new List<string> { "AudioMetaDataWeights", "FileInfo", "Images", "TrackArtists", "ValidWeight" };
|
||||
var differencesDescription = $"{ System.Environment.NewLine }";
|
||||
foreach (var difference in differences)
|
||||
{
|
||||
if (File.Exists(newPath))
|
||||
if (skipDifferences.Contains(difference.Name))
|
||||
{
|
||||
File.Delete(newPath);
|
||||
continue;
|
||||
}
|
||||
fileInfo.MoveTo(newPath);
|
||||
differencesDescription += $"╟ || { difference.Name } : Was [{ difference.OldValue}] Now [{ difference.NewValue}]{ System.Environment.NewLine }";
|
||||
}
|
||||
Console.Write($"╟ ≡ != ID3 Tag Modified: { differencesDescription }");
|
||||
|
||||
if (!isReadOnly)
|
||||
{
|
||||
TagsHelper.WriteTags(pluginMetaData, pluginMetaData.Filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("╟ 🔒 Read Only Mode: Not Modifying File ID3 Tags.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileInfo.CopyTo(newPath, true);
|
||||
Console.WriteLine($"╟ ≡ == ID3 Tag NOT Modified");
|
||||
}
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($"╠═» { (doCopy ? "Copied" : "Moved")} MP3 File to [{ newPath }]");
|
||||
}
|
||||
else
|
||||
{
|
||||
var oBad = originalMetaData == null;
|
||||
var pBad = pluginMetaData == null;
|
||||
Console.WriteLine($"╟ !! MetaData comparison skipped. { (oBad ? "Pre MetaData is Invalid" : "")} { (pBad ? "Post MetaData is Invalid" : "") }");
|
||||
}
|
||||
if (!pluginMetaData.IsValid)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"╟ ❗ INVALID: Missing: { ID3TagsHelper.DetermineMissingRequiredMetaData(pluginMetaData) }");
|
||||
Console.ResetColor();
|
||||
}
|
||||
Console.WriteLine("╠════════════════════════╣");
|
||||
else
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine($"╟ (Post) : { pluginMetaData }");
|
||||
Console.ResetColor();
|
||||
|
||||
var artistToken = ArtistInspectorToken(tagLib.Data);
|
||||
if (!artistsFound.Contains(artistToken))
|
||||
{
|
||||
artistsFound.Add(artistToken);
|
||||
}
|
||||
var releaseToken = ReleaseInspectorToken(tagLib.Data);
|
||||
if (!releasesFound.Contains(releaseToken))
|
||||
{
|
||||
releasesFound.Add(releaseToken);
|
||||
}
|
||||
var newFileName = $"CD{ (tagLib.Data.Disc ?? ID3TagsHelper.DetermineDiscNumber(tagLib.Data)).ToString("000") }_{ tagLib.Data.TrackNumber.Value.ToString("0000") }.mp3";
|
||||
// Artist sub folder is created to hold Releases for Artist and Artist Images
|
||||
var artistSubDirectory = directory == dest ? fileInfo.DirectoryName : Path.Combine(dest, artistToken);
|
||||
// Each release is put into a subfolder into the current run Inspector folder to hold MP3 Files and Release Images
|
||||
var subDirectory = directory == dest ? fileInfo.DirectoryName : Path.Combine(dest, artistToken, releaseToken);
|
||||
if (!isReadOnly && !Directory.Exists(subDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(subDirectory);
|
||||
}
|
||||
// Inspect images
|
||||
if (!inspectedImagesInDirectories.Contains(directoryInfo.FullName))
|
||||
{
|
||||
// Get all artist images and move to artist folder
|
||||
var foundArtistImages = new List<FileInfo>();
|
||||
foundArtistImages.AddRange(ImageHelper.FindImagesByName(directoryInfo, tagLib.Data.Artist, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImagesByName(directoryInfo.Parent, tagLib.Data.Artist, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo.Parent, Enums.ImageType.Artist, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo.Parent, Enums.ImageType.ArtistSecondary, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo, Enums.ImageType.Artist, SearchOption.TopDirectoryOnly));
|
||||
foundArtistImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo, Enums.ImageType.ArtistSecondary, SearchOption.TopDirectoryOnly));
|
||||
|
||||
foreach (var artistImage in foundArtistImages)
|
||||
{
|
||||
InspectImage(isReadOnly, doCopy, dest, artistSubDirectory, artistImage);
|
||||
}
|
||||
|
||||
// Get all release images and move to release folder
|
||||
var foundReleaseImages = new List<FileInfo>();
|
||||
foundReleaseImages.AddRange(ImageHelper.FindImagesByName(directoryInfo, tagLib.Data.Release, SearchOption.AllDirectories));
|
||||
foundReleaseImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo, Enums.ImageType.Release, SearchOption.AllDirectories));
|
||||
foundReleaseImages.AddRange(ImageHelper.FindImageTypeInDirectory(directoryInfo, Enums.ImageType.ReleaseSecondary, SearchOption.AllDirectories));
|
||||
foreach (var foundReleaseImage in foundReleaseImages)
|
||||
{
|
||||
InspectImage(isReadOnly, doCopy, dest, subDirectory, foundReleaseImage);
|
||||
}
|
||||
inspectedImagesInDirectories.Add(directoryInfo.FullName);
|
||||
}
|
||||
// If enabled move MP3 to new folder
|
||||
var newPath = Path.Combine(dest, subDirectory, newFileName.ToFileNameFriendly());
|
||||
if (isReadOnly)
|
||||
{
|
||||
Console.WriteLine($"╟ 🔒 Read Only Mode: File would be [{ (doCopy ? "Copied" : "Moved") }] to [{ newPath }]");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!doCopy)
|
||||
{
|
||||
if (fileInfo.FullName != newPath)
|
||||
{
|
||||
if (File.Exists(newPath))
|
||||
{
|
||||
File.Delete(newPath);
|
||||
}
|
||||
fileInfo.MoveTo(newPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileInfo.CopyTo(newPath, true);
|
||||
}
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($"╠═ 🚛 { (doCopy ? "Copied" : "Moved")} MP3 File to [{ newPath }]");
|
||||
Console.ResetColor();
|
||||
}
|
||||
Console.WriteLine("╠════════════════════════╣");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Run post-processing directory plugins against current directory
|
||||
|
@ -391,7 +410,7 @@ namespace Roadie.Library.Inspect
|
|||
var pluginResult = plugin.Process(directoryInfo);
|
||||
if (!pluginResult.IsSuccess)
|
||||
{
|
||||
Console.WriteLine($"Plugin Failed: Error [{ JsonConvert.SerializeObject(pluginResult)}]");
|
||||
Console.WriteLine($"📛 Plugin Failed: Error [{ JsonConvert.SerializeObject(pluginResult)}]");
|
||||
return;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(pluginResult.Data))
|
||||
|
@ -407,20 +426,56 @@ namespace Roadie.Library.Inspect
|
|||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex);
|
||||
Console.WriteLine("!! Exception: " + ex.ToString());
|
||||
Console.WriteLine("📛 Exception: " + ex.ToString());
|
||||
}
|
||||
if (!dontDeleteEmptyFolders)
|
||||
{
|
||||
var delEmptyFolderIn = new DirectoryInfo(directoryToInspect);
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine($"X Deleting Empty folders in [{ delEmptyFolderIn.FullName }]");
|
||||
Console.WriteLine($"❌ Deleting Empty folders in [{ delEmptyFolderIn.FullName }]");
|
||||
Console.ResetColor();
|
||||
FolderPathHelper.DeleteEmptyDirs(directoryToInspect, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("X ■ Read Only Mode: Not deleting empty folders.");
|
||||
Console.WriteLine("🔒 Read Only Mode: Not deleting empty folders.");
|
||||
}
|
||||
// Run PreInspect script
|
||||
scriptResult = RunScript(Configuration.Processing.PostInspectScript, doCopy, isReadOnly, directoryToInspect, destination);
|
||||
if (!string.IsNullOrEmpty(scriptResult))
|
||||
{
|
||||
Console.BackgroundColor = ConsoleColor.Blue;
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine($"PostInspectScript Results: { Environment.NewLine + scriptResult + Environment.NewLine }");
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
|
||||
private string RunScript(string scriptFilename, bool doCopy, bool isReadOnly, string directoryToInspect, string dest)
|
||||
{
|
||||
if(string.IsNullOrEmpty(scriptFilename))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
var script = File.ReadAllText(scriptFilename);
|
||||
using (var ps = PowerShell.Create())
|
||||
{
|
||||
var r = "";
|
||||
var results = ps.AddScript(script).Invoke();
|
||||
foreach (var result in results)
|
||||
{
|
||||
r += result.ToString() + System.Environment.NewLine;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"📛 Error with Script File [{scriptFilename}], Error [{ ex.ToString() }] ");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void InspectImage(bool isReadOnly, bool doCopy, string dest, string subdirectory, FileInfo image)
|
||||
|
@ -433,7 +488,13 @@ namespace Roadie.Library.Inspect
|
|||
return;
|
||||
}
|
||||
Console.WriteLine($"╟─ Inspecting Image [{ image.FullName }]");
|
||||
var newImageFolder = new DirectoryInfo(Path.Combine(dest, subdirectory));
|
||||
if(!newImageFolder.Exists)
|
||||
{
|
||||
newImageFolder.Create();
|
||||
}
|
||||
var newImagePath = Path.Combine(dest, subdirectory, image.Name);
|
||||
|
||||
if (image.FullName != newImagePath)
|
||||
{
|
||||
var looper = 0;
|
||||
|
@ -444,25 +505,60 @@ namespace Roadie.Library.Inspect
|
|||
}
|
||||
if (isReadOnly)
|
||||
{
|
||||
Console.WriteLine($"╟ ■ Read Only Mode: Would be [{ (doCopy ? "Copied" : "Moved") }] to [{ newImagePath }]");
|
||||
Console.WriteLine($"╟ 🔒 Read Only Mode: Would be [{ (doCopy ? "Copied" : "Moved") }] to [{ newImagePath }]");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!doCopy)
|
||||
try
|
||||
{
|
||||
image.MoveTo(newImagePath);
|
||||
if (!doCopy)
|
||||
{
|
||||
image.MoveTo(newImagePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
image.CopyTo(newImagePath, true);
|
||||
}
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($"╠═ 🚛 { (doCopy ? "Copied" : "Moved")} Image File to [{ newImagePath }]");
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
image.CopyTo(newImagePath, true);
|
||||
Logger.LogError(ex);
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"📛 Error file [{ image.FullName }], newImagePath [{ newImagePath }], Exception: [{ ex.ToString() }]");
|
||||
}
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($"╠═» { (doCopy ? "Copied" : "Moved")} Image File to [{ newImagePath }]");
|
||||
}
|
||||
}
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
private void MessageLogger_Messages(object sender, EventMessage e) => Console.WriteLine($"Log Level [{ e.Level }] Log Message [{ e.Message }] ");
|
||||
private void MessageLogger_Messages(object sender, EventMessage e)
|
||||
{
|
||||
Console.WriteLine($"Log Level [{ e.Level }] Log Message [{ e.Message }] ");
|
||||
var message = e.Message;
|
||||
switch (e.Level)
|
||||
{
|
||||
case LogLevel.Trace:
|
||||
this.Logger.LogTrace(message);
|
||||
break;
|
||||
|
||||
case LogLevel.Debug:
|
||||
this.Logger.LogDebug(message);
|
||||
break;
|
||||
|
||||
case LogLevel.Information:
|
||||
this.Logger.LogInformation(message);
|
||||
break;
|
||||
|
||||
case LogLevel.Warning:
|
||||
this.Logger.LogWarning(message);
|
||||
break;
|
||||
|
||||
case LogLevel.Critical:
|
||||
this.Logger.LogCritical(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ using Roadie.Library.Utility;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Roadie.Library.Models
|
||||
|
@ -23,13 +24,12 @@ namespace Roadie.Library.Models
|
|||
{
|
||||
if (this._alternateNamesList == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.AlternateNames))
|
||||
if (!string.IsNullOrEmpty(this.AlternateNames))
|
||||
{
|
||||
return null;
|
||||
this._alternateNamesList = this.AlternateNames.Split('|');
|
||||
}
|
||||
return this.AlternateNames.Split('|');
|
||||
}
|
||||
return this._alternateNamesList;
|
||||
return this._alternateNamesList ?? Enumerable.Empty<string>();
|
||||
}
|
||||
set
|
||||
{
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using Roadie.Library.Enums;
|
||||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -98,7 +100,14 @@ namespace Roadie.Library.Models.Pagination
|
|||
return result.ToString();
|
||||
}
|
||||
|
||||
public bool? FilterOnlyMissing { get; set; }
|
||||
public short? FilterToStatus { get; set; }
|
||||
public Statuses FilterToStatusValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return SafeParser.ToEnum<Statuses>(FilterToStatus);
|
||||
}
|
||||
}
|
||||
|
||||
public Guid? FilterToArtistId { get; set; }
|
||||
public Guid? FilterToReleaseId { get; set; }
|
||||
|
|
|
@ -11,17 +11,18 @@
|
|||
<PackageReference Include="AutoCompare.Core" Version="1.0.0" />
|
||||
<PackageReference Include="CsvHelper" Version="12.1.2" />
|
||||
<PackageReference Include="EFCore.BulkExtensions" Version="2.4.7" />
|
||||
<PackageReference Include="FluentFTP" Version="25.0.1" />
|
||||
<PackageReference Include="FluentFTP" Version="25.0.3" />
|
||||
<PackageReference Include="Hashids.net" Version="1.2.2" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.7" />
|
||||
<PackageReference Include="IdSharp.Common" Version="1.0.1" />
|
||||
<PackageReference Include="IdSharp.Tagging" Version="1.0.0-rc3" />
|
||||
<PackageReference Include="Inflatable.Lastfm" Version="1.1.0.339" />
|
||||
<PackageReference Include="Mapster" Version="4.0.0" />
|
||||
<PackageReference Include="Mapster" Version="4.1.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.PowerShell.5.ReferenceAssemblies" Version="1.1.0" />
|
||||
<PackageReference Include="MimeMapping" Version="1.0.1.12" />
|
||||
<PackageReference Include="NodaTime" Version="2.4.5" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
@ -484,31 +485,37 @@ namespace Roadie.Api.Services
|
|||
});
|
||||
}
|
||||
|
||||
public async Task<OperationResult<bool>> ScanAllCollections(ApplicationUser user, bool isReadOnly = false, bool doPurgeFirst = true)
|
||||
public async Task<OperationResult<bool>> ScanAllCollections(ApplicationUser user, bool isReadOnly = false, bool doPurgeFirst = false)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
var errors = new List<Exception>();
|
||||
|
||||
var collections = this.DbContext.Collections.Where(x => x.Status != Statuses.Complete).ToArray();
|
||||
var collections = this.DbContext.Collections.Where(x => x.IsLocked == false).ToArray();
|
||||
var updatedReleaseIds = new List<int>();
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await this.ScanCollection(user, collection.RoadieId, isReadOnly, doPurgeFirst);
|
||||
var result = await this.ScanCollection(user, collection.RoadieId, isReadOnly, doPurgeFirst, false);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
errors.AddRange(result.Errors);
|
||||
}
|
||||
updatedReleaseIds.AddRange((int[])result.AdditionalData["updatedReleaseIds"]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex);
|
||||
await this.LogAndPublish(ex.ToString(), LogLevel.Error);
|
||||
errors.Add(ex);
|
||||
}
|
||||
}
|
||||
foreach (var updatedReleaseId in updatedReleaseIds.Distinct())
|
||||
{
|
||||
await this.UpdateReleaseRank(updatedReleaseId);
|
||||
}
|
||||
sw.Stop();
|
||||
this.Logger.LogInformation(string.Format("ScanAllCollections, By User `{0}`", user));
|
||||
await this.LogAndPublish($"ScanAllCollections, By User `{user}`, Updated Release Count [{ updatedReleaseIds.Distinct().Count() }], ElapsedTime [{ sw.ElapsedMilliseconds}]", LogLevel.Information);
|
||||
return new OperationResult<bool>
|
||||
{
|
||||
IsSuccess = !errors.Any(),
|
||||
|
@ -561,12 +568,13 @@ namespace Roadie.Api.Services
|
|||
};
|
||||
}
|
||||
|
||||
public async Task<OperationResult<bool>> ScanCollection(ApplicationUser user, Guid collectionId, bool isReadOnly = false, bool doPurgeFirst = true)
|
||||
public async Task<OperationResult<bool>> ScanCollection(ApplicationUser user, Guid collectionId, bool isReadOnly = false, bool doPurgeFirst = false, bool doUpdateRanks = true)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
CollectionRelease[] crs = new CollectionRelease[0];
|
||||
var releaseIdsInCollection = new List<int>();
|
||||
var updatedReleaseIds = new List<int>();
|
||||
var result = new List<PositionArtistRelease>();
|
||||
var errors = new List<Exception>();
|
||||
var collection = this.DbContext.Collections.FirstOrDefault(x => x.RoadieId == collectionId);
|
||||
|
@ -579,7 +587,8 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
if (doPurgeFirst)
|
||||
{
|
||||
crs = this.DbContext.CollectionReleases.Where(x => x.CollectionId == collection.Id).ToArray();
|
||||
await this.LogAndPublish($"ScanCollection Purgeing Collection [{ collectionId}]", LogLevel.Warning);
|
||||
var crs = this.DbContext.CollectionReleases.Where(x => x.CollectionId == collection.Id).ToArray();
|
||||
this.DbContext.CollectionReleases.RemoveRange(crs);
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
}
|
||||
|
@ -603,7 +612,7 @@ namespace Roadie.Api.Services
|
|||
select a).ToArray();
|
||||
if (!artistResults.Any())
|
||||
{
|
||||
this.Logger.LogWarning("Unable To Find Artist [{0}], SearchName [{1}]", csvRelease.Artist, searchName);
|
||||
await this.LogAndPublish($"Unable To Find Artist [{csvRelease.Artist }], SearchName [{ searchName}]", LogLevel.Warning);
|
||||
csvRelease.Status = Library.Enums.Statuses.Missing;
|
||||
continue;
|
||||
}
|
||||
|
@ -626,13 +635,14 @@ namespace Roadie.Api.Services
|
|||
}
|
||||
if (release == null)
|
||||
{
|
||||
this.Logger.LogWarning("Unable To Find Release [{0}], SearchName [{1}]", csvRelease.Release, searchName);
|
||||
await this.LogAndPublish($"Unable To Find Release [{csvRelease.Release}] for Artist [{csvRelease.Artist}], SearchName [{searchName}]", LogLevel.Warning );
|
||||
csvRelease.Status = Library.Enums.Statuses.Missing;
|
||||
continue;
|
||||
}
|
||||
var isInCollection = this.DbContext.CollectionReleases.FirstOrDefault(x => x.CollectionId == collection.Id &&
|
||||
x.ListNumber == csvRelease.Position &&
|
||||
x.ReleaseId == release.Id);
|
||||
var updated = false;
|
||||
// Found in Database but not in collection add to Collection
|
||||
if (isInCollection == null)
|
||||
{
|
||||
|
@ -642,13 +652,20 @@ namespace Roadie.Api.Services
|
|||
ReleaseId = release.Id,
|
||||
ListNumber = csvRelease.Position,
|
||||
});
|
||||
updated = true;
|
||||
}
|
||||
// If Item in Collection is at different List number update CollectionRelease
|
||||
else if (isInCollection.ListNumber != csvRelease.Position)
|
||||
{
|
||||
isInCollection.LastUpdated = now;
|
||||
isInCollection.ListNumber = csvRelease.Position;
|
||||
updated = true;
|
||||
}
|
||||
if(updated && !updatedReleaseIds.Any(x => x == release.Id))
|
||||
{
|
||||
updatedReleaseIds.Add(release.Id);
|
||||
}
|
||||
releaseIdsInCollection.Add(release.Id);
|
||||
}
|
||||
collection.LastUpdated = now;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
|
@ -669,10 +686,22 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
collection.Status = Statuses.Incomplete;
|
||||
}
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
foreach (var cr in crs)
|
||||
var collectionReleasesToRemove = (from cr in this.DbContext.CollectionReleases
|
||||
where cr.CollectionId == collection.Id
|
||||
where !releaseIdsInCollection.Contains(cr.ReleaseId)
|
||||
select cr).ToArray();
|
||||
if (collectionReleasesToRemove.Any())
|
||||
{
|
||||
await this.UpdateReleaseRank(cr.ReleaseId);
|
||||
await this.LogAndPublish($"Removing [{ collectionReleasesToRemove.Count() }] Stale Release Records from Collection.", LogLevel.Information);
|
||||
this.DbContext.CollectionReleases.RemoveRange(collectionReleasesToRemove);
|
||||
}
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
if (doUpdateRanks)
|
||||
{
|
||||
foreach(var updatedReleaseId in updatedReleaseIds)
|
||||
{
|
||||
await this.UpdateReleaseRank(updatedReleaseId);
|
||||
}
|
||||
}
|
||||
this.CacheManager.ClearRegion(collection.CacheRegion);
|
||||
}
|
||||
|
@ -687,6 +716,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
return new OperationResult<bool>
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object> { { "updatedReleaseIds", updatedReleaseIds.ToArray() } },
|
||||
IsSuccess = !errors.Any(),
|
||||
Data = true,
|
||||
OperationTime = sw.ElapsedMilliseconds,
|
||||
|
|
|
@ -147,7 +147,7 @@ namespace Roadie.Api.Services
|
|||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
int[] favoriteArtistIds = new int[0];
|
||||
IQueryable<int> favoriteArtistIds = null;
|
||||
if (request.FilterFavoriteOnly)
|
||||
{
|
||||
favoriteArtistIds = (from a in this.DbContext.Artists
|
||||
|
@ -155,9 +155,9 @@ namespace Roadie.Api.Services
|
|||
where ua.IsFavorite ?? false
|
||||
where (roadieUser == null || ua.UserId == roadieUser.Id)
|
||||
select a.Id
|
||||
).ToArray();
|
||||
);
|
||||
}
|
||||
int[] labelArtistIds = new int[0];
|
||||
IQueryable<int> labelArtistIds = null;
|
||||
if (request.FilterToLabelId.HasValue)
|
||||
{
|
||||
labelArtistIds = (from l in this.DbContext.Labels
|
||||
|
@ -165,10 +165,9 @@ namespace Roadie.Api.Services
|
|||
join r in this.DbContext.Releases on rl.ReleaseId equals r.Id
|
||||
where l.RoadieId == request.FilterToLabelId
|
||||
select r.ArtistId)
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
.Distinct();
|
||||
}
|
||||
int[] genreArtistIds = new int[0];
|
||||
IQueryable<int> genreArtistIds = null;
|
||||
var isFilteredToGenre = false;
|
||||
if (!string.IsNullOrEmpty(request.Filter) && request.Filter.StartsWith(":genre", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
@ -177,8 +176,7 @@ namespace Roadie.Api.Services
|
|||
join g in this.DbContext.Genres on ag.GenreId equals g.Id
|
||||
where g.Name.Contains(genreFilter)
|
||||
select ag.ArtistId)
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
.Distinct();
|
||||
isFilteredToGenre = true;
|
||||
request.Filter = null;
|
||||
}
|
||||
|
@ -278,14 +276,17 @@ namespace Roadie.Api.Services
|
|||
sw.Stop();
|
||||
if (!string.IsNullOrEmpty(request.Filter) && rowCount == 0)
|
||||
{
|
||||
// Create request for no artist found
|
||||
var req = new data.Request
|
||||
if (Configuration.RecordNoResultSearches)
|
||||
{
|
||||
UserId = roadieUser?.Id,
|
||||
Description = request.Filter
|
||||
};
|
||||
this.DbContext.Requests.Add(req);
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
// Create request for no artist found
|
||||
var req = new data.Request
|
||||
{
|
||||
UserId = roadieUser?.Id,
|
||||
Description = request.Filter
|
||||
};
|
||||
this.DbContext.Requests.Add(req);
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return new Library.Models.Pagination.PagedResult<ArtistList>
|
||||
{
|
||||
|
@ -465,7 +466,13 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var originalArtistFolder = artist.ArtistFileFolder(this.Configuration, this.Configuration.LibraryFolder);
|
||||
artist.AlternateNames = model.AlternateNamesList.ToDelimitedList();
|
||||
var specialArtistName = model.Name.ToAlphanumericName();
|
||||
var alt = new List<string>(model.AlternateNamesList);
|
||||
if (!model.AlternateNamesList.Contains(specialArtistName, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
alt.Add(specialArtistName);
|
||||
}
|
||||
artist.AlternateNames = alt.ToDelimitedList();
|
||||
artist.ArtistType = model.ArtistType;
|
||||
artist.AmgId = model.AmgId;
|
||||
artist.BeginDate = model.BeginDate;
|
||||
|
|
|
@ -170,12 +170,17 @@ namespace Roadie.Api.Services
|
|||
}
|
||||
var result = (from c in collections
|
||||
where (request.FilterValue.Length == 0 || (request.FilterValue.Length > 0 && c.Name.Contains(request.Filter)))
|
||||
where (request.FilterToStatusValue == Statuses.Ok || (c.Status == request.FilterToStatusValue))
|
||||
select CollectionList.FromDataCollection(c, (from crc in this.DbContext.CollectionReleases
|
||||
where crc.CollectionId == c.Id
|
||||
select crc.Id).Count(), this.MakeCollectionThumbnailImage(c.RoadieId)));
|
||||
var sortBy = string.IsNullOrEmpty(request.Sort) ? request.OrderValue(new Dictionary<string, string> { { "Collection.Text", "ASC" } }) : request.OrderValue(null);
|
||||
var rowCount = result.Count();
|
||||
var rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
if (request.FilterToStatusValue == Statuses.Incomplete)
|
||||
{
|
||||
rows = rows.OrderByDescending(x => x.PercentComplete).ThenBy(x => x.SortName).ToArray();
|
||||
}
|
||||
sw.Stop();
|
||||
return Task.FromResult(new Library.Models.Pagination.PagedResult<CollectionList>
|
||||
{
|
||||
|
|
|
@ -27,11 +27,11 @@ namespace Roadie.Api.Services
|
|||
|
||||
Task<OperationResult<Dictionary<string, List<string>>>> MissingCollectionReleases(ApplicationUser user);
|
||||
|
||||
Task<OperationResult<bool>> ScanAllCollections(ApplicationUser user, bool isReadOnly = false, bool doPurgeFirst = true);
|
||||
Task<OperationResult<bool>> ScanAllCollections(ApplicationUser user, bool isReadOnly = false, bool doPurgeFirst = false);
|
||||
|
||||
Task<OperationResult<bool>> ScanArtist(ApplicationUser user, Guid artistId, bool isReadOnly = false);
|
||||
|
||||
Task<OperationResult<bool>> ScanCollection(ApplicationUser user, Guid collectionId, bool isReadOnly = false, bool doPurgeFirst = true);
|
||||
Task<OperationResult<bool>> ScanCollection(ApplicationUser user, Guid collectionId, bool isReadOnly = false, bool doPurgeFirst = false, bool doUpdateRanks = true);
|
||||
|
||||
Task<OperationResult<bool>> ScanInboundFolder(ApplicationUser user, bool isReadOnly = false);
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ namespace Roadie.Api.Services
|
|||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
IEnumerable<int> collectionReleaseIds = null;
|
||||
IQueryable<int> collectionReleaseIds = null;
|
||||
if (request.FilterToCollectionId.HasValue)
|
||||
{
|
||||
collectionReleaseIds = (from cr in this.DbContext.CollectionReleases
|
||||
|
@ -177,9 +177,9 @@ namespace Roadie.Api.Services
|
|||
join r in this.DbContext.Releases on cr.ReleaseId equals r.Id
|
||||
where c.RoadieId == request.FilterToCollectionId.Value
|
||||
orderby cr.ListNumber
|
||||
select r.Id).ToArray();
|
||||
select r.Id);
|
||||
}
|
||||
int[] favoriteReleaseIds = new int[0];
|
||||
IQueryable<int> favoriteReleaseIds = null;
|
||||
if (request.FilterFavoriteOnly)
|
||||
{
|
||||
favoriteReleaseIds = (from a in this.DbContext.Releases
|
||||
|
@ -187,9 +187,9 @@ namespace Roadie.Api.Services
|
|||
where ur.IsFavorite ?? false
|
||||
where (roadieUser == null || ur.UserId == roadieUser.Id)
|
||||
select a.Id
|
||||
).ToArray();
|
||||
);
|
||||
}
|
||||
int[] genreReleaseIds = new int[0];
|
||||
IQueryable<int> genreReleaseIds = null;
|
||||
var isFilteredToGenre = false;
|
||||
if (!string.IsNullOrEmpty(request.FilterByGenre) || (!string.IsNullOrEmpty(request.Filter) && request.Filter.StartsWith(":genre", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
|
@ -198,8 +198,7 @@ namespace Roadie.Api.Services
|
|||
join g in this.DbContext.Genres on rg.GenreId equals g.Id
|
||||
where g.Name.Contains(genreFilter)
|
||||
select rg.ReleaseId)
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
.Distinct();
|
||||
request.Filter = null;
|
||||
isFilteredToGenre = true;
|
||||
}
|
||||
|
@ -384,6 +383,7 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
Text = par.Release
|
||||
},
|
||||
Status = Statuses.Missing,
|
||||
CssClass = "missing",
|
||||
ArtistThumbnail = new Library.Models.Image($"{this.HttpContext.ImageBaseUrl }/unknown.jpg"),
|
||||
Thumbnail = new Library.Models.Image($"{this.HttpContext.ImageBaseUrl }/unknown.jpg"),
|
||||
|
@ -392,6 +392,10 @@ namespace Roadie.Api.Services
|
|||
}
|
||||
}
|
||||
// Resort the list for the collection by listNumber
|
||||
if (request.FilterToStatusValue != Statuses.Ok)
|
||||
{
|
||||
newRows = newRows.Where(x => x.Status == request.FilterToStatusValue).ToList();
|
||||
}
|
||||
rows = newRows.OrderBy(x => x.ListNumber).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
rowCount = collection.CollectionCount;
|
||||
}
|
||||
|
@ -614,7 +618,13 @@ namespace Roadie.Api.Services
|
|||
release.IsVirtual = model.IsVirtual;
|
||||
release.Status = SafeParser.ToEnum<Statuses>(model.Status);
|
||||
release.Title = model.Title;
|
||||
release.AlternateNames = model.AlternateNamesList.ToDelimitedList();
|
||||
var specialReleaseTitle = model.Title.ToAlphanumericName();
|
||||
var alt = new List<string>(model.AlternateNamesList);
|
||||
if (!model.AlternateNamesList.Contains(specialReleaseTitle, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
alt.Add(specialReleaseTitle);
|
||||
}
|
||||
release.AlternateNames = alt.ToDelimitedList();
|
||||
release.ReleaseDate = model.ReleaseDate;
|
||||
release.Rating = model.Rating;
|
||||
release.TrackCount = model.TrackCount;
|
||||
|
@ -682,7 +692,6 @@ namespace Roadie.Api.Services
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (model.Genres != null && model.Genres.Any())
|
||||
{
|
||||
// Remove existing Genres not in model list
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="2.2.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.4.0" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.16" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.17" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -203,7 +203,7 @@ namespace Roadie.Api.Services
|
|||
select t.Id).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
}
|
||||
|
||||
int[] topTrackids = new int[0];
|
||||
IQueryable<int> topTrackids = null;
|
||||
if (request.FilterTopPlayedOnly)
|
||||
{
|
||||
// Get request number of top played songs for artist
|
||||
|
@ -215,7 +215,7 @@ namespace Roadie.Api.Services
|
|||
where a.RoadieId == request.FilterToArtistId
|
||||
orderby ut.PlayedCount descending
|
||||
select t.Id
|
||||
).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
).Skip(request.SkipValue).Take(request.LimitValue);
|
||||
}
|
||||
int[] randomTrackIds = null;
|
||||
if (doRandomize ?? false)
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace Roadie.Api
|
|||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var dbFilename = Path.Combine("logs", "errors.db");
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.ReadFrom.Configuration(Configuration)
|
||||
.CreateLogger();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"Roadie.Api": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
"ASPNETCORE_ENVIRONMENT": "Production"
|
||||
},
|
||||
"applicationUrl": "http://localhost:5123/"
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.OData" Version="7.1.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="5.0.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="5.2.0" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.RollingFileAlternate" Version="2.0.9" />
|
||||
|
|
Loading…
Add table
Reference in a new issue