mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
@@ -28,7 +28,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 = 4;
|
private const int DEFINITION_VERSION = 5;
|
||||||
|
|
||||||
//Used when moving yml to C#
|
//Used when moving yml to C#
|
||||||
private readonly List<string> _defintionBlocklist = new List<string>()
|
private readonly List<string> _defintionBlocklist = new List<string>()
|
||||||
|
@@ -48,6 +48,9 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
protected static readonly Regex _LogicFunctionRegex = new Regex(
|
protected static readonly Regex _LogicFunctionRegex = new Regex(
|
||||||
$@"\b({string.Join("|", _SupportedLogicFunctions.Select(Regex.Escape))})(?:\s+(\(?\.[^\)\s]+\)?|""[^""]+"")){{2,}}");
|
$@"\b({string.Join("|", _SupportedLogicFunctions.Select(Regex.Escape))})(?:\s+(\(?\.[^\)\s]+\)?|""[^""]+"")){{2,}}");
|
||||||
|
|
||||||
|
// Matches CSS selectors for the JSON parser
|
||||||
|
protected static readonly Regex _jsonSelectorRegex = new Regex(@"\:(?<filter>.+?)\((?<key>.+?)\)(?=:|\z)", RegexOptions.Compiled);
|
||||||
|
|
||||||
public CardigannSettings Settings { get; set; }
|
public CardigannSettings Settings { get; set; }
|
||||||
|
|
||||||
public CardigannBase(IConfigService configService,
|
public CardigannBase(IConfigService configService,
|
||||||
@@ -234,13 +237,20 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
|
|
||||||
if (selector.Selector != null)
|
if (selector.Selector != null)
|
||||||
{
|
{
|
||||||
var selector_Selector = ApplyGoTemplateText(selector.Selector.TrimStart('.'), variables);
|
var selectorSelector = ApplyGoTemplateText(selector.Selector.TrimStart('.'), variables);
|
||||||
var selection = parentObj.SelectToken(selector_Selector);
|
selectorSelector = JsonParseFieldSelector(parentObj, selectorSelector);
|
||||||
|
|
||||||
|
JToken selection = null;
|
||||||
|
if (selectorSelector != null)
|
||||||
|
{
|
||||||
|
selection = parentObj.SelectToken(selectorSelector);
|
||||||
|
}
|
||||||
|
|
||||||
if (selection == null)
|
if (selection == null)
|
||||||
{
|
{
|
||||||
if (required)
|
if (required)
|
||||||
{
|
{
|
||||||
throw new Exception(string.Format("Selector \"{0}\" didn't match {1}", selector_Selector, parentObj.ToString()));
|
throw new Exception(string.Format("Selector \"{0}\" didn't match {1}", selectorSelector, parentObj.ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -851,5 +861,89 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
|
|
||||||
return settingsBaseUrl;
|
return settingsBaseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected JArray JsonParseRowsSelector(JToken parsedJson, string rowSelector)
|
||||||
|
{
|
||||||
|
var selector = rowSelector.Split(':')[0];
|
||||||
|
var rowsObj = parsedJson.SelectToken(selector).Value<JArray>();
|
||||||
|
return new JArray(rowsObj.Where(t =>
|
||||||
|
JsonParseFieldSelector(t.Value<JObject>(), rowSelector.Remove(0, selector.Length)) != null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string JsonParseFieldSelector(JToken parsedJson, string rowSelector)
|
||||||
|
{
|
||||||
|
var selector = rowSelector.Split(':')[0];
|
||||||
|
JToken parsedObject;
|
||||||
|
if (string.IsNullOrWhiteSpace(selector))
|
||||||
|
{
|
||||||
|
parsedObject = parsedJson;
|
||||||
|
}
|
||||||
|
else if (parsedJson.SelectToken(selector) != null)
|
||||||
|
{
|
||||||
|
parsedObject = parsedJson.SelectToken(selector);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Match match in _jsonSelectorRegex.Matches(rowSelector))
|
||||||
|
{
|
||||||
|
var filter = match.Result("${filter}");
|
||||||
|
var key = match.Result("${key}");
|
||||||
|
Match innerMatch;
|
||||||
|
switch (filter)
|
||||||
|
{
|
||||||
|
case "has":
|
||||||
|
innerMatch = _jsonSelectorRegex.Match(key);
|
||||||
|
if (innerMatch.Success)
|
||||||
|
{
|
||||||
|
if (JsonParseFieldSelector(parsedObject, key) == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (parsedObject.SelectToken(key) == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "not":
|
||||||
|
innerMatch = _jsonSelectorRegex.Match(key);
|
||||||
|
if (innerMatch.Success)
|
||||||
|
{
|
||||||
|
if (JsonParseFieldSelector(parsedObject, key) != null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (parsedObject.SelectToken(key) != null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "contains":
|
||||||
|
if (!parsedObject.ToString().Contains(key))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_logger.Error(string.Format("CardigannIndexer ({0}): Unsupported selector: {1}", _definition.Id, rowSelector));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return selector;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -151,6 +151,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
public int After { get; set; }
|
public int After { get; set; }
|
||||||
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; } = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SearchPathBlock : RequestBlock
|
public class SearchPathBlock : RequestBlock
|
||||||
@@ -200,8 +201,6 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
public class ResponseBlock
|
public class ResponseBlock
|
||||||
{
|
{
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public string Attribute { get; set; }
|
|
||||||
public bool Multiple { get; set; }
|
|
||||||
public string NoResultsMessage { get; set; }
|
public string NoResultsMessage { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -83,16 +83,16 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var rowsObj = parsedJson.SelectToken(search.Rows.Selector);
|
var rowsArray = JsonParseRowsSelector(parsedJson, search.Rows.Selector);
|
||||||
if (rowsObj == null)
|
if (rowsArray == null)
|
||||||
{
|
{
|
||||||
throw new IndexerException(indexerResponse, "Error Parsing Rows Selector");
|
throw new IndexerException(indexerResponse, "Error Parsing Rows Selector");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var row in rowsObj.Value<JArray>())
|
foreach (var row in rowsArray)
|
||||||
{
|
{
|
||||||
var selObj = request.SearchPath.Response.Attribute != null ? row.SelectToken(request.SearchPath.Response.Attribute).Value<JToken>() : row;
|
var selObj = search.Rows.Attribute != null ? row.SelectToken(search.Rows.Attribute).Value<JToken>() : row;
|
||||||
var mulRows = request.SearchPath.Response.Multiple == true ? selObj.Values<JObject>() : new List<JObject> { selObj.Value<JObject>() };
|
var mulRows = search.Rows.Multiple ? selObj.Values<JObject>() : new List<JObject> { selObj.Value<JObject>() };
|
||||||
|
|
||||||
foreach (var mulRow in mulRows)
|
foreach (var mulRow in mulRows)
|
||||||
{
|
{
|
||||||
|
@@ -8,13 +8,6 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
|||||||
public Dictionary<string, object> Variables { get; private set; }
|
public Dictionary<string, object> Variables { get; private set; }
|
||||||
public SearchPathBlock SearchPath { get; private set; }
|
public SearchPathBlock SearchPath { get; private set; }
|
||||||
|
|
||||||
public CardigannRequest(string url, HttpAccept httpAccept, Dictionary<string, object> variables, SearchPathBlock searchPath)
|
|
||||||
: base(url, httpAccept)
|
|
||||||
{
|
|
||||||
Variables = variables;
|
|
||||||
SearchPath = searchPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CardigannRequest(HttpRequest httpRequest, Dictionary<string, object> variables, SearchPathBlock searchPath)
|
public CardigannRequest(HttpRequest httpRequest, Dictionary<string, object> variables, SearchPathBlock searchPath)
|
||||||
: base(httpRequest)
|
: base(httpRequest)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user