mirror of
https://github.com/fiso64/slsk-batchdl.git
synced 2024-12-22 22:42:41 +00:00
commit
This commit is contained in:
parent
11579385a9
commit
c5806e5d24
2 changed files with 138 additions and 52 deletions
11
README.md
11
README.md
|
@ -250,14 +250,9 @@ Files satisfying `pref-` conditions will be preferred; setting `--pref-format "f
|
||||||
**Important note**: Some info may be unavailable depending on the client used by the peer. For example, the default Soulseek client does not share the file bitrate. By default, if `--min-bitrate` is set, then files with unknown bitrate will still be downloaded. You can configure it to reject all files where one of the checked properties is unavailable by enabling `--strict-conditions`. (As a consequence, if `--min-bitrate` is also set then any files shared by users with the default client will be ignored)
|
**Important note**: Some info may be unavailable depending on the client used by the peer. For example, the default Soulseek client does not share the file bitrate. By default, if `--min-bitrate` is set, then files with unknown bitrate will still be downloaded. You can configure it to reject all files where one of the checked properties is unavailable by enabling `--strict-conditions`. (As a consequence, if `--min-bitrate` is also set then any files shared by users with the default client will be ignored)
|
||||||
|
|
||||||
### Name format
|
### Name format
|
||||||
Available tags are: artist, artists, album_artist, album_artists, title, album, year, track, disc, filename, default_foldername. Name format supports subdirectories as well as conditional expressions: `{str1|str2}` – If any tags in str1 are null, choose str2. String literals enclosed in parentheses are ignored in the null check.
|
Variables enclosed in {} will be replaced by the corresponding file tag value. Available variables are: artist, sartist, artists, albumartist, albumartists, title, stitle, album, salbum, year, track, disc, filename, foldername. The variables sartist, stitle and salbum will be replaced by the source artist, title and album respectively (i.e what is shown in spotify/youtube/csv file) instead of the tag values of the downloaded file. Name format supports subdirectories as well as conditional expressions like `{tag1|tag2}` – If tag1 is null, choose tag2. String literals enclosed in parentheses are ignored in the null check. Examples:
|
||||||
```
|
- `{artist} - {title}`: Always name it 'Artist - Title'. Because some files on Soulseek do not have tags, the second example is preferred:
|
||||||
{artist( - )title|album_artist( - )title|filename}
|
- `{artist( - )title|filename}`: If artist and title is not null, name it 'Artist - Title', otherwise use the original filename.
|
||||||
```
|
|
||||||
```
|
|
||||||
{album(/)}{track(. )}{artist|(unknown artist)} - {title|(unknown title)}
|
|
||||||
```
|
|
||||||
Here `{album(/)}` will conditionally put the download into a subfolder; if the album tag is null, then the slash won't be added to the path. An alternative is `{album|(missing album)}/` which will save all songs with unknown album under `missing album`.
|
|
||||||
|
|
||||||
### Quality vs Speed
|
### Quality vs Speed
|
||||||
The following options will make it go faster, but may decrease search result quality or cause instability:
|
The following options will make it go faster, but may decrease search result quality or cause instability:
|
||||||
|
|
|
@ -23,7 +23,7 @@ using SlDictionary = System.Collections.Concurrent.ConcurrentDictionary<string,
|
||||||
|
|
||||||
// undocumented options
|
// undocumented options
|
||||||
// --on-complete
|
// --on-complete
|
||||||
// --artist-col, --title-col, --album-col, --length-col, --yt-desc-col, --yt-id-col
|
// --artist-col, --title-col, --album-col, --length-col, --yt-desc-col, --yt-id-col, --album-track-count-col
|
||||||
// --input-type, --login, --random-login, --no-modify-share-count --fast-search-delay,
|
// --input-type, --login, --random-login, --no-modify-share-count --fast-search-delay,
|
||||||
// --fails-to-deprioritize (=1), --fails-to-ignore (=2)
|
// --fails-to-deprioritize (=1), --fails-to-ignore (=2)
|
||||||
// --cond, --pref, --danger-words, --pref-danger-words, --strict-title, --strict-artist, --strict-album
|
// --cond, --pref, --danger-words, --pref-danger-words, --strict-title, --strict-artist, --strict-album
|
||||||
|
@ -77,6 +77,7 @@ static class Program
|
||||||
static string trackCol = "";
|
static string trackCol = "";
|
||||||
static string ytIdCol = "";
|
static string ytIdCol = "";
|
||||||
static string descCol = "";
|
static string descCol = "";
|
||||||
|
static string trackCountCol = "";
|
||||||
static string lengthCol = "";
|
static string lengthCol = "";
|
||||||
static bool aggregate = false;
|
static bool aggregate = false;
|
||||||
static bool album = false;
|
static bool album = false;
|
||||||
|
@ -470,6 +471,9 @@ static class Program
|
||||||
case "--yt-desc-col":
|
case "--yt-desc-col":
|
||||||
descCol = args[++i];
|
descCol = args[++i];
|
||||||
break;
|
break;
|
||||||
|
case "--album-track-count-col":
|
||||||
|
trackCountCol = args[++i];
|
||||||
|
break;
|
||||||
case "--yt-id-col":
|
case "--yt-id-col":
|
||||||
ytIdCol = args[++i];
|
ytIdCol = args[++i];
|
||||||
break;
|
break;
|
||||||
|
@ -630,10 +634,19 @@ static class Program
|
||||||
case "--atc":
|
case "--atc":
|
||||||
case "--album-track-count":
|
case "--album-track-count":
|
||||||
string a = args[++i];
|
string a = args[++i];
|
||||||
if (a.Last() == '-')
|
if (a == "-1")
|
||||||
|
{
|
||||||
|
minAlbumTrackCount = -1;
|
||||||
|
maxAlbumTrackCount = -1;
|
||||||
|
}
|
||||||
|
else if (a.Last() == '-')
|
||||||
|
{
|
||||||
maxAlbumTrackCount = int.Parse(a.Substring(0, a.Length - 1));
|
maxAlbumTrackCount = int.Parse(a.Substring(0, a.Length - 1));
|
||||||
|
}
|
||||||
else if (a.Last() == '+')
|
else if (a.Last() == '+')
|
||||||
|
{
|
||||||
minAlbumTrackCount = int.Parse(a.Substring(0, a.Length - 1));
|
minAlbumTrackCount = int.Parse(a.Substring(0, a.Length - 1));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
minAlbumTrackCount = int.Parse(a);
|
minAlbumTrackCount = int.Parse(a);
|
||||||
|
@ -917,7 +930,7 @@ static class Program
|
||||||
if (debugDisableDownload)
|
if (debugDisableDownload)
|
||||||
maxConcurrentProcesses = 1;
|
maxConcurrentProcesses = 1;
|
||||||
|
|
||||||
ignoreOn = ignoreOn > deprioritizeOn ? deprioritizeOn : ignoreOn;
|
ignoreOn = Math.Min(ignoreOn, deprioritizeOn);
|
||||||
|
|
||||||
if (inputType == "youtube" || (inputType == "" && input.StartsWith("http") && input.Contains("youtu")))
|
if (inputType == "youtube" || (inputType == "" && input.StartsWith("http") && input.Contains("youtu")))
|
||||||
{
|
{
|
||||||
|
@ -1192,7 +1205,7 @@ static class Program
|
||||||
if (!File.Exists(csvPath))
|
if (!File.Exists(csvPath))
|
||||||
throw new FileNotFoundException("CSV file not found");
|
throw new FileNotFoundException("CSV file not found");
|
||||||
|
|
||||||
var tracks = await ParseCsvIntoTrackInfo(csvPath, artistCol, trackCol, lengthCol, albumCol, descCol, ytIdCol, timeUnit, ytParse);
|
var tracks = await ParseCsvIntoTrackInfo(csvPath, artistCol, trackCol, lengthCol, albumCol, descCol, ytIdCol, trackCountCol, timeUnit, ytParse);
|
||||||
tracks = tracks.Skip(off).Take(max).ToList();
|
tracks = tracks.Skip(off).Take(max).ToList();
|
||||||
trackLists = TrackLists.FromFlatList(tracks, aggregate, album);
|
trackLists = TrackLists.FromFlatList(tracks, aggregate, album);
|
||||||
defaultFolderName = Path.GetFileNameWithoutExtension(csvPath);
|
defaultFolderName = Path.GetFileNameWithoutExtension(csvPath);
|
||||||
|
@ -2125,7 +2138,7 @@ static class Program
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameFormat != "" && !useYtdlp)
|
if (nameFormat != "" && !useYtdlp)
|
||||||
saveFilePath = ApplyNamingFormat(saveFilePath);
|
saveFilePath = ApplyNamingFormat(saveFilePath, track);
|
||||||
|
|
||||||
return saveFilePath;
|
return saveFilePath;
|
||||||
}
|
}
|
||||||
|
@ -2238,10 +2251,22 @@ static class Program
|
||||||
x.Item2.Count(x => Utils.IsMusicFile(x.file.Filename))
|
x.Item2.Count(x => Utils.IsMusicFile(x.file.Filename))
|
||||||
).ToList();
|
).ToList();
|
||||||
|
|
||||||
bool countIsGood(int count, int min, int max) => count >= min && (max == -1 || count <= max);
|
int min, max;
|
||||||
|
if (track.MinAlbumTrackCount != -1 || track.MaxAlbumTrackCount != -1)
|
||||||
|
{
|
||||||
|
min = track.MinAlbumTrackCount;
|
||||||
|
max = track.MaxAlbumTrackCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min = minAlbumTrackCount;
|
||||||
|
max = maxAlbumTrackCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool countIsGood(int count) => count >= min && (max == -1 || count <= max);
|
||||||
|
|
||||||
var result = musicFolders
|
var result = musicFolders
|
||||||
.Where(x => countIsGood(x.Item2.Count(rf => Utils.IsMusicFile(rf.file.Filename)), minAlbumTrackCount, maxAlbumTrackCount))
|
.Where(x => countIsGood(x.Item2.Count(rf => Utils.IsMusicFile(rf.file.Filename))))
|
||||||
.Select(ls => ls.Item2.Select(x => {
|
.Select(ls => ls.Item2.Select(x => {
|
||||||
var t = new Track
|
var t = new Track
|
||||||
{
|
{
|
||||||
|
@ -3291,7 +3316,7 @@ static class Program
|
||||||
|
|
||||||
|
|
||||||
static async Task<List<Track>> ParseCsvIntoTrackInfo(string path, string artistCol = "", string trackCol = "",
|
static async Task<List<Track>> ParseCsvIntoTrackInfo(string path, string artistCol = "", string trackCol = "",
|
||||||
string lengthCol = "", string albumCol = "", string descCol = "", string ytIdCol = "", string timeUnit = "s", bool ytParse = false)
|
string lengthCol = "", string albumCol = "", string descCol = "", string ytIdCol = "", string trackCountCol = "", string timeUnit = "s", bool ytParse = false)
|
||||||
{
|
{
|
||||||
var tracks = new List<Track>();
|
var tracks = new List<Track>();
|
||||||
using var sr = new StreamReader(path, System.Text.Encoding.UTF8);
|
using var sr = new StreamReader(path, System.Text.Encoding.UTF8);
|
||||||
|
@ -3301,14 +3326,15 @@ static class Program
|
||||||
while (header == null || header.Count == 0 || !header.Any(t => t.Trim() != ""))
|
while (header == null || header.Count == 0 || !header.Any(t => t.Trim() != ""))
|
||||||
header = parser.ReadNextRow();
|
header = parser.ReadNextRow();
|
||||||
|
|
||||||
string[] cols = { artistCol, albumCol, trackCol, lengthCol, descCol, ytIdCol };
|
string[] cols = { artistCol, albumCol, trackCol, lengthCol, descCol, ytIdCol, trackCountCol };
|
||||||
string[][] aliases = {
|
string[][] aliases = {
|
||||||
new[] { "artist", "artist name", "artists", "artist names" },
|
new[] { "artist", "artist name", "artists", "artist names" },
|
||||||
new[] { "album", "album name", "album title" },
|
new[] { "album", "album name", "album title" },
|
||||||
new[] { "title", "song", "track title", "track name", "song name", "track" },
|
new[] { "title", "song", "track title", "track name", "song name", "track" },
|
||||||
new[] { "length", "duration", "track length", "track duration", "song length", "song duration" },
|
new[] { "length", "duration", "track length", "track duration", "song length", "song duration" },
|
||||||
new[] { "description", "youtube description" },
|
new[] { "description", "youtube description" },
|
||||||
new[] { "id", "youtube id", "url" }
|
new[] { "url", "id", "youtube id" },
|
||||||
|
new[] { "track count", "album track count" }
|
||||||
};
|
};
|
||||||
|
|
||||||
string usingColumns = "";
|
string usingColumns = "";
|
||||||
|
@ -3338,8 +3364,8 @@ static class Program
|
||||||
throw new Exception("No columns specified and couldn't determine automatically");
|
throw new Exception("No columns specified and couldn't determine automatically");
|
||||||
|
|
||||||
int[] indices = cols.Select(col => col == "" ? -1 : header.IndexOf(col)).ToArray();
|
int[] indices = cols.Select(col => col == "" ? -1 : header.IndexOf(col)).ToArray();
|
||||||
int artistIndex, albumIndex, trackIndex, lengthIndex, descIndex, ytIdIndex;
|
int artistIndex, albumIndex, trackIndex, lengthIndex, descIndex, ytIdIndex, trackCountIndex;
|
||||||
(artistIndex, albumIndex, trackIndex, lengthIndex, descIndex, ytIdIndex) = (indices[0], indices[1], indices[2], indices[3], indices[4], indices[5]);
|
(artistIndex, albumIndex, trackIndex, lengthIndex, descIndex, ytIdIndex, trackCountIndex) = (indices[0], indices[1], indices[2], indices[3], indices[4], indices[5], indices[6]);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -3359,6 +3385,28 @@ static class Program
|
||||||
if (albumIndex >= 0) track.Album = values[albumIndex];
|
if (albumIndex >= 0) track.Album = values[albumIndex];
|
||||||
if (descIndex >= 0) desc = values[descIndex];
|
if (descIndex >= 0) desc = values[descIndex];
|
||||||
if (ytIdIndex >= 0) track.URI = values[ytIdIndex];
|
if (ytIdIndex >= 0) track.URI = values[ytIdIndex];
|
||||||
|
if (trackCountIndex >= 0)
|
||||||
|
{
|
||||||
|
string a = values[trackCountIndex].Trim();
|
||||||
|
if (a == "-1")
|
||||||
|
{
|
||||||
|
track.MinAlbumTrackCount = -1;
|
||||||
|
track.MaxAlbumTrackCount = -1;
|
||||||
|
}
|
||||||
|
else if (a.Last() == '-' && int.TryParse(a.AsSpan(0, a.Length - 1), out int n))
|
||||||
|
{
|
||||||
|
track.MaxAlbumTrackCount = n;
|
||||||
|
}
|
||||||
|
else if (a.Last() == '+' && int.TryParse(a.AsSpan(0, a.Length - 1), out n))
|
||||||
|
{
|
||||||
|
track.MinAlbumTrackCount = n;
|
||||||
|
}
|
||||||
|
else if (int.TryParse(a, out n))
|
||||||
|
{
|
||||||
|
track.MinAlbumTrackCount = n;
|
||||||
|
track.MaxAlbumTrackCount = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (lengthIndex >= 0)
|
if (lengthIndex >= 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -3469,13 +3517,13 @@ static class Program
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static string ApplyNamingFormat(string filepath)
|
static string ApplyNamingFormat(string filepath, Track track)
|
||||||
{
|
{
|
||||||
if (nameFormat == "" || !Utils.IsMusicFile(filepath))
|
if (nameFormat == "" || !Utils.IsMusicFile(filepath))
|
||||||
return filepath;
|
return filepath;
|
||||||
|
|
||||||
string add = Path.GetRelativePath(outputFolder, Path.GetDirectoryName(filepath));
|
string add = Path.GetRelativePath(outputFolder, Path.GetDirectoryName(filepath));
|
||||||
string newFilePath = NamingFormat(filepath, nameFormat);
|
string newFilePath = NamingFormat(filepath, nameFormat, track);
|
||||||
if (filepath != newFilePath)
|
if (filepath != newFilePath)
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(newFilePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(newFilePath));
|
||||||
|
@ -3487,7 +3535,7 @@ static class Program
|
||||||
return newFilePath;
|
return newFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string NamingFormat(string filepath, string format)
|
static string NamingFormat(string filepath, string format, Track track)
|
||||||
{
|
{
|
||||||
string newName = format;
|
string newName = format;
|
||||||
TagLib.File? file = null;
|
TagLib.File? file = null;
|
||||||
|
@ -3511,7 +3559,7 @@ static class Program
|
||||||
{
|
{
|
||||||
string[] parts = Regex.Split(opt, @"\([^\)]*\)");
|
string[] parts = Regex.Split(opt, @"\([^\)]*\)");
|
||||||
string[] result = parts.Where(part => !string.IsNullOrWhiteSpace(part)).ToArray();
|
string[] result = parts.Where(part => !string.IsNullOrWhiteSpace(part)).ToArray();
|
||||||
if (result.All(x => GetTagValue(file, x) != "")) {
|
if (result.All(x => GetVarValue(x, file, track) != "")) {
|
||||||
chosenOpt = opt;
|
chosenOpt = opt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3522,7 +3570,7 @@ static class Program
|
||||||
if (match.Value.StartsWith("(") && match.Value.EndsWith(")"))
|
if (match.Value.StartsWith("(") && match.Value.EndsWith(")"))
|
||||||
return match.Value.Substring(1, match.Value.Length-2);
|
return match.Value.Substring(1, match.Value.Length-2);
|
||||||
else
|
else
|
||||||
return GetTagValue(file, match.Value);
|
return GetVarValue(match.Value, file, track);
|
||||||
});
|
});
|
||||||
string old = match.Groups[1].Value;
|
string old = match.Groups[1].Value;
|
||||||
old = old.StartsWith("{{") ? old.Substring(1) : old;
|
old = old.StartsWith("{{") ? old.Substring(1) : old;
|
||||||
|
@ -3548,22 +3596,29 @@ static class Program
|
||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string GetTagValue(TagLib.File file, string tag)
|
static string GetVarValue(string x, TagLib.File file, Track track)
|
||||||
{
|
{
|
||||||
switch (tag)
|
switch (x)
|
||||||
{
|
{
|
||||||
case "artist":
|
case "artist":
|
||||||
return (file.Tag.FirstPerformer ?? "").RemoveFt();
|
return file.Tag.FirstPerformer ?? "";
|
||||||
case "artists":
|
case "artists":
|
||||||
return string.Join(" & ", file.Tag.Performers).RemoveFt();
|
return string.Join(" & ", file.Tag.Performers);
|
||||||
case "album_artist":
|
case "albumartist":
|
||||||
return (file.Tag.FirstAlbumArtist ?? "").RemoveFt();
|
return file.Tag.FirstAlbumArtist ?? "";
|
||||||
case "album_artists":
|
case "albumartists":
|
||||||
return string.Join(" & ", file.Tag.AlbumArtists).RemoveFt();
|
return string.Join(" & ", file.Tag.AlbumArtists);
|
||||||
case "title":
|
case "title":
|
||||||
return file.Tag.Title ?? "";
|
return file.Tag.Title ?? "";
|
||||||
case "album":
|
case "album":
|
||||||
return file.Tag.Album ?? "";
|
return file.Tag.Album ?? "";
|
||||||
|
case "sartist":
|
||||||
|
case "sartists":
|
||||||
|
return track.Artist;
|
||||||
|
case "stitle":
|
||||||
|
return track.Title;
|
||||||
|
case "salbum":
|
||||||
|
return track.Album;
|
||||||
case "year":
|
case "year":
|
||||||
return file.Tag.Year.ToString() ?? "";
|
return file.Tag.Year.ToString() ?? "";
|
||||||
case "track":
|
case "track":
|
||||||
|
@ -3572,7 +3627,7 @@ static class Program
|
||||||
return file.Tag.Disc.ToString() ?? "";
|
return file.Tag.Disc.ToString() ?? "";
|
||||||
case "filename":
|
case "filename":
|
||||||
return Path.GetFileNameWithoutExtension(file.Name);
|
return Path.GetFileNameWithoutExtension(file.Name);
|
||||||
case "default_foldername":
|
case "foldername":
|
||||||
return defaultFolderName;
|
return defaultFolderName;
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
|
@ -3581,34 +3636,66 @@ static class Program
|
||||||
|
|
||||||
static bool TrackMatchesFilename(Track track, string filename)
|
static bool TrackMatchesFilename(Track track, string filename)
|
||||||
{
|
{
|
||||||
string[] ignore = new string[] { " ", "_", "-", ".", "(", ")" };
|
if (track.Title.Trim() == "" || filename.Trim() == "")
|
||||||
string searchName = track.Title.Replace(ignore, "").ToLower();
|
return false;
|
||||||
searchName = searchName.ReplaceInvalidChars("").RemoveFt().RemoveSquareBrackets();
|
|
||||||
searchName = searchName == "" ? track.Title : searchName;
|
|
||||||
|
|
||||||
string searchName2 = "";
|
string[] ignore = new string[] { " ", "_", "-", ".", "(", ")", "[", "]" };
|
||||||
if (searchName.Length <= 3) {
|
|
||||||
searchName2 = track.Artist.Replace(ignore, "").ToLower();
|
string preprocess1(string s, bool removeSlash = true)
|
||||||
searchName2 = searchName2.ReplaceInvalidChars("").RemoveFt().RemoveSquareBrackets();
|
{
|
||||||
searchName2 = searchName2 == "" ? track.Artist : searchName2;
|
s = s.ReplaceInvalidChars("", false, removeSlash).Replace(ignore, "").ToLower();
|
||||||
|
s = s.RemoveFt().RemoveDiacritics();
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
string fullpath = filename;
|
string preprocess2(string s, bool removeSlash = true)
|
||||||
filename = Path.GetFileNameWithoutExtension(filename);
|
{
|
||||||
filename = filename.ReplaceInvalidChars("");
|
s = s.ReplaceInvalidChars("", false, removeSlash).ToLower().RemoveDiacritics();
|
||||||
filename = filename.Replace(ignore, "").ToLower();
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
if (filename.Contains(searchName) && FileConditions.StrictString(fullpath, searchName2, ignoreCase:true, boundarySkipWs:true))
|
string preprocess3(string s)
|
||||||
|
{
|
||||||
|
s = s.ToLower().RemoveDiacritics();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
string title = preprocess1(track.Title);
|
||||||
|
string artist = preprocess1(track.Artist);
|
||||||
|
string fname = preprocess1(Path.GetFileNameWithoutExtension(filename));
|
||||||
|
string path = preprocess1(filename, false);
|
||||||
|
|
||||||
|
if (title == "" || fname == "")
|
||||||
|
{
|
||||||
|
title = preprocess2(track.Title);
|
||||||
|
artist = preprocess2(track.Artist);
|
||||||
|
fname = preprocess2(Path.GetFileNameWithoutExtension(filename));
|
||||||
|
path = preprocess2(filename, false);
|
||||||
|
|
||||||
|
if (title == "" || fname == "")
|
||||||
|
{
|
||||||
|
title = preprocess3(track.Title);
|
||||||
|
artist = preprocess3(track.Artist);
|
||||||
|
fname = preprocess3(Path.GetFileNameWithoutExtension(filename));
|
||||||
|
path = preprocess3(filename);
|
||||||
|
|
||||||
|
if (title == "" || fname == "")
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fname.Contains(title) && path.Contains(artist))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ((track.ArtistMaybeWrong || track.Artist == "") && track.Title.Contains(" - "))
|
else if ((track.ArtistMaybeWrong || track.Artist == "") && track.Title.Contains(" - "))
|
||||||
{
|
{
|
||||||
searchName = track.Title.Substring(track.Title.IndexOf(" - ") + 3).Replace(ignore, "").ToLower();
|
title = preprocess1(track.Title.Substring(track.Title.IndexOf(" - ") + 3));
|
||||||
searchName = searchName.ReplaceInvalidChars("").RemoveFt().RemoveSquareBrackets();
|
if (title != "")
|
||||||
if (searchName != "")
|
|
||||||
{
|
{
|
||||||
if (filename.Contains(searchName))
|
if (preprocess1(filename, false).Contains(title))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4372,6 +4459,8 @@ public struct Track
|
||||||
public int Length = -1;
|
public int Length = -1;
|
||||||
public bool ArtistMaybeWrong = false;
|
public bool ArtistMaybeWrong = false;
|
||||||
public bool IsAlbum = false;
|
public bool IsAlbum = false;
|
||||||
|
public int MinAlbumTrackCount = -1;
|
||||||
|
public int MaxAlbumTrackCount = -1;
|
||||||
public bool IsNotAudio = false;
|
public bool IsNotAudio = false;
|
||||||
public string FailureReason = "";
|
public string FailureReason = "";
|
||||||
public string DownloadPath = "";
|
public string DownloadPath = "";
|
||||||
|
@ -4406,6 +4495,8 @@ public struct Track
|
||||||
FailureReason = other.FailureReason;
|
FailureReason = other.FailureReason;
|
||||||
DownloadPath = other.DownloadPath;
|
DownloadPath = other.DownloadPath;
|
||||||
Other = other.Other;
|
Other = other.Other;
|
||||||
|
MinAlbumTrackCount = other.MinAlbumTrackCount;
|
||||||
|
MaxAlbumTrackCount = other.MaxAlbumTrackCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override readonly string ToString()
|
public override readonly string ToString()
|
||||||
|
|
Loading…
Reference in a new issue