1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-27 22:57:09 -04:00

New: Better interface for creating custom formats

This commit is contained in:
ta264
2020-02-18 21:03:05 +00:00
committed by Qstick
parent a5bac30ef3
commit 241bf85f15
74 changed files with 2259 additions and 1090 deletions
@@ -0,0 +1,34 @@
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public abstract class CustomFormatSpecificationBase : ICustomFormatSpecification
{
public abstract int Order { get; }
public abstract string ImplementationName { get; }
public virtual string InfoLink => "https://github.com/Radarr/Radarr/wiki/Custom-Formats-Aphrodite";
public string Name { get; set; }
public bool Negate { get; set; }
public bool Required { get; set; }
public ICustomFormatSpecification Clone()
{
return (ICustomFormatSpecification)MemberwiseClone();
}
public bool IsSatisfiedBy(ParsedMovieInfo movieInfo)
{
var match = IsSatisfiedByWithoutNegate(movieInfo);
if (Negate)
{
match = !match;
}
return match;
}
protected abstract bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo);
}
}
@@ -0,0 +1,16 @@
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class EditionSpecification : RegexSpecificationBase
{
public override int Order => 2;
public override string ImplementationName => "Edition";
public override string InfoLink => "https://github.com/Radarr/Radarr/wiki/Custom-Formats-Aphrodite#edition";
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return MatchString(movieInfo.Edition);
}
}
}
@@ -0,0 +1,17 @@
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public interface ICustomFormatSpecification
{
int Order { get; }
string InfoLink { get; }
string ImplementationName { get; }
string Name { get; set; }
bool Negate { get; set; }
bool Required { get; set; }
ICustomFormatSpecification Clone();
bool IsSatisfiedBy(ParsedMovieInfo movieInfo);
}
}
@@ -0,0 +1,22 @@
using System.Collections.Generic;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class IndexerFlagSpecification : CustomFormatSpecificationBase
{
public override int Order => 4;
public override string ImplementationName => "Indexer Flag";
[FieldDefinition(1, Label = "Flag", Type = FieldType.Select, SelectOptions = typeof(IndexerFlags))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
var flags = movieInfo?.ExtraInfo?.GetValueOrDefault("IndexerFlags") as IndexerFlags?;
return flags?.HasFlag((IndexerFlags)Value) == true;
}
}
}
@@ -0,0 +1,20 @@
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class LanguageSpecification : CustomFormatSpecificationBase
{
public override int Order => 3;
public override string ImplementationName => "Language";
[FieldDefinition(1, Label = "Language", Type = FieldType.Select, SelectOptions = typeof(LanguageFieldConverter))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return movieInfo?.Languages?.Contains((Language)Value) ?? false;
}
}
}
@@ -0,0 +1,20 @@
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Core.CustomFormats
{
public class QualityModifierSpecification : CustomFormatSpecificationBase
{
public override int Order => 7;
public override string ImplementationName => "Quality Modifier";
[FieldDefinition(1, Label = "Quality Modifier", Type = FieldType.Select, SelectOptions = typeof(Modifier))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return (movieInfo?.Quality?.Quality?.Modifier ?? (int)Modifier.NONE) == (Modifier)Value;
}
}
}
@@ -0,0 +1,32 @@
using System.Text.RegularExpressions;
using NzbDrone.Core.Annotations;
namespace NzbDrone.Core.CustomFormats
{
public abstract class RegexSpecificationBase : CustomFormatSpecificationBase
{
protected Regex _regex;
protected string _raw;
[FieldDefinition(1, Label = "Regular Expression")]
public string Value
{
get => _raw;
set
{
_raw = value;
_regex = new Regex(value, RegexOptions.Compiled | RegexOptions.IgnoreCase);
}
}
protected bool MatchString(string compared)
{
if (compared == null || _regex == null)
{
return false;
}
return _regex.IsMatch(compared);
}
}
}
@@ -0,0 +1,20 @@
using System.Collections.Generic;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class ReleaseTitleSpecification : RegexSpecificationBase
{
public override int Order => 1;
public override string ImplementationName => "Release Title";
public override string InfoLink => "https://github.com/Radarr/Radarr/wiki/Custom-Formats-Aphrodite#release-title";
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
var filename = (string)movieInfo?.ExtraInfo?.GetValueOrDefault("Filename");
return MatchString(movieInfo?.SimpleReleaseTitle) || MatchString(filename);
}
}
}
@@ -0,0 +1,20 @@
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class ResolutionSpecification : CustomFormatSpecificationBase
{
public override int Order => 6;
public override string ImplementationName => "Resolution";
[FieldDefinition(1, Label = "Resolution", Type = FieldType.Select, SelectOptions = typeof(Resolution))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return (movieInfo?.Quality?.Quality?.Resolution ?? (int)Resolution.Unknown) == Value;
}
}
}
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class SizeSpecification : CustomFormatSpecificationBase
{
public override int Order => 8;
public override string ImplementationName => "Size";
[FieldDefinition(1, Label = "Minimum Size", Unit = "GB", Type = FieldType.Number)]
public double Min { get; set; }
[FieldDefinition(1, Label = "Maximum Size", Unit = "GB", Type = FieldType.Number)]
public double Max { get; set; }
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
var size = (movieInfo?.ExtraInfo?.GetValueOrDefault("Size", 0.0) as long?) ?? 0;
return size > Min.Gigabytes() && size < Max.Gigabytes();
}
}
}
@@ -0,0 +1,20 @@
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Core.CustomFormats
{
public class SourceSpecification : CustomFormatSpecificationBase
{
public override int Order => 5;
public override string ImplementationName => "Source";
[FieldDefinition(1, Label = "Source", Type = FieldType.Select, SelectOptions = typeof(Source))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return (movieInfo?.Quality?.Quality?.Source ?? (int)Source.UNKNOWN) == (Source)Value;
}
}
}