2020-02-09 02:35:16 +00:00
|
|
|
using System;
|
2015-04-13 06:25:21 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2018-03-10 08:05:56 +00:00
|
|
|
using Jackett.Common.Services.Interfaces;
|
|
|
|
using Jackett.Common.Utils;
|
|
|
|
using Newtonsoft.Json.Linq;
|
2015-04-13 06:25:21 +00:00
|
|
|
|
2018-03-10 08:05:56 +00:00
|
|
|
namespace Jackett.Common.Models.IndexerConfig
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
2016-10-27 07:30:03 +00:00
|
|
|
public class ConfigurationData
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
2020-04-21 06:45:21 +00:00
|
|
|
private const string PASSWORD_REPLACEMENT = "|||%%PREVJACKPASSWD%%|||";
|
2021-03-16 23:29:26 +00:00
|
|
|
protected Dictionary<string, ConfigurationItem> dynamics = new Dictionary<string, ConfigurationItem>(); // list for dynamic items
|
2015-08-07 19:09:13 +00:00
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public HiddenStringConfigurationItem CookieHeader { get; private set; } = new HiddenStringConfigurationItem(name:"CookieHeader");
|
|
|
|
public HiddenStringConfigurationItem LastError { get; private set; } = new HiddenStringConfigurationItem(name:"LastError");
|
|
|
|
public StringConfigurationItem SiteLink { get; private set; } = new StringConfigurationItem(name:"Site Link");
|
2015-08-03 21:38:45 +00:00
|
|
|
|
2020-04-21 06:45:21 +00:00
|
|
|
public ConfigurationData()
|
2015-07-27 00:03:51 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Loads all JSON values into the matching properties.
|
|
|
|
/// </summary>
|
2020-12-11 23:12:40 +00:00
|
|
|
public void LoadConfigDataValuesFromJson(JToken json, IProtectionService ps = null)
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
2016-12-10 16:53:41 +00:00
|
|
|
if (json == null)
|
|
|
|
return;
|
2020-04-21 06:45:21 +00:00
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
var jsonArray = (JArray)json;
|
2020-04-21 06:45:21 +00:00
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
foreach (var item in GetAllConfigurationItems().Where(x => x.CanBeSavedToFile))
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
var jsonToken = jsonArray.FirstOrDefault(f => f.Value<string>("id") == item.ID);
|
|
|
|
if (jsonToken == null)
|
2015-08-03 21:38:45 +00:00
|
|
|
continue;
|
2020-04-21 06:45:21 +00:00
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
switch (item)
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
case StringConfigurationItem stringItem:
|
|
|
|
{
|
|
|
|
if (HasPasswordValue(item))
|
2015-08-07 19:09:13 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
var pw = ReadValueAs<string>(jsonToken);
|
|
|
|
if (pw != PASSWORD_REPLACEMENT)
|
2015-08-07 19:09:13 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
stringItem.Value = ps != null ? ps.UnProtect(pw) : pw;
|
2015-08-07 19:09:13 +00:00
|
|
|
}
|
2017-04-15 08:45:10 +00:00
|
|
|
}
|
2017-01-02 20:39:28 +00:00
|
|
|
else
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
stringItem.Value = ReadValueAs<string>(jsonToken);
|
2020-04-21 06:45:21 +00:00
|
|
|
}
|
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
case HiddenStringConfigurationItem hiddenStringItem:
|
|
|
|
{
|
|
|
|
hiddenStringItem.Value = ReadValueAs<string>(jsonToken);
|
2020-04-21 06:45:21 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
case BoolConfigurationItem boolItem:
|
|
|
|
{
|
|
|
|
boolItem.Value = ReadValueAs<bool>(jsonToken);
|
2020-04-21 06:45:21 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
case SingleSelectConfigurationItem singleSelectItem:
|
|
|
|
{
|
|
|
|
singleSelectItem.Value = ReadValueAs<string>(jsonToken);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MultiSelectConfigurationItem multiSelectItem:
|
|
|
|
{
|
|
|
|
var values = jsonToken.Value<JArray>("values");
|
2020-04-21 06:45:21 +00:00
|
|
|
if (values != null)
|
2021-03-16 23:29:26 +00:00
|
|
|
{
|
|
|
|
multiSelectItem.Values = values.Values<string>().ToArray();
|
|
|
|
}
|
2020-04-21 06:45:21 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
case PasswordConfigurationItem passwordItem:
|
|
|
|
{
|
|
|
|
var pw = ReadValueAs<string>(jsonToken);
|
|
|
|
if (pw != PASSWORD_REPLACEMENT)
|
|
|
|
{
|
|
|
|
passwordItem.Value = ps != null ? ps.UnProtect(pw) : pw;
|
|
|
|
}
|
2020-04-21 06:45:21 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
2015-04-13 06:25:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
private T ReadValueAs<T>(JToken jToken) => jToken.Value<T>("value");
|
|
|
|
|
|
|
|
private bool HasPasswordValue(ConfigurationItem item)
|
|
|
|
=> string.Equals(item.Name, "password", StringComparison.InvariantCultureIgnoreCase);
|
|
|
|
|
2015-08-07 19:09:13 +00:00
|
|
|
public JToken ToJson(IProtectionService ps, bool forDisplay = true)
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
|
|
|
var jArray = new JArray();
|
2021-03-16 23:29:26 +00:00
|
|
|
|
|
|
|
var configurationItems = GetConfigurationItems(forDisplay);
|
|
|
|
foreach (var configurationItem in configurationItems)
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
JObject jObject = null;
|
|
|
|
|
|
|
|
switch (configurationItem)
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
case ConfigurationItemMaybePassword maybePassword:
|
|
|
|
{
|
|
|
|
// Remove this code and give each derived ConfigurationItem class its own ToJson method
|
|
|
|
// as soon as everyone is using PasswordConfigurationItem for passwords.
|
|
|
|
jObject = maybePassword.ToJson(ps);
|
2015-04-13 06:25:21 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
case BoolConfigurationItem boolItem:
|
|
|
|
{
|
|
|
|
jObject = boolItem.ToJson();
|
2015-04-13 06:25:21 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
case SingleSelectConfigurationItem singleSelectItem:
|
|
|
|
{
|
|
|
|
jObject = singleSelectItem.ToJson();
|
2020-02-19 20:23:55 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
case MultiSelectConfigurationItem multiSelectItem:
|
|
|
|
{
|
|
|
|
jObject = multiSelectItem.ToJson();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DisplayImageConfigurationItem imageItem:
|
|
|
|
{
|
|
|
|
jObject = imageItem.ToJson();
|
2017-05-28 16:12:41 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
case PasswordConfigurationItem passwordItem:
|
|
|
|
{
|
|
|
|
jObject = passwordItem.ToJson(forDisplay, ps);
|
2015-04-13 06:25:21 +00:00
|
|
|
break;
|
2021-03-16 23:29:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (jObject != null)
|
|
|
|
{
|
|
|
|
jArray.Add(jObject);
|
2015-04-13 06:25:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return jArray;
|
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
private IEnumerable<ConfigurationItem> GetAllConfigurationItems()
|
2015-08-03 21:38:45 +00:00
|
|
|
{
|
2020-04-21 06:45:21 +00:00
|
|
|
var properties = GetType()
|
|
|
|
.GetProperties()
|
|
|
|
.Where(p => p.CanRead)
|
2021-03-16 23:29:26 +00:00
|
|
|
.Where(p => p.PropertyType.IsSubclassOf(typeof(ConfigurationItem)))
|
2020-10-08 19:16:22 +00:00
|
|
|
.Where(p => p.GetValue(this) != null)
|
2021-03-16 23:29:26 +00:00
|
|
|
.Select(p => (ConfigurationItem)p.GetValue(this)).ToList();
|
2020-04-21 06:45:21 +00:00
|
|
|
|
|
|
|
// remove/insert Site Link manualy to make sure it shows up first
|
|
|
|
properties.Remove(SiteLink);
|
|
|
|
properties.Insert(0, SiteLink);
|
|
|
|
|
|
|
|
properties.AddRange(dynamics.Values);
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
return properties;
|
|
|
|
}
|
|
|
|
|
|
|
|
private ConfigurationItem[] GetConfigurationItems(bool forDisplay)
|
|
|
|
=> GetAllConfigurationItems().Where(p => forDisplay ? p.CanBeShownToUser : p.CanBeSavedToFile).ToArray();
|
|
|
|
|
|
|
|
public void AddDynamic(string ID, ConfigurationItem item) => dynamics[ID] = item;
|
|
|
|
|
|
|
|
public ConfigurationItem GetDynamic(string ID) => dynamics.TryGetValue(ID, out var value) ? value : null;
|
|
|
|
|
|
|
|
public ConfigurationItem GetDynamicByName(string Name)
|
|
|
|
=> dynamics.Values.FirstOrDefault(i => string.Equals(i.Name, Name, StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
|
|
|
|
public abstract class ConfigurationItem
|
|
|
|
{
|
|
|
|
public string ID => Name.Replace(" ", "").ToLower();
|
|
|
|
public string Name { get; }
|
|
|
|
public string ItemType { get; }
|
|
|
|
|
|
|
|
public bool CanBeShownToUser { get; } = true;
|
|
|
|
public bool CanBeSavedToFile { get; } = true;
|
|
|
|
|
|
|
|
protected ConfigurationItem(string name, string itemType, bool canBeShownToUser = true, bool canBeSavedToFile = true)
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
Name = name; // TODO Error when name is null/empty/not unique/...
|
|
|
|
ItemType = itemType;
|
|
|
|
CanBeShownToUser = canBeShownToUser;
|
|
|
|
CanBeSavedToFile = canBeSavedToFile;
|
2020-04-21 06:45:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
protected JObject CreateJObject()
|
|
|
|
{
|
|
|
|
return new JObject
|
|
|
|
{
|
|
|
|
["id"] = ID,
|
|
|
|
["type"] = ItemType.ToLower(),
|
|
|
|
["name"] = Name
|
|
|
|
};
|
|
|
|
}
|
2015-08-03 21:38:45 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Remove this class when all passwords are configured to use the correct class: PasswordConfigurationItem.
|
|
|
|
/// </summary>
|
|
|
|
public abstract class ConfigurationItemMaybePassword : ConfigurationItem
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
public string Value { get; set; }
|
|
|
|
|
|
|
|
protected ConfigurationItemMaybePassword(string name, string itemType, bool canBeShownToUser = true, bool canBeSavedToFile = true)
|
|
|
|
: base(name, itemType, canBeShownToUser, canBeSavedToFile)
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
|
|
|
}
|
2021-03-16 23:29:26 +00:00
|
|
|
|
|
|
|
public JObject ToJson(IProtectionService protectionService = null)
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
var jObject = CreateJObject();
|
|
|
|
|
|
|
|
if (string.Equals(Name, "password", StringComparison.InvariantCultureIgnoreCase))
|
|
|
|
{
|
|
|
|
var password = Value;
|
|
|
|
if (string.IsNullOrEmpty(password))
|
|
|
|
password = string.Empty;
|
|
|
|
else if (protectionService != null)
|
|
|
|
password = protectionService.Protect(password);
|
|
|
|
jObject["value"] = password;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
jObject["value"] = Value;
|
|
|
|
}
|
|
|
|
return jObject;
|
2020-04-21 06:45:21 +00:00
|
|
|
}
|
2020-04-20 22:52:42 +00:00
|
|
|
}
|
2018-06-26 15:47:19 +00:00
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public class StringConfigurationItem : ConfigurationItemMaybePassword
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
public StringConfigurationItem(string name)
|
|
|
|
: base(name, itemType: "inputstring")
|
|
|
|
{
|
|
|
|
}
|
2015-04-13 06:25:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public class HiddenStringConfigurationItem : ConfigurationItemMaybePassword
|
2015-08-02 17:28:59 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
public HiddenStringConfigurationItem(string name)
|
|
|
|
: base(name, itemType: "hiddendata", canBeShownToUser: false)
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
|
|
|
}
|
2015-08-02 17:28:59 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public class DisplayInfoConfigurationItem : ConfigurationItemMaybePassword
|
2015-04-18 06:05:30 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
public DisplayInfoConfigurationItem(string name, string value)
|
|
|
|
: base(name, itemType: "displayinfo", canBeSavedToFile: false)
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
|
|
|
Value = value;
|
|
|
|
}
|
2015-04-18 06:05:30 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public class BoolConfigurationItem : ConfigurationItem
|
2015-04-13 06:25:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
public bool Value { get; set; }
|
|
|
|
|
|
|
|
public BoolConfigurationItem(string name)
|
|
|
|
: base(name, itemType: "inputbool")
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public JObject ToJson()
|
|
|
|
{
|
|
|
|
var jObject = CreateJObject();
|
|
|
|
jObject["value"] = Value;
|
|
|
|
return jObject;
|
|
|
|
}
|
2015-04-13 06:25:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public class DisplayImageConfigurationItem : ConfigurationItem
|
2020-02-19 20:23:55 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
public byte[] Value { get; set; }
|
|
|
|
|
|
|
|
public DisplayImageConfigurationItem(string name)
|
|
|
|
: base(name, itemType: "displayimage", canBeSavedToFile: false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public JObject ToJson()
|
|
|
|
{
|
|
|
|
var jObject = CreateJObject();
|
|
|
|
|
|
|
|
var dataUri = DataUrlUtils.BytesToDataUrl(Value, "image/jpeg");
|
|
|
|
jObject["value"] = dataUri;
|
|
|
|
|
|
|
|
return jObject;
|
|
|
|
}
|
2020-04-21 06:45:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public class SingleSelectConfigurationItem : ConfigurationItem
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
public string Value { get; set; }
|
|
|
|
|
|
|
|
public Dictionary<string, string> Options { get; }
|
|
|
|
|
|
|
|
public SingleSelectConfigurationItem(string name, Dictionary<string, string> options)
|
|
|
|
: base(name, itemType: "inputselect") => Options = options;
|
|
|
|
|
|
|
|
public JObject ToJson()
|
|
|
|
{
|
|
|
|
var jObject = CreateJObject();
|
|
|
|
|
|
|
|
jObject["value"] = Value;
|
|
|
|
jObject["options"] = new JObject();
|
|
|
|
foreach (var option in Options)
|
|
|
|
{
|
|
|
|
jObject["options"][option.Key] = option.Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return jObject;
|
|
|
|
}
|
2020-04-21 06:45:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public class MultiSelectConfigurationItem : ConfigurationItem
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
|
|
|
public string[] Values { get; set; }
|
2020-02-19 20:23:55 +00:00
|
|
|
|
|
|
|
public Dictionary<string, string> Options { get; }
|
2020-04-21 06:45:21 +00:00
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public MultiSelectConfigurationItem(string name, Dictionary<string, string> options)
|
|
|
|
: base(name, itemType: "inputcheckbox") => Options = options;
|
|
|
|
|
|
|
|
public JObject ToJson()
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
var jObject = CreateJObject();
|
|
|
|
|
|
|
|
jObject["values"] = new JArray(Values);
|
|
|
|
jObject["options"] = new JObject();
|
|
|
|
foreach (var option in Options)
|
|
|
|
{
|
|
|
|
jObject["options"][option.Key] = option.Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return jObject;
|
2020-04-21 06:45:21 +00:00
|
|
|
}
|
2020-02-19 20:23:55 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public class PasswordConfigurationItem : ConfigurationItem
|
2017-05-28 16:12:41 +00:00
|
|
|
{
|
|
|
|
public string Value { get; set; }
|
2020-04-21 06:45:21 +00:00
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public PasswordConfigurationItem(string name)
|
|
|
|
: base(name, itemType: "password")
|
|
|
|
{
|
|
|
|
}
|
2020-04-21 06:45:21 +00:00
|
|
|
|
2021-03-16 23:29:26 +00:00
|
|
|
public JObject ToJson(bool forDisplay, IProtectionService protectionService = null)
|
2020-04-21 06:45:21 +00:00
|
|
|
{
|
2021-03-16 23:29:26 +00:00
|
|
|
var jObject = CreateJObject();
|
|
|
|
|
|
|
|
var password = Value;
|
|
|
|
if (string.IsNullOrEmpty(password))
|
|
|
|
password = string.Empty;
|
|
|
|
else if (forDisplay)
|
|
|
|
password = PASSWORD_REPLACEMENT;
|
|
|
|
else if (protectionService != null)
|
|
|
|
password = protectionService.Protect(password);
|
|
|
|
jObject["value"] = password;
|
|
|
|
|
|
|
|
return jObject;
|
2020-04-21 06:45:21 +00:00
|
|
|
}
|
2017-05-28 16:12:41 +00:00
|
|
|
}
|
2015-04-13 06:25:21 +00:00
|
|
|
}
|
|
|
|
}
|