New: (Cardigann) Bump to v9 (#1551)

* New: (Cardigann) Add MissingAttributeEqualsNoResults support

(cherry picked from commit 4e8bb37a5c)

* New: (Cardigann) Add AllowEmptyInputs

* New: (Cardigann) Bump to v9

* New: (Cardigann) Add default value for fields
This commit is contained in:
Bogdan
2023-03-30 14:57:04 +03:00
committed by GitHub
parent 26f700731b
commit bceebc34c1
5 changed files with 58 additions and 18 deletions

View File

@@ -29,7 +29,7 @@ namespace NzbDrone.Core.IndexerVersions
/* Update Service will fall back if version # does not exist for an indexer per Ta */ /* Update Service will fall back if version # does not exist for an indexer per Ta */
private const string DEFINITION_BRANCH = "master"; private const string DEFINITION_BRANCH = "master";
private const int DEFINITION_VERSION = 8; private const int DEFINITION_VERSION = 9;
// Used when moving yml to C# // Used when moving yml to C#
private readonly List<string> _definitionBlocklist = new () private readonly List<string> _definitionBlocklist = new ()

View File

@@ -825,9 +825,19 @@ namespace NzbDrone.Core.Indexers.Cardigann
protected JArray JsonParseRowsSelector(JToken parsedJson, string rowSelector) protected JArray JsonParseRowsSelector(JToken parsedJson, string rowSelector)
{ {
var selector = rowSelector.Split(':')[0]; var selector = rowSelector.Split(':')[0];
var rowsObj = parsedJson.SelectToken(selector).Value<JArray>();
return new JArray(rowsObj.Where(t => try
JsonParseFieldSelector(t.Value<JObject>(), rowSelector.Remove(0, selector.Length)) != null)); {
var rowsObj = parsedJson.SelectToken(selector).Value<JArray>();
return new JArray(rowsObj.Where(t => JsonParseFieldSelector(t.Value<JObject>(), rowSelector.Remove(0, selector.Length)) != null));
}
catch (Exception ex)
{
_logger.Trace(ex, "Failed to parse JSON rows for selector \"{0}\"", rowSelector);
return null;
}
} }
private string JsonParseFieldSelector(JToken parsedJson, string rowSelector) private string JsonParseFieldSelector(JToken parsedJson, string rowSelector)

View File

@@ -116,6 +116,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
{ {
public string Selector { get; set; } public string Selector { get; set; }
public bool Optional { get; set; } public bool Optional { get; set; }
public string Default { get; set; }
public string Text { get; set; } public string Text { get; set; }
public string Attribute { get; set; } public string Attribute { get; set; }
public string Remove { get; set; } public string Remove { get; set; }
@@ -146,6 +147,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
public List<SearchPathBlock> Paths { get; set; } public List<SearchPathBlock> Paths { get; set; }
public Dictionary<string, List<string>> Headers { get; set; } public Dictionary<string, List<string>> Headers { get; set; }
public List<FilterBlock> Keywordsfilters { get; set; } public List<FilterBlock> Keywordsfilters { get; set; }
public bool AllowEmptyInputs { get; set; }
public Dictionary<string, string> Inputs { get; set; } public Dictionary<string, string> Inputs { get; set; }
public List<ErrorBlock> Error { get; set; } public List<ErrorBlock> Error { get; set; }
public List<FilterBlock> Preprocessingfilters { get; set; } public List<FilterBlock> Preprocessingfilters { get; set; }
@@ -159,6 +161,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
public SelectorBlock Dateheaders { get; set; } public SelectorBlock Dateheaders { get; set; }
public SelectorBlock Count { get; set; } public SelectorBlock Count { get; set; }
public bool Multiple { get; set; } public bool Multiple { get; set; }
public bool MissingAttributeEqualsNoResults { get; set; }
} }
public class SearchPathBlock : RequestBlock public class SearchPathBlock : RequestBlock

View File

@@ -90,8 +90,14 @@ namespace NzbDrone.Core.Indexers.Cardigann
} }
var rowsArray = JsonParseRowsSelector(parsedJson, search.Rows.Selector); var rowsArray = JsonParseRowsSelector(parsedJson, search.Rows.Selector);
if (rowsArray == null) if (rowsArray == null)
{ {
if (search.Rows.MissingAttributeEqualsNoResults)
{
return releases;
}
throw new IndexerException(indexerResponse, "Error Parsing Rows Selector"); throw new IndexerException(indexerResponse, "Error Parsing Rows Selector");
} }
@@ -117,6 +123,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
string value = null; string value = null;
var variablesKey = ".Result." + fieldName; var variablesKey = ".Result." + fieldName;
var isOptional = OptionalFields.Contains(field.Key) || fieldModifiers.Contains("optional") || field.Value.Optional; var isOptional = OptionalFields.Contains(field.Key) || fieldModifiers.Contains("optional") || field.Value.Optional;
try try
{ {
var parentObj = mulRow; var parentObj = mulRow;
@@ -126,28 +133,35 @@ namespace NzbDrone.Core.Indexers.Cardigann
} }
value = HandleJsonSelector(field.Value, parentObj, variables, !isOptional); value = HandleJsonSelector(field.Value, parentObj, variables, !isOptional);
if (isOptional && string.IsNullOrWhiteSpace(value))
if (isOptional && value.IsNullOrWhiteSpace())
{ {
variables[variablesKey] = null; var defaultValue = ApplyGoTemplateText(field.Value.Default, variables);
continue;
if (defaultValue.IsNullOrWhiteSpace())
{
variables[variablesKey] = null;
continue;
}
value = defaultValue;
} }
variables[variablesKey] = ParseFields(value, fieldName, release, fieldModifiers, searchUrlUri); variables[variablesKey] = ParseFields(value, fieldName, release, fieldModifiers, searchUrlUri);
} }
catch (Exception ex) catch (Exception ex)
{ {
if (!variables.ContainsKey(variablesKey)) if (!variables.ContainsKey(variablesKey) || isOptional)
{ {
variables[variablesKey] = null; variables[variablesKey] = null;
} }
if (isOptional) if (isOptional)
{ {
variables[variablesKey] = null;
continue; continue;
} }
throw new CardigannException(string.Format("Error while parsing field={0}, selector={1}, value={2}: {3}", field.Key, field.Value.Selector, value ?? "<null>", ex.Message)); throw new CardigannException($"Error while parsing field={field.Key}, selector={field.Value.Selector}, value={value ?? "<null>"}: {ex.Message}", ex);
} }
} }
@@ -248,34 +262,41 @@ namespace NzbDrone.Core.Indexers.Cardigann
string value = null; string value = null;
var variablesKey = ".Result." + fieldName; var variablesKey = ".Result." + fieldName;
var isOptional = OptionalFields.Contains(field.Key) || fieldModifiers.Contains("optional") || field.Value.Optional; var isOptional = OptionalFields.Contains(field.Key) || fieldModifiers.Contains("optional") || field.Value.Optional;
try try
{ {
value = HandleSelector(field.Value, row, variables, !isOptional); value = HandleSelector(field.Value, row, variables, !isOptional);
if (isOptional && string.IsNullOrWhiteSpace(value)) if (isOptional && value.IsNullOrWhiteSpace())
{ {
variables[variablesKey] = null; var defaultValue = ApplyGoTemplateText(field.Value.Default, variables);
continue;
if (defaultValue.IsNullOrWhiteSpace())
{
variables[variablesKey] = null;
continue;
}
value = defaultValue;
} }
variables[variablesKey] = ParseFields(value, fieldName, release, fieldModifiers, searchUrlUri); variables[variablesKey] = ParseFields(value, fieldName, release, fieldModifiers, searchUrlUri);
} }
catch (Exception ex) catch (Exception ex)
{ {
if (!variables.ContainsKey(variablesKey)) if (!variables.ContainsKey(variablesKey) || isOptional)
{ {
variables[variablesKey] = null; variables[variablesKey] = null;
} }
if (OptionalFields.Contains(field.Key) || fieldModifiers.Contains("optional") || field.Value.Optional) if (isOptional)
{ {
variables[variablesKey] = null;
continue; continue;
} }
if (indexerLogging) if (indexerLogging)
{ {
_logger.Trace("Error while parsing field={0}, selector={1}, value={2}: {3}", field.Key, field.Value.Selector, value == null ? "<null>" : value, ex.Message); _logger.Trace(ex, "Error while parsing field={0}, selector={1}, value={2}: {3}", field.Key, field.Value.Selector, value ?? "<null>", ex.Message);
} }
} }
} }

View File

@@ -9,6 +9,7 @@ using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser; using AngleSharp.Html.Parser;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog; using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Indexers.Definitions.Cardigann; using NzbDrone.Core.Indexers.Definitions.Cardigann;
@@ -1119,7 +1120,12 @@ namespace NzbDrone.Core.Indexers.Cardigann
} }
else else
{ {
queryCollection.Add(input.Key, ApplyGoTemplateText(input.Value, variables)); var inputValue = ApplyGoTemplateText(input.Value, variables);
if (inputValue.IsNotNullOrWhiteSpace() || search.AllowEmptyInputs)
{
queryCollection.Add(input.Key, inputValue);
}
} }
} }
} }