Added a "select" input type and "default" value for settings. (#1423)

* Added a selectbox and updated nyaasi to include two.

* Added a "default" field for settings.
This commit is contained in:
Mike 2017-05-28 18:12:41 +02:00 committed by kaso17
parent 31ce2ca545
commit a3c443e69b
10 changed files with 131 additions and 14 deletions

View File

@ -62,6 +62,10 @@ body {
height: 20px; height: 20px;
} }
.setup-item-inputselect {
max-width: 255px;
}
[data-type=hiddendata]{ [data-type=hiddendata]{
display: none; display: none;
} }

View File

@ -527,6 +527,9 @@ function getConfigModalJson(configForm) {
case "inputbool": case "inputbool":
itemEntry.value = $el.find(".setup-item-inputbool input").is(":checked"); itemEntry.value = $el.find(".setup-item-inputbool input").is(":checked");
break; break;
case "inputselect":
itemEntry.value = $el.find(".setup-item-inputselect select").val();
break;
case "recaptcha": case "recaptcha":
if (window.jackettIsLocal) { if (window.jackettIsLocal) {
var version = $el.find('.jackettrecaptcha').data("version"); var version = $el.find('.jackettrecaptcha').data("version");

View File

@ -62,6 +62,10 @@ body {
height: 20px; height: 20px;
} }
.setup-item-inputselect {
max-width: 255px;
}
[data-type=hiddendata]{ [data-type=hiddendata]{
display: none; display: none;
} }

View File

@ -26,6 +26,7 @@
<script src="../libs/handlebars.min.js"></script> <script src="../libs/handlebars.min.js"></script>
<script src="../libs/moment.min.js"></script> <script src="../libs/moment.min.js"></script>
<script src="../libs/handlebarsmoment.js"></script> <script src="../libs/handlebarsmoment.js"></script>
<script src="../libs/handlebarsextend.js"></script>
<script src="../bootstrap/bootstrap.min.js"></script> <script src="../bootstrap/bootstrap.min.js"></script>
<script src="../libs/bootstrap-notify.js"></script> <script src="../libs/bootstrap-notify.js"></script>
<script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script> <script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>
@ -178,6 +179,19 @@
{{/if}} {{/if}}
</div> </div>
</script> </script>
<script id="setup-item-inputselect" type="text/x-handlebars-template">
<div class="setup-item-inputselect">
<select class="form-control" data-id="{{id}}">
{{#each options}}
{{#ifCond ../value @key}}
<option value="{{@key}}" selected>{{this}}</option>
{{else}}
<option value="{{@key}}">{{this}}</option>
{{/ifCond}}
{{/each}}
</select>
</div>
</script>
<script id="setup-item-recaptcha" type="text/x-handlebars-template"> <script id="setup-item-recaptcha" type="text/x-handlebars-template">
<div class="jackettrecaptcha"> <div class="jackettrecaptcha">
</div> </div>

View File

@ -0,0 +1,6 @@
Handlebars.registerHelper('ifCond', function (v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});

View File

@ -40,6 +40,9 @@
case "inputbool": case "inputbool":
data.config[id] = $valEl.val(); data.config[id] = $valEl.val();
break; break;
case "inputselect":
data.config[id] = $valEl.val();
break;
} }
}); });

View File

@ -7,7 +7,36 @@
links: links:
- https://nyaa.si - https://nyaa.si
settings: [] settings:
- name: filter-id
type: select
label: Filter
default: "0"
options:
0: No filter
1: No remakes
2: Trusted only
- name: cat-id
type: select
label: Category
default: "0_0"
options:
0_0: "All categories"
1_0: "Anime"
1_1: "- Anime Music Video"
1_2: "- English-translated"
1_3: "- Non-English-translated"
1_4: "- Raw"
2_0: "Audio"
2_1: "- Lossless"
2_2: "- Lossy"
3_0: "Literature"
3_1: "- English-translated"
3_2: "- Non-English-translated"
3_3: "- Lossy"
6_0: "Software"
6_1: "- Applications"
6_2: "- Games"
caps: caps:
categorymappings: categorymappings:
@ -30,16 +59,16 @@
- {id: 6_0, cat: PC, desc: "Software"} - {id: 6_0, cat: PC, desc: "Software"}
- {id: 6_1, cat: PC/ISO, desc: "Applications"} - {id: 6_1, cat: PC/ISO, desc: "Applications"}
- {id: 6_2, cat: PC/Games, desc: "Games"} - {id: 6_2, cat: PC/Games, desc: "Games"}
modes: modes:
search: [q] search: [q]
tv-search: [q] tv-search: [q]
search: search:
path: / path: /
inputs: inputs:
q: "{{ .Query.Keywords}}" q: "{{ .Query.Keywords}}"
f: "{{ .Config.filter-id }}"
c: "{{ .Config.cat-id }}"
rows: rows:
selector: tr.default,tr.danger,tr.success selector: tr.default,tr.danger,tr.success
fields: fields:

View File

@ -113,6 +113,8 @@ namespace Jackett.Indexers
public string Name { get; set; } public string Name { get; set; }
public string Type { get; set; } public string Type { get; set; }
public string Label { get; set; } public string Label { get; set; }
public string Default { get; set; }
public Dictionary<string, string> Options { get; set; }
} }
public class CategorymappingBlock public class CategorymappingBlock
@ -302,18 +304,40 @@ namespace Jackett.Indexers
foreach (var Setting in Definition.Settings) foreach (var Setting in Definition.Settings)
{ {
Item item; Item item;
if (Setting.Type != null && Setting.Type == "checkbox")
if (Setting.Type != null)
{ {
item = new BoolItem() { Value = false }; switch (Setting.Type)
} {
else if(Setting.Type != null && Setting.Type == "password") case "checkbox":
{ item = new BoolItem {Value = false};
item = new StringItem();
if (Setting.Default != null && Setting.Default == "true")
{
((BoolItem) item).Value = true;
}
break;
case "password":
case "text":
item = new StringItem { Value = Setting.Default };
break;
case "select":
if (Setting.Options == null)
{
throw new Exception("Options must be given for the 'select' type.");
}
item = new SelectItem(Setting.Options) { Value = Setting.Default };
break;
default:
throw new Exception($"Invalid setting type '{Setting.Type}' specified.");
}
} }
else else
{ {
item = new StringItem(); item = new StringItem { Value = Setting.Default }; ;
} }
item.Name = Setting.Label; item.Name = Setting.Label;
configData.AddDynamic(Setting.Name, item); configData.AddDynamic(Setting.Name, item);
} }
@ -377,6 +401,10 @@ namespace Jackett.Indexers
{ {
value = (((BoolItem)item).Value == true ? "true" : ""); value = (((BoolItem)item).Value == true ? "true" : "");
} }
else if (item.GetType() == typeof(SelectItem))
{
value = ((SelectItem)item).Value;
}
else else
{ {
value = ((StringItem)item).Value; value = ((StringItem)item).Value;

View File

@ -419,6 +419,9 @@
<None Include="Resources\test.xml" /> <None Include="Resources\test.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Content\libs\handlebarsextend.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Definitions\**\*.yml"> <Content Include="Definitions\**\*.yml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>

View File

@ -4,9 +4,6 @@ using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Jackett.Models.IndexerConfig namespace Jackett.Models.IndexerConfig
{ {
@ -19,6 +16,7 @@ namespace Jackett.Models.IndexerConfig
{ {
InputString, InputString,
InputBool, InputBool,
InputSelect,
DisplayImage, DisplayImage,
DisplayInfo, DisplayInfo,
HiddenData, HiddenData,
@ -85,6 +83,9 @@ namespace Jackett.Models.IndexerConfig
case ItemType.InputBool: case ItemType.InputBool:
((BoolItem)item).Value = arrItem.Value<bool>("value"); ((BoolItem)item).Value = arrItem.Value<bool>("value");
break; break;
case ItemType.InputSelect:
((SelectItem)item).Value = arrItem.Value<string>("value");
break;
case ItemType.Recaptcha: case ItemType.Recaptcha:
((RecaptchaItem)item).Value = arrItem.Value<string>("value"); ((RecaptchaItem)item).Value = arrItem.Value<string>("value");
((RecaptchaItem)item).Cookie = arrItem.Value<string>("cookie"); ((RecaptchaItem)item).Cookie = arrItem.Value<string>("cookie");
@ -129,6 +130,15 @@ namespace Jackett.Models.IndexerConfig
case ItemType.InputBool: case ItemType.InputBool:
jObject["value"] = ((BoolItem)item).Value; jObject["value"] = ((BoolItem)item).Value;
break; break;
case ItemType.InputSelect:
jObject["value"] = ((SelectItem)item).Value;
jObject["options"] = new JObject();
foreach (var option in ((SelectItem)item).Options)
{
jObject["options"][option.Key] = option.Value;
}
break;
case ItemType.DisplayImage: case ItemType.DisplayImage:
string dataUri = DataUrlUtils.BytesToDataUrl(((ImageItem)item).Value, "image/jpeg"); string dataUri = DataUrlUtils.BytesToDataUrl(((ImageItem)item).Value, "image/jpeg");
jObject["value"] = dataUri; jObject["value"] = dataUri;
@ -156,7 +166,7 @@ namespace Jackett.Models.IndexerConfig
if (!forDisplay) if (!forDisplay)
{ {
properties = properties properties = properties
.Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString || p.ItemType == ItemType.Recaptcha || p.ItemType == ItemType.DisplayInfo) .Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString || p.ItemType == ItemType.InputSelect || p.ItemType == ItemType.Recaptcha || p.ItemType == ItemType.DisplayInfo)
.ToList(); .ToList();
} }
@ -245,6 +255,19 @@ namespace Jackett.Models.IndexerConfig
} }
} }
public class SelectItem : Item
{
public string Value { get; set; }
public Dictionary<string, string> Options { get; }
public SelectItem(Dictionary<string, string> options)
{
ItemType = ItemType.InputSelect;
Options = options;
}
}
//public abstract Item[] GetItems(); //public abstract Item[] GetItems();
} }
} }