mirror of
https://github.com/Readarr/Readarr.git
synced 2026-04-24 22:35:39 -04:00
Moved Extension methods in common to subfolder
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class DictionaryExtensions
|
||||
{
|
||||
public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue = default(TValue))
|
||||
{
|
||||
TValue value;
|
||||
return dictionary.TryGetValue(key, out value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static Dictionary<T1, T2> Merge<T1, T2>(this Dictionary<T1, T2> first, Dictionary<T1, T2> second)
|
||||
{
|
||||
if (first == null) throw new ArgumentNullException("first");
|
||||
if (second == null) throw new ArgumentNullException("second");
|
||||
|
||||
var merged = new Dictionary<T1, T2>();
|
||||
first.ToList().ForEach(kv => merged[kv.Key] = kv.Value);
|
||||
second.ToList().ForEach(kv => merged[kv.Key] = kv.Value);
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
public static void Add<TKey, TValue>(this ICollection<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
|
||||
{
|
||||
collection.Add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
|
||||
{
|
||||
var knownKeys = new HashSet<TKey>();
|
||||
|
||||
return source.Where(element => knownKeys.Add(keySelector(element)));
|
||||
}
|
||||
|
||||
public static void AddIfNotNull<TSource>(this List<TSource> source, TSource item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
source.Add(item);
|
||||
}
|
||||
|
||||
public static bool Empty<TSource>(this IEnumerable<TSource> source)
|
||||
{
|
||||
return !source.Any();
|
||||
}
|
||||
|
||||
public static bool None<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
||||
{
|
||||
return !source.Any(predicate);
|
||||
}
|
||||
|
||||
public static bool NotAll<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
||||
{
|
||||
return !source.All(predicate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class LevenstheinExtensions
|
||||
{
|
||||
public static Int32 LevenshteinDistance(this String text, String other, Int32 costInsert = 1, Int32 costDelete = 1, Int32 costSubstitute = 1)
|
||||
{
|
||||
if (text == other) return 0;
|
||||
if (text.Length == 0) return other.Length * costInsert;
|
||||
if (other.Length == 0) return text.Length * costDelete;
|
||||
|
||||
Int32[] matrix = new Int32[other.Length + 1];
|
||||
|
||||
for (var i = 1; i < matrix.Length; i++)
|
||||
{
|
||||
matrix[i] = i * costInsert;
|
||||
}
|
||||
|
||||
for (var i = 0; i < text.Length; i++)
|
||||
{
|
||||
Int32 topLeft = matrix[0];
|
||||
matrix[0] = matrix[0] + costDelete;
|
||||
|
||||
for (var j = 0; j < other.Length; j++)
|
||||
{
|
||||
Int32 top = matrix[j];
|
||||
Int32 left = matrix[j + 1];
|
||||
|
||||
var sumIns = top + costInsert;
|
||||
var sumDel = left + costDelete;
|
||||
var sumSub = topLeft + (text[i] == other[j] ? 0 : costSubstitute);
|
||||
|
||||
topLeft = matrix[j + 1];
|
||||
matrix[j + 1] = Math.Min(Math.Min(sumIns, sumDel), sumSub);
|
||||
}
|
||||
}
|
||||
|
||||
return matrix[other.Length];
|
||||
}
|
||||
|
||||
public static Int32 LevenshteinDistanceClean(this String expected, String other)
|
||||
{
|
||||
expected = expected.ToLower().Replace(".", "");
|
||||
other = other.ToLower().Replace(".", "");
|
||||
|
||||
return expected.LevenshteinDistance(other, 1, 3, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class PathExtensions
|
||||
{
|
||||
private const string APP_CONFIG_FILE = "config.xml";
|
||||
private const string NZBDRONE_DB = "nzbdrone.db";
|
||||
private const string NZBDRONE_LOG_DB = "logs.db";
|
||||
private const string NLOG_CONFIG_FILE = "nlog.config";
|
||||
private const string UPDATE_CLIENT_EXE = "NzbDrone.Update.exe";
|
||||
private const string BACKUP_FOLDER = "Backups";
|
||||
|
||||
private static readonly string UPDATE_SANDBOX_FOLDER_NAME = "nzbdrone_update" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "NzbDrone" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_BACKUP_FOLDER_NAME = "nzbdrone_backup" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_BACKUP_APPDATA_FOLDER_NAME = "nzbdrone_appdata_backup" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_CLIENT_FOLDER_NAME = "NzbDrone.Update" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_LOG_FOLDER_NAME = "UpdateLogs" + Path.DirectorySeparatorChar;
|
||||
|
||||
public static string CleanFilePath(this string path)
|
||||
{
|
||||
Ensure.That(path, () => path).IsNotNullOrWhiteSpace();
|
||||
Ensure.That(path, () => path).IsValidPath();
|
||||
|
||||
var info = new FileInfo(path.Trim());
|
||||
|
||||
if (!OsInfo.IsMono && info.FullName.StartsWith(@"\\")) //UNC
|
||||
{
|
||||
return info.FullName.TrimEnd('/', '\\', ' ');
|
||||
}
|
||||
|
||||
return info.FullName.TrimEnd('/').Trim('\\', ' ');
|
||||
}
|
||||
|
||||
public static bool PathEquals(this string firstPath, string secondPath)
|
||||
{
|
||||
if (firstPath.Equals(secondPath, OsInfo.PathStringComparison)) return true;
|
||||
return String.Equals(firstPath.CleanFilePath(), secondPath.CleanFilePath(), OsInfo.PathStringComparison);
|
||||
}
|
||||
|
||||
public static string GetRelativePath(this string parentPath, string childPath)
|
||||
{
|
||||
if (!parentPath.IsParentPath(childPath))
|
||||
{
|
||||
throw new Exceptions.NotParentException("{0} is not a child of {1}", childPath, parentPath);
|
||||
}
|
||||
|
||||
return childPath.Substring(parentPath.Length).Trim(Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
public static string GetParentPath(this string childPath)
|
||||
{
|
||||
var parentPath = childPath.TrimEnd('\\', '/');
|
||||
|
||||
var index = parentPath.LastIndexOfAny(new[] { '\\', '/' });
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
return parentPath.Substring(0, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsParentPath(this string parentPath, string childPath)
|
||||
{
|
||||
parentPath = parentPath.TrimEnd(Path.DirectorySeparatorChar);
|
||||
childPath = childPath.TrimEnd(Path.DirectorySeparatorChar);
|
||||
|
||||
var parent = new DirectoryInfo(parentPath);
|
||||
var child = new DirectoryInfo(childPath);
|
||||
|
||||
while (child.Parent != null)
|
||||
{
|
||||
if (child.Parent.FullName.Equals(parent.FullName, OsInfo.PathStringComparison))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
child = child.Parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static readonly Regex WindowsPathWithDriveRegex = new Regex(@"^[a-zA-Z]:\\", RegexOptions.Compiled);
|
||||
|
||||
public static bool IsPathValid(this string path)
|
||||
{
|
||||
if (path.ContainsInvalidPathChars() || string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (OsInfo.IsMono)
|
||||
{
|
||||
return path.StartsWith(Path.DirectorySeparatorChar.ToString());
|
||||
}
|
||||
|
||||
if (path.StartsWith("\\") || WindowsPathWithDriveRegex.IsMatch(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ContainsInvalidPathChars(this string text)
|
||||
{
|
||||
return text.IndexOfAny(Path.GetInvalidPathChars()) >= 0;
|
||||
}
|
||||
|
||||
private static string GetProperCapitalization(DirectoryInfo dirInfo)
|
||||
{
|
||||
var parentDirInfo = dirInfo.Parent;
|
||||
if (parentDirInfo == null)
|
||||
{
|
||||
//Drive letter
|
||||
return dirInfo.Name.ToUpper();
|
||||
}
|
||||
|
||||
var folderName = dirInfo.Name;
|
||||
|
||||
if (dirInfo.Exists)
|
||||
{
|
||||
folderName = parentDirInfo.GetDirectories(dirInfo.Name)[0].Name;
|
||||
}
|
||||
|
||||
return Path.Combine(GetProperCapitalization(parentDirInfo), folderName);
|
||||
}
|
||||
|
||||
public static string GetActualCasing(this string path)
|
||||
{
|
||||
if (OsInfo.IsMono || path.StartsWith("\\"))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
if (Directory.Exists(path) && (File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
|
||||
{
|
||||
return GetProperCapitalization(new DirectoryInfo(path));
|
||||
}
|
||||
|
||||
var fileInfo = new FileInfo(path);
|
||||
var dirInfo = fileInfo.Directory;
|
||||
|
||||
var fileName = fileInfo.Name;
|
||||
|
||||
if (dirInfo != null && fileInfo.Exists)
|
||||
{
|
||||
fileName = dirInfo.GetFiles(fileInfo.Name)[0].Name;
|
||||
}
|
||||
|
||||
return Path.Combine(GetProperCapitalization(dirInfo), fileName);
|
||||
}
|
||||
|
||||
public static string GetAppDataPath(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return appFolderInfo.AppDataFolder;
|
||||
}
|
||||
|
||||
public static string GetLogFolder(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetAppDataPath(appFolderInfo), "logs");
|
||||
}
|
||||
|
||||
public static string GetConfigPath(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetAppDataPath(appFolderInfo), APP_CONFIG_FILE);
|
||||
}
|
||||
|
||||
public static string GetMediaCoverPath(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetAppDataPath(appFolderInfo), "MediaCover");
|
||||
}
|
||||
|
||||
public static string GetUpdateLogFolder(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetAppDataPath(appFolderInfo), UPDATE_LOG_FOLDER_NAME);
|
||||
}
|
||||
|
||||
public static string GetUpdateSandboxFolder(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(appFolderInfo.TempFolder, UPDATE_SANDBOX_FOLDER_NAME);
|
||||
}
|
||||
|
||||
public static string GetUpdateBackUpFolder(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_BACKUP_FOLDER_NAME);
|
||||
}
|
||||
|
||||
public static string GetUpdateBackUpAppDataFolder(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_BACKUP_APPDATA_FOLDER_NAME);
|
||||
}
|
||||
|
||||
public static string GetUpdateBackupConfigFile(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetUpdateBackUpAppDataFolder(appFolderInfo), APP_CONFIG_FILE);
|
||||
}
|
||||
|
||||
public static string GetUpdateBackupDatabase(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetUpdateBackUpAppDataFolder(appFolderInfo), NZBDRONE_DB);
|
||||
}
|
||||
|
||||
public static string GetUpdatePackageFolder(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_PACKAGE_FOLDER_NAME);
|
||||
}
|
||||
|
||||
public static string GetUpdateClientFolder(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetUpdatePackageFolder(appFolderInfo), UPDATE_CLIENT_FOLDER_NAME);
|
||||
}
|
||||
|
||||
public static string GetUpdateClientExePath(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_CLIENT_EXE);
|
||||
}
|
||||
|
||||
public static string GetBackupFolder(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetAppDataPath(appFolderInfo), BACKUP_FOLDER);
|
||||
}
|
||||
|
||||
public static string GetNzbDroneDatabase(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetAppDataPath(appFolderInfo), NZBDRONE_DB);
|
||||
}
|
||||
|
||||
public static string GetLogDatabase(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(GetAppDataPath(appFolderInfo), NZBDRONE_LOG_DB);
|
||||
}
|
||||
|
||||
public static string GetNlogConfigPath(this IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
return Path.Combine(appFolderInfo.StartUpFolder, NLOG_CONFIG_FILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class ResourceExtensions
|
||||
{
|
||||
public static Byte[] GetManifestResourceBytes(this Assembly assembly, String name)
|
||||
{
|
||||
var stream = assembly.GetManifestResourceStream(name);
|
||||
|
||||
var result = new Byte[stream.Length];
|
||||
var read = stream.Read(result, 0, result.Length);
|
||||
|
||||
if (read != result.Length)
|
||||
{
|
||||
throw new EndOfStreamException("Reached end of stream before reading enough bytes.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string NullSafe(this string target)
|
||||
{
|
||||
return ((object)target).NullSafe().ToString();
|
||||
}
|
||||
|
||||
public static object NullSafe(this object target)
|
||||
{
|
||||
if (target != null) return target;
|
||||
return "[NULL]";
|
||||
}
|
||||
|
||||
public static string FirstCharToUpper(this string input)
|
||||
{
|
||||
return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
|
||||
}
|
||||
|
||||
public static string Inject(this string format, params object[] formattingArgs)
|
||||
{
|
||||
return string.Format(format, formattingArgs);
|
||||
}
|
||||
|
||||
private static readonly Regex CollapseSpace = new Regex(@"\s+", RegexOptions.Compiled);
|
||||
|
||||
public static string Replace(this string text, int index, int length, string replacement)
|
||||
{
|
||||
text = text.Remove(index, length);
|
||||
text = text.Insert(index, replacement);
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string RemoveAccent(this string text)
|
||||
{
|
||||
var normalizedString = text.Normalize(NormalizationForm.FormD);
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
foreach (var c in normalizedString)
|
||||
{
|
||||
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
||||
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
|
||||
{
|
||||
stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
|
||||
}
|
||||
|
||||
public static string TrimEnd(this string text, string postfix)
|
||||
{
|
||||
if (text.EndsWith(postfix))
|
||||
text = text.Substring(0, text.Length - postfix.Length);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string CleanSpaces(this string text)
|
||||
{
|
||||
return CollapseSpace.Replace(text, " ").Trim();
|
||||
}
|
||||
|
||||
public static bool IsNullOrWhiteSpace(this string text)
|
||||
{
|
||||
return String.IsNullOrWhiteSpace(text);
|
||||
}
|
||||
|
||||
public static bool IsNotNullOrWhiteSpace(this string text)
|
||||
{
|
||||
return !String.IsNullOrWhiteSpace(text);
|
||||
}
|
||||
|
||||
public static bool ContainsIgnoreCase(this string text, string contains)
|
||||
{
|
||||
return text.IndexOf(contains, StringComparison.InvariantCultureIgnoreCase) > -1;
|
||||
}
|
||||
|
||||
public static string WrapInQuotes(this string text)
|
||||
{
|
||||
if (!text.Contains(" "))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
return "\"" + text + "\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Common
|
||||
{
|
||||
public static class TryParseExtensions
|
||||
{
|
||||
public static Nullable<int> ParseInt32(this string source)
|
||||
{
|
||||
Int32 result = 0;
|
||||
|
||||
if (Int32.TryParse(source, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Nullable<long> ParseInt64(this string source)
|
||||
{
|
||||
Int64 result = 0;
|
||||
|
||||
if (Int64.TryParse(source, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user