1
0
Fork 0
mirror of https://github.com/fiso64/slsk-batchdl.git synced 2025-01-08 22:42:42 +00:00
slsk-batchdl/slsk-batchdl/FileConditions.cs
2024-08-26 23:52:54 +02:00

296 lines
12 KiB
C#

using System.Text.RegularExpressions;
using Data;
using SearchResponse = Soulseek.SearchResponse;
public class FileConditions
{
public int LengthTolerance = -1;
public int MinBitrate = -1;
public int MaxBitrate = -1;
public int MinSampleRate = -1;
public int MaxSampleRate = -1;
public int MinBitDepth = -1;
public int MaxBitDepth = -1;
public bool StrictTitle = false;
public bool StrictArtist = false;
public bool StrictAlbum = false;
public string[] DangerWords = Array.Empty<string>();
public string[] Formats = Array.Empty<string>();
public string[] BannedUsers = Array.Empty<string>();
public string StrictStringRegexRemove = string.Empty;
public bool StrictStringDiacrRemove = true;
public bool AcceptNoLength = true;
public bool AcceptMissingProps = true;
public FileConditions() { }
public FileConditions(FileConditions other)
{
LengthTolerance = other.LengthTolerance;
MinBitrate = other.MinBitrate;
MaxBitrate = other.MaxBitrate;
MinSampleRate = other.MinSampleRate;
MaxSampleRate = other.MaxSampleRate;
AcceptNoLength = other.AcceptNoLength;
StrictArtist = other.StrictArtist;
StrictTitle = other.StrictTitle;
MinBitDepth = other.MinBitDepth;
MaxBitDepth = other.MaxBitDepth;
Formats = other.Formats.ToArray();
DangerWords = other.DangerWords.ToArray();
BannedUsers = other.BannedUsers.ToArray();
}
public override bool Equals(object obj)
{
if (obj is FileConditions other)
{
return LengthTolerance == other.LengthTolerance &&
MinBitrate == other.MinBitrate &&
MaxBitrate == other.MaxBitrate &&
MinSampleRate == other.MinSampleRate &&
MaxSampleRate == other.MaxSampleRate &&
MinBitDepth == other.MinBitDepth &&
MaxBitDepth == other.MaxBitDepth &&
StrictTitle == other.StrictTitle &&
StrictArtist == other.StrictArtist &&
StrictAlbum == other.StrictAlbum &&
StrictStringRegexRemove == other.StrictStringRegexRemove &&
StrictStringDiacrRemove == other.StrictStringDiacrRemove &&
AcceptNoLength == other.AcceptNoLength &&
AcceptMissingProps == other.AcceptMissingProps &&
Formats.SequenceEqual(other.Formats) &&
DangerWords.SequenceEqual(other.DangerWords) &&
BannedUsers.SequenceEqual(other.BannedUsers);
}
return false;
}
public void UnsetClientSpecificFields()
{
MinBitrate = -1;
MaxBitrate = -1;
MinSampleRate = -1;
MaxSampleRate = -1;
MinBitDepth = -1;
MaxBitDepth = -1;
}
public bool FileSatisfies(Soulseek.File file, Track track, SearchResponse? response)
{
return DangerWordSatisfies(file.Filename, track.Title, track.Artist) && FormatSatisfies(file.Filename)
&& LengthToleranceSatisfies(file, track.Length) && BitrateSatisfies(file) && SampleRateSatisfies(file)
&& StrictTitleSatisfies(file.Filename, track.Title) && StrictArtistSatisfies(file.Filename, track.Artist)
&& StrictAlbumSatisfies(file.Filename, track.Album) && BannedUsersSatisfies(response) && BitDepthSatisfies(file);
}
public bool FileSatisfies(TagLib.File file, Track track, bool filenameChecks = false)
{
return DangerWordSatisfies(file.Name, track.Title, track.Artist) && FormatSatisfies(file.Name)
&& LengthToleranceSatisfies(file, track.Length) && BitrateSatisfies(file) && SampleRateSatisfies(file)
&& BitDepthSatisfies(file) && (!filenameChecks || StrictTitleSatisfies(file.Name, track.Title)
&& StrictArtistSatisfies(file.Name, track.Artist) && StrictAlbumSatisfies(file.Name, track.Album));
}
public bool FileSatisfies(SimpleFile file, Track track, bool filenameChecks = false)
{
return DangerWordSatisfies(file.Path, track.Title, track.Artist) && FormatSatisfies(file.Path)
&& LengthToleranceSatisfies(file, track.Length) && BitrateSatisfies(file) && SampleRateSatisfies(file)
&& BitDepthSatisfies(file) && (!filenameChecks || StrictTitleSatisfies(file.Path, track.Title)
&& StrictArtistSatisfies(file.Path, track.Artist) && StrictAlbumSatisfies(file.Path, track.Album));
}
public bool DangerWordSatisfies(string fname, string tname, string aname)
{
if (tname.Length == 0)
return true;
fname = Utils.GetFileNameWithoutExtSlsk(fname).Replace(" — ", " - ");
tname = tname.Replace(" — ", " - ");
foreach (var word in DangerWords)
{
if (fname.ContainsIgnoreCase(word) ^ tname.ContainsIgnoreCase(word))
{
if (!(fname.Contains(" - ") && fname.ContainsIgnoreCase(word) && aname.ContainsIgnoreCase(word)))
{
if (word == "mix")
return fname.ContainsIgnoreCase("original mix") || tname.ContainsIgnoreCase("original mix");
else
return false;
}
}
}
return true;
}
public bool StrictTitleSatisfies(string fname, string tname, bool noPath = true)
{
if (!StrictTitle || tname.Length == 0)
return true;
fname = noPath ? Utils.GetFileNameWithoutExtSlsk(fname) : fname;
return StrictString(fname, tname, StrictStringRegexRemove, StrictStringDiacrRemove, ignoreCase: true);
}
public bool StrictArtistSatisfies(string fname, string aname)
{
if (!StrictArtist || aname.Length == 0)
return true;
return StrictString(fname, aname, StrictStringRegexRemove, StrictStringDiacrRemove, ignoreCase: true, boundarySkipWs: false);
}
public bool StrictAlbumSatisfies(string fname, string alname)
{
if (!StrictAlbum || alname.Length == 0)
return true;
return StrictString(Utils.GetDirectoryNameSlsk(fname), alname, StrictStringRegexRemove, StrictStringDiacrRemove, ignoreCase: true);
}
public static string StrictStringPreprocess(string str, string regexRemove = "", bool diacrRemove = true)
{
str = str.Replace('_', ' ').ReplaceInvalidChars(' ', true, false);
str = regexRemove.Length > 0 ? Regex.Replace(str, regexRemove, "") : str;
str = diacrRemove ? str.RemoveDiacritics() : str;
str = str.Trim().RemoveConsecutiveWs();
return str;
}
public static bool StrictString(string fname, string tname, string regexRemove = "", bool diacrRemove = true, bool ignoreCase = true, bool boundarySkipWs = true)
{
if (tname.Length == 0)
return true;
fname = StrictStringPreprocess(fname, regexRemove, diacrRemove);
tname = StrictStringPreprocess(tname, regexRemove, diacrRemove);
if (boundarySkipWs)
return fname.ContainsWithBoundaryIgnoreWs(tname, ignoreCase, acceptLeftDigit: true);
else
return fname.ContainsWithBoundary(tname, ignoreCase);
}
public static bool BracketCheck(Track track, Track other)
{
string t1 = track.Title.RemoveFt().Replace('[', '(');
if (t1.Contains('('))
return true;
string t2 = other.Title.RemoveFt().Replace('[', '(');
if (!t2.Contains('('))
return true;
return false;
}
public bool FormatSatisfies(string fname)
{
if (Formats.Length == 0)
return true;
string ext = Path.GetExtension(fname).TrimStart('.').ToLower();
return ext.Length > 0 && Formats.Any(f => f == ext);
}
public bool LengthToleranceSatisfies(Soulseek.File file, int wantedLength) => LengthToleranceSatisfies(file.Length, wantedLength);
public bool LengthToleranceSatisfies(TagLib.File file, int wantedLength) => LengthToleranceSatisfies((int)file.Properties.Duration.TotalSeconds, wantedLength);
public bool LengthToleranceSatisfies(SimpleFile file, int wantedLength) => LengthToleranceSatisfies(file.Length, wantedLength);
public bool LengthToleranceSatisfies(int? length, int wantedLength)
{
if (LengthTolerance < 0 || wantedLength < 0)
return true;
if (length == null || length < 0)
return AcceptNoLength && AcceptMissingProps;
return Math.Abs((int)length - wantedLength) <= LengthTolerance;
}
public bool BitrateSatisfies(Soulseek.File file) => BitrateSatisfies(file.BitRate);
public bool BitrateSatisfies(TagLib.File file) => BitrateSatisfies(file.Properties.AudioBitrate);
public bool BitrateSatisfies(SimpleFile file) => BitrateSatisfies(file.Bitrate);
public bool BitrateSatisfies(int? bitrate)
{
return BoundCheck(bitrate, MinBitrate, MaxBitrate);
}
public bool SampleRateSatisfies(Soulseek.File file) => SampleRateSatisfies(file.SampleRate);
public bool SampleRateSatisfies(TagLib.File file) => SampleRateSatisfies(file.Properties.AudioSampleRate);
public bool SampleRateSatisfies(SimpleFile file) => SampleRateSatisfies(file.Samplerate);
public bool SampleRateSatisfies(int? sampleRate)
{
return BoundCheck(sampleRate, MinSampleRate, MaxSampleRate);
}
public bool BitDepthSatisfies(Soulseek.File file) => BitDepthSatisfies(file.BitDepth);
public bool BitDepthSatisfies(TagLib.File file) => BitDepthSatisfies(file.Properties.BitsPerSample);
public bool BitDepthSatisfies(SimpleFile file) => BitDepthSatisfies(file.Bitdepth);
public bool BitDepthSatisfies(int? bitdepth)
{
return BoundCheck(bitdepth, MinBitDepth, MaxBitDepth);
}
public bool BoundCheck(int? num, int min, int max)
{
if (max < 0 && min < 0)
return true;
if (num == null || num < 0)
return AcceptMissingProps;
if (num < min || max != -1 && num > max)
return false;
return true;
}
public bool BannedUsersSatisfies(SearchResponse? response)
{
return response == null || !BannedUsers.Any(x => x == response.Username);
}
public string GetNotSatisfiedName(Soulseek.File file, Track track, SearchResponse? response)
{
if (!DangerWordSatisfies(file.Filename, track.Title, track.Artist))
return "DangerWord fails";
if (!FormatSatisfies(file.Filename))
return "Format fails";
if (!LengthToleranceSatisfies(file, track.Length))
return "Length fails";
if (!BitrateSatisfies(file))
return "Bitrate fails";
if (!SampleRateSatisfies(file))
return "SampleRate fails";
if (!StrictTitleSatisfies(file.Filename, track.Title))
return "StrictTitle fails";
if (!StrictArtistSatisfies(file.Filename, track.Artist))
return "StrictArtist fails";
if (!BitDepthSatisfies(file))
return "BitDepth fails";
if (!BannedUsersSatisfies(response))
return "BannedUsers fails";
return "Satisfied";
}
public string GetNotSatisfiedName(TagLib.File file, Track track)
{
if (!DangerWordSatisfies(file.Name, track.Title, track.Artist))
return "DangerWord fails";
if (!FormatSatisfies(file.Name))
return "Format fails";
if (!LengthToleranceSatisfies(file, track.Length))
return "Length fails";
if (!BitrateSatisfies(file))
return "Bitrate fails";
if (!SampleRateSatisfies(file))
return "SampleRate fails";
if (!StrictTitleSatisfies(file.Name, track.Title))
return "StrictTitle fails";
if (!StrictArtistSatisfies(file.Name, track.Artist))
return "StrictArtist fails";
if (!BitDepthSatisfies(file))
return "BitDepth fails";
return "Satisfied";
}
}