Jackett/src/Jackett.Common/Utils/Extensions.cs

163 lines
4.4 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
2017-08-07 20:33:23 +00:00
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Jackett.Common.Utils
{
public class NonNullException : Exception
{
public NonNullException() : base("Parameter cannot be null")
{
}
}
public class NonNull<T> where T : class
{
public NonNull(T val)
{
if (val == null)
new NonNullException();
Value = val;
}
public static implicit operator T(NonNull<T> n)
{
return n.Value;
}
private T Value;
}
Feature/new api (#1584) * Introducing API v2 There were multiple inconsistencies in the old API and I have been toying with the idea to replace it. This will suck for everyone who was building on top of the Jackett API, however as it was probably too painful to do so I'd say no one really tried. Now API v2.0 should be much more constistent as it uses DTObjects, and instead of manually constructing a json response it is handled by the ASP.NET web api. It is much more RESTful than it was, proper GET endpoints are introduced, and updating resources are now done via POST - it might be improved by introducing other type of REST methods. I know this sucks as completely breaks backward compatibility, however it'll probably make it easier to maintain and build on top of in the long run. * Use DELETE method to unconfigure an indexer * Remove debugging format from NLog * Fixing an null exception * Properly implementing IExceptionFilter interface * Enable adding public indexers without configuration * Fix missing manual search results * Basic modularization of the JS API * Introduce API versioning * Fix redirects to the dashboard * Cleaning up a little bit * Revamping Torznab and Potato as well * Move preconditions to FilterAttributes and simplify logic * Remove legacy filtering... will move to IResultFilter * Minor adjustment on results interface * Use Interpolated strings in ResultsController * DTO-ify * Remove fallback logic from potato results * DTO everywhere!!! * DTO-ify everything! * I hope this is my last piece of modification to this PR * Remove test variables... * Left out a couple conflicts... It's late
2017-08-08 15:02:16 +00:00
public static class GenericConversionExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this T obj)
{
return new T[] { obj };
}
2017-08-07 20:33:23 +00:00
Feature/new api (#1584) * Introducing API v2 There were multiple inconsistencies in the old API and I have been toying with the idea to replace it. This will suck for everyone who was building on top of the Jackett API, however as it was probably too painful to do so I'd say no one really tried. Now API v2.0 should be much more constistent as it uses DTObjects, and instead of manually constructing a json response it is handled by the ASP.NET web api. It is much more RESTful than it was, proper GET endpoints are introduced, and updating resources are now done via POST - it might be improved by introducing other type of REST methods. I know this sucks as completely breaks backward compatibility, however it'll probably make it easier to maintain and build on top of in the long run. * Use DELETE method to unconfigure an indexer * Remove debugging format from NLog * Fixing an null exception * Properly implementing IExceptionFilter interface * Enable adding public indexers without configuration * Fix missing manual search results * Basic modularization of the JS API * Introduce API versioning * Fix redirects to the dashboard * Cleaning up a little bit * Revamping Torznab and Potato as well * Move preconditions to FilterAttributes and simplify logic * Remove legacy filtering... will move to IResultFilter * Minor adjustment on results interface * Use Interpolated strings in ResultsController * DTO-ify * Remove fallback logic from potato results * DTO everywhere!!! * DTO-ify everything! * I hope this is my last piece of modification to this PR * Remove test variables... * Left out a couple conflicts... It's late
2017-08-08 15:02:16 +00:00
public static NonNull<T> ToNonNull<T>(this T obj) where T : class
2017-08-07 20:33:23 +00:00
{
Feature/new api (#1584) * Introducing API v2 There were multiple inconsistencies in the old API and I have been toying with the idea to replace it. This will suck for everyone who was building on top of the Jackett API, however as it was probably too painful to do so I'd say no one really tried. Now API v2.0 should be much more constistent as it uses DTObjects, and instead of manually constructing a json response it is handled by the ASP.NET web api. It is much more RESTful than it was, proper GET endpoints are introduced, and updating resources are now done via POST - it might be improved by introducing other type of REST methods. I know this sucks as completely breaks backward compatibility, however it'll probably make it easier to maintain and build on top of in the long run. * Use DELETE method to unconfigure an indexer * Remove debugging format from NLog * Fixing an null exception * Properly implementing IExceptionFilter interface * Enable adding public indexers without configuration * Fix missing manual search results * Basic modularization of the JS API * Introduce API versioning * Fix redirects to the dashboard * Cleaning up a little bit * Revamping Torznab and Potato as well * Move preconditions to FilterAttributes and simplify logic * Remove legacy filtering... will move to IResultFilter * Minor adjustment on results interface * Use Interpolated strings in ResultsController * DTO-ify * Remove fallback logic from potato results * DTO everywhere!!! * DTO-ify everything! * I hope this is my last piece of modification to this PR * Remove test variables... * Left out a couple conflicts... It's late
2017-08-08 15:02:16 +00:00
return new NonNull<T>(obj);
2017-08-07 20:33:23 +00:00
}
}
Feature/new api (#1584) * Introducing API v2 There were multiple inconsistencies in the old API and I have been toying with the idea to replace it. This will suck for everyone who was building on top of the Jackett API, however as it was probably too painful to do so I'd say no one really tried. Now API v2.0 should be much more constistent as it uses DTObjects, and instead of manually constructing a json response it is handled by the ASP.NET web api. It is much more RESTful than it was, proper GET endpoints are introduced, and updating resources are now done via POST - it might be improved by introducing other type of REST methods. I know this sucks as completely breaks backward compatibility, however it'll probably make it easier to maintain and build on top of in the long run. * Use DELETE method to unconfigure an indexer * Remove debugging format from NLog * Fixing an null exception * Properly implementing IExceptionFilter interface * Enable adding public indexers without configuration * Fix missing manual search results * Basic modularization of the JS API * Introduce API versioning * Fix redirects to the dashboard * Cleaning up a little bit * Revamping Torznab and Potato as well * Move preconditions to FilterAttributes and simplify logic * Remove legacy filtering... will move to IResultFilter * Minor adjustment on results interface * Use Interpolated strings in ResultsController * DTO-ify * Remove fallback logic from potato results * DTO everywhere!!! * DTO-ify everything! * I hope this is my last piece of modification to this PR * Remove test variables... * Left out a couple conflicts... It's late
2017-08-08 15:02:16 +00:00
public static class EnumerableExtension
{
Feature/new api (#1584) * Introducing API v2 There were multiple inconsistencies in the old API and I have been toying with the idea to replace it. This will suck for everyone who was building on top of the Jackett API, however as it was probably too painful to do so I'd say no one really tried. Now API v2.0 should be much more constistent as it uses DTObjects, and instead of manually constructing a json response it is handled by the ASP.NET web api. It is much more RESTful than it was, proper GET endpoints are introduced, and updating resources are now done via POST - it might be improved by introducing other type of REST methods. I know this sucks as completely breaks backward compatibility, however it'll probably make it easier to maintain and build on top of in the long run. * Use DELETE method to unconfigure an indexer * Remove debugging format from NLog * Fixing an null exception * Properly implementing IExceptionFilter interface * Enable adding public indexers without configuration * Fix missing manual search results * Basic modularization of the JS API * Introduce API versioning * Fix redirects to the dashboard * Cleaning up a little bit * Revamping Torznab and Potato as well * Move preconditions to FilterAttributes and simplify logic * Remove legacy filtering... will move to IResultFilter * Minor adjustment on results interface * Use Interpolated strings in ResultsController * DTO-ify * Remove fallback logic from potato results * DTO everywhere!!! * DTO-ify everything! * I hope this is my last piece of modification to this PR * Remove test variables... * Left out a couple conflicts... It's late
2017-08-08 15:02:16 +00:00
public static string AsString(this IEnumerable<char> chars)
{
Feature/new api (#1584) * Introducing API v2 There were multiple inconsistencies in the old API and I have been toying with the idea to replace it. This will suck for everyone who was building on top of the Jackett API, however as it was probably too painful to do so I'd say no one really tried. Now API v2.0 should be much more constistent as it uses DTObjects, and instead of manually constructing a json response it is handled by the ASP.NET web api. It is much more RESTful than it was, proper GET endpoints are introduced, and updating resources are now done via POST - it might be improved by introducing other type of REST methods. I know this sucks as completely breaks backward compatibility, however it'll probably make it easier to maintain and build on top of in the long run. * Use DELETE method to unconfigure an indexer * Remove debugging format from NLog * Fixing an null exception * Properly implementing IExceptionFilter interface * Enable adding public indexers without configuration * Fix missing manual search results * Basic modularization of the JS API * Introduce API versioning * Fix redirects to the dashboard * Cleaning up a little bit * Revamping Torznab and Potato as well * Move preconditions to FilterAttributes and simplify logic * Remove legacy filtering... will move to IResultFilter * Minor adjustment on results interface * Use Interpolated strings in ResultsController * DTO-ify * Remove fallback logic from potato results * DTO everywhere!!! * DTO-ify everything! * I hope this is my last piece of modification to this PR * Remove test variables... * Left out a couple conflicts... It's late
2017-08-08 15:02:16 +00:00
return String.Concat(chars);
}
public static bool IsEmpty<T>(this IEnumerable<T> collection)
{
return collection.Count() > 0;
}
public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> list)
{
return list.SelectMany(x => x);
}
}
public static class StringExtension
{
public static bool IsNullOrEmptyOrWhitespace(this string str)
{
return string.IsNullOrEmpty(str) || string.IsNullOrWhiteSpace(str);
}
public static DateTime ToDateTime(this string str)
{
return DateTime.Parse(str);
}
public static Uri ToUri(this string str)
{
return new Uri(str);
}
}
public static class CollectionExtension
{
public static bool IsEmpty<T>(this ICollection<T> obj)
{
return obj.Count == 0;
}
public static bool IsEmptyOrNull<T>(this ICollection<T> obj)
{
return obj == null || obj.IsEmpty();
}
}
public static class XElementExtension
{
public static XElement First(this XElement element, string name)
{
return element.Descendants(name).First();
}
public static string FirstValue(this XElement element, string name)
{
return element.First(name).Value;
}
}
Feature/new api (#1584) * Introducing API v2 There were multiple inconsistencies in the old API and I have been toying with the idea to replace it. This will suck for everyone who was building on top of the Jackett API, however as it was probably too painful to do so I'd say no one really tried. Now API v2.0 should be much more constistent as it uses DTObjects, and instead of manually constructing a json response it is handled by the ASP.NET web api. It is much more RESTful than it was, proper GET endpoints are introduced, and updating resources are now done via POST - it might be improved by introducing other type of REST methods. I know this sucks as completely breaks backward compatibility, however it'll probably make it easier to maintain and build on top of in the long run. * Use DELETE method to unconfigure an indexer * Remove debugging format from NLog * Fixing an null exception * Properly implementing IExceptionFilter interface * Enable adding public indexers without configuration * Fix missing manual search results * Basic modularization of the JS API * Introduce API versioning * Fix redirects to the dashboard * Cleaning up a little bit * Revamping Torznab and Potato as well * Move preconditions to FilterAttributes and simplify logic * Remove legacy filtering... will move to IResultFilter * Minor adjustment on results interface * Use Interpolated strings in ResultsController * DTO-ify * Remove fallback logic from potato results * DTO everywhere!!! * DTO-ify everything! * I hope this is my last piece of modification to this PR * Remove test variables... * Left out a couple conflicts... It's late
2017-08-08 15:02:16 +00:00
public static class KeyValuePairsExtension
{
public static IDictionary<Key, Value> ToDictionary<Key, Value>(this IEnumerable<KeyValuePair<Key, Value>> pairs)
{
return pairs.ToDictionary(x => x.Key, x => x.Value);
}
}
public static class ParseExtension
{
public static T? TryParse<T>(this string value) where T : struct
{
var type = typeof(T);
var parseMethods = type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).Where(m => m.Name == "Parse");
var parseMethod = parseMethods.Where(m =>
{
var parameters = m.GetParameters();
var hasOnlyOneParameter = parameters.Count() == 1;
var firstParameterIsString = parameters.First().ParameterType == typeof(string);
return hasOnlyOneParameter && firstParameterIsString;
}).First();
if (parseMethod == null)
return null;
try
{
var val = parseMethod.Invoke(null, new object[] { value });
return (T)val;
}
catch
{
return null;
}
}
}
2017-08-07 20:33:23 +00:00
public static class TaskExtensions
{
public static Task<IEnumerable<TResult>> Until<TResult>(this IEnumerable<Task<TResult>> tasks, TimeSpan timeout)
{
var timeoutTask = Task.Delay(timeout);
var aggregateTask = Task.WhenAll(tasks);
var anyTask = Task.WhenAny(timeoutTask, aggregateTask);
var continuation = anyTask.ContinueWith((_) =>
{
var completedTasks = tasks.Where(t => t.Status == TaskStatus.RanToCompletion);
var results = completedTasks.Select(t => t.Result);
return results;
});
return continuation;
}
}
}