mirror of https://github.com/Jackett/Jackett
Web UI improvements, delete indexer support, fixed api key
This commit is contained in:
parent
6d31fae4cf
commit
de111c4202
|
@ -9,6 +9,9 @@ namespace Jackett
|
||||||
{
|
{
|
||||||
public class ApiKey
|
public class ApiKey
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public static string CurrentKey;
|
||||||
|
|
||||||
const string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
const string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
public static string Generate()
|
public static string Generate()
|
||||||
|
|
|
@ -11,15 +11,18 @@ namespace Jackett
|
||||||
public class IndexerManager
|
public class IndexerManager
|
||||||
{
|
{
|
||||||
|
|
||||||
static string AppConfigDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Jackett");
|
static string IndexerConfigDirectory = Path.Combine(Program.AppConfigDirectory, "Indexers");
|
||||||
static string IndexerConfigDirectory = Path.Combine(AppConfigDirectory, "Indexers");
|
|
||||||
|
|
||||||
public Dictionary<string, IndexerInterface> Indexers { get; private set; }
|
public Dictionary<string, IndexerInterface> Indexers { get; private set; }
|
||||||
|
|
||||||
public IndexerManager()
|
public IndexerManager()
|
||||||
{
|
{
|
||||||
Indexers = new Dictionary<string, IndexerInterface>();
|
Indexers = new Dictionary<string, IndexerInterface>();
|
||||||
|
LoadMissingIndexers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadMissingIndexers()
|
||||||
|
{
|
||||||
var implementedIndexerTypes = AppDomain.CurrentDomain.GetAssemblies()
|
var implementedIndexerTypes = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
.SelectMany(s => s.GetTypes())
|
.SelectMany(s => s.GetTypes())
|
||||||
.Where(p => typeof(IndexerInterface).IsAssignableFrom(p) && !p.IsInterface)
|
.Where(p => typeof(IndexerInterface).IsAssignableFrom(p) && !p.IsInterface)
|
||||||
|
@ -31,10 +34,13 @@ namespace Jackett
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexerInterface LoadIndexer(Type indexerType)
|
void LoadIndexer(Type indexerType)
|
||||||
{
|
{
|
||||||
var name = indexerType.Name.Trim().ToLower();
|
var name = indexerType.Name.Trim().ToLower();
|
||||||
|
|
||||||
|
if (Indexers.ContainsKey(name))
|
||||||
|
return;
|
||||||
|
|
||||||
IndexerInterface newIndexer = (IndexerInterface)Activator.CreateInstance(indexerType);
|
IndexerInterface newIndexer = (IndexerInterface)Activator.CreateInstance(indexerType);
|
||||||
newIndexer.OnSaveConfigurationRequested += newIndexer_OnSaveConfigurationRequested;
|
newIndexer.OnSaveConfigurationRequested += newIndexer_OnSaveConfigurationRequested;
|
||||||
|
|
||||||
|
@ -46,7 +52,6 @@ namespace Jackett
|
||||||
}
|
}
|
||||||
|
|
||||||
Indexers.Add(name, newIndexer);
|
Indexers.Add(name, newIndexer);
|
||||||
return newIndexer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetIndexerConfigFilePath(IndexerInterface indexer)
|
string GetIndexerConfigFilePath(IndexerInterface indexer)
|
||||||
|
@ -71,5 +76,14 @@ namespace Jackett
|
||||||
return indexer;
|
return indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeleteIndexer(string name)
|
||||||
|
{
|
||||||
|
var indexer = GetIndexer(name);
|
||||||
|
var configPath = GetIndexerConfigFilePath(indexer);
|
||||||
|
File.Delete(configPath);
|
||||||
|
Indexers.Remove(name);
|
||||||
|
LoadMissingIndexers();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,9 @@
|
||||||
<Content Include="WebContent\congruent_outline.png">
|
<Content Include="WebContent\congruent_outline.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="WebContent\crissXcross.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="WebContent\handlebars-v3.0.1.js">
|
<Content Include="WebContent\handlebars-v3.0.1.js">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -9,13 +10,12 @@ namespace Jackett
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
public static ManualResetEvent ExitEvent = new ManualResetEvent(false);
|
public static string AppConfigDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Jackett");
|
||||||
|
|
||||||
static IndexerManager indexerManager;
|
public static ManualResetEvent ExitEvent = new ManualResetEvent(false);
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
indexerManager = new IndexerManager();
|
|
||||||
|
|
||||||
var resultPage = new ResultPage(new ChannelInfo
|
var resultPage = new ResultPage(new ChannelInfo
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,8 @@ namespace Jackett
|
||||||
|
|
||||||
public Server()
|
public Server()
|
||||||
{
|
{
|
||||||
|
LoadApiKey();
|
||||||
|
|
||||||
indexerManager = new IndexerManager();
|
indexerManager = new IndexerManager();
|
||||||
webApi = new WebApi(indexerManager);
|
webApi = new WebApi(indexerManager);
|
||||||
|
|
||||||
|
@ -25,6 +27,18 @@ namespace Jackett
|
||||||
listener.Prefixes.Add("http://*:9117/");
|
listener.Prefixes.Add("http://*:9117/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadApiKey()
|
||||||
|
{
|
||||||
|
var apiKeyFile = Path.Combine(Program.AppConfigDirectory, "api_key.txt");
|
||||||
|
if (File.Exists(apiKeyFile))
|
||||||
|
ApiKey.CurrentKey = File.ReadAllText(apiKeyFile).Trim();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ApiKey.CurrentKey = ApiKey.Generate();
|
||||||
|
File.WriteAllText(apiKeyFile, ApiKey.CurrentKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async void Start()
|
public async void Start()
|
||||||
{
|
{
|
||||||
listener.Start();
|
listener.Start();
|
||||||
|
|
|
@ -21,14 +21,16 @@ namespace Jackett
|
||||||
GetConfigForm,
|
GetConfigForm,
|
||||||
ConfigureIndexer,
|
ConfigureIndexer,
|
||||||
GetIndexers,
|
GetIndexers,
|
||||||
TestIndexer
|
TestIndexer,
|
||||||
|
DeleteIndexer
|
||||||
}
|
}
|
||||||
static Dictionary<string, WebApiMethod> WebApiMethods = new Dictionary<string, WebApiMethod>
|
static Dictionary<string, WebApiMethod> WebApiMethods = new Dictionary<string, WebApiMethod>
|
||||||
{
|
{
|
||||||
{ "get_config_form", WebApiMethod.GetConfigForm },
|
{ "get_config_form", WebApiMethod.GetConfigForm },
|
||||||
{ "configure_indexer", WebApiMethod.ConfigureIndexer },
|
{ "configure_indexer", WebApiMethod.ConfigureIndexer },
|
||||||
{ "get_indexers", WebApiMethod.GetIndexers },
|
{ "get_indexers", WebApiMethod.GetIndexers },
|
||||||
{ "test_indexer", WebApiMethod.TestIndexer}
|
{ "test_indexer", WebApiMethod.TestIndexer },
|
||||||
|
{ "delete_indexer", WebApiMethod.DeleteIndexer }
|
||||||
};
|
};
|
||||||
|
|
||||||
IndexerManager indexerManager;
|
IndexerManager indexerManager;
|
||||||
|
@ -80,102 +82,39 @@ namespace Jackett
|
||||||
return JObject.Parse(postData);
|
return JObject.Parse(postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delegate Task<JToken> HandlerTask(HttpListenerContext context);
|
||||||
|
|
||||||
async void ProcessWebApiRequest(HttpListenerContext context, WebApiMethod method)
|
async void ProcessWebApiRequest(HttpListenerContext context, WebApiMethod method)
|
||||||
{
|
{
|
||||||
var query = HttpUtility.ParseQueryString(context.Request.Url.Query);
|
var query = HttpUtility.ParseQueryString(context.Request.Url.Query);
|
||||||
|
|
||||||
JToken jsonReply = new JObject();
|
|
||||||
|
|
||||||
context.Response.ContentType = "text/json";
|
context.Response.ContentType = "text/json";
|
||||||
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
||||||
|
|
||||||
|
HandlerTask handlerTask;
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
case WebApiMethod.GetConfigForm:
|
case WebApiMethod.GetConfigForm:
|
||||||
try
|
handlerTask = HandleConfigForm;
|
||||||
{
|
|
||||||
var postData = await ReadPostDataJson(context.Request.InputStream);
|
|
||||||
string indexerString = (string)postData["indexer"];
|
|
||||||
var indexer = indexerManager.GetIndexer(indexerString);
|
|
||||||
var config = await indexer.GetConfigurationForSetup();
|
|
||||||
jsonReply["config"] = config.ToJson();
|
|
||||||
jsonReply["name"] = indexer.DisplayName;
|
|
||||||
jsonReply["result"] = "success";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
jsonReply["result"] = "error";
|
|
||||||
jsonReply["error"] = ex.Message;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WebApiMethod.ConfigureIndexer:
|
case WebApiMethod.ConfigureIndexer:
|
||||||
try
|
handlerTask = HandleConfigureIndexer;
|
||||||
{
|
|
||||||
var postData = await ReadPostDataJson(context.Request.InputStream);
|
|
||||||
string indexerString = (string)postData["indexer"];
|
|
||||||
var indexer = indexerManager.GetIndexer(indexerString);
|
|
||||||
jsonReply["name"] = indexer.DisplayName;
|
|
||||||
await indexer.ApplyConfiguration(postData["config"]);
|
|
||||||
await indexer.VerifyConnection();
|
|
||||||
jsonReply["result"] = "success";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
jsonReply["result"] = "error";
|
|
||||||
jsonReply["error"] = ex.Message;
|
|
||||||
if (ex is ExceptionWithConfigData)
|
|
||||||
{
|
|
||||||
jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WebApiMethod.GetIndexers:
|
case WebApiMethod.GetIndexers:
|
||||||
try
|
handlerTask = HandleGetIndexers;
|
||||||
{
|
|
||||||
jsonReply["result"] = "success";
|
|
||||||
jsonReply["api_key"] = ApiKey.Generate();
|
|
||||||
JArray items = new JArray();
|
|
||||||
foreach (var i in indexerManager.Indexers)
|
|
||||||
{
|
|
||||||
var indexer = i.Value;
|
|
||||||
var item = new JObject();
|
|
||||||
item["id"] = i.Key;
|
|
||||||
item["name"] = indexer.DisplayName;
|
|
||||||
item["description"] = indexer.DisplayDescription;
|
|
||||||
item["configured"] = indexer.IsConfigured;
|
|
||||||
item["site_link"] = indexer.SiteLink;
|
|
||||||
items.Add(item);
|
|
||||||
}
|
|
||||||
jsonReply["items"] = items;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
jsonReply["result"] = "error";
|
|
||||||
jsonReply["error"] = ex.Message;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WebApiMethod.TestIndexer:
|
case WebApiMethod.TestIndexer:
|
||||||
try
|
handlerTask = HandleTestIndexer;
|
||||||
{
|
break;
|
||||||
var postData = await ReadPostDataJson(context.Request.InputStream);
|
case WebApiMethod.DeleteIndexer:
|
||||||
string indexerString = (string)postData["indexer"];
|
handlerTask = HandleDeleteIndexer;
|
||||||
var indexer = indexerManager.GetIndexer(indexerString);
|
|
||||||
jsonReply["name"] = indexer.DisplayName;
|
|
||||||
await indexer.VerifyConnection();
|
|
||||||
jsonReply["result"] = "success";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
jsonReply["result"] = "error";
|
|
||||||
jsonReply["error"] = ex.Message;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
jsonReply["result"] = "error";
|
handlerTask = HandleInvalidApiMethod;
|
||||||
jsonReply["error"] = "Invalid API method";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
JToken jsonReply = await handlerTask(context);
|
||||||
ReplyWithJson(context, jsonReply);
|
ReplyWithJson(context, jsonReply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,5 +125,131 @@ namespace Jackett
|
||||||
context.Response.OutputStream.Close();
|
context.Response.OutputStream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task<JToken> HandleInvalidApiMethod(HttpListenerContext context)
|
||||||
|
{
|
||||||
|
return Task<JToken>.Run(() =>
|
||||||
|
{
|
||||||
|
JToken jsonReply = new JObject();
|
||||||
|
jsonReply["result"] = "error";
|
||||||
|
jsonReply["error"] = "Invalid API method";
|
||||||
|
return jsonReply;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<JToken> HandleConfigForm(HttpListenerContext context)
|
||||||
|
{
|
||||||
|
JToken jsonReply = new JObject();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var postData = await ReadPostDataJson(context.Request.InputStream);
|
||||||
|
string indexerString = (string)postData["indexer"];
|
||||||
|
var indexer = indexerManager.GetIndexer(indexerString);
|
||||||
|
var config = await indexer.GetConfigurationForSetup();
|
||||||
|
jsonReply["config"] = config.ToJson();
|
||||||
|
jsonReply["name"] = indexer.DisplayName;
|
||||||
|
jsonReply["result"] = "success";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
jsonReply["result"] = "error";
|
||||||
|
jsonReply["error"] = ex.Message;
|
||||||
|
}
|
||||||
|
return jsonReply;
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<JToken> HandleConfigureIndexer(HttpListenerContext context)
|
||||||
|
{
|
||||||
|
JToken jsonReply = new JObject();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var postData = await ReadPostDataJson(context.Request.InputStream);
|
||||||
|
string indexerString = (string)postData["indexer"];
|
||||||
|
var indexer = indexerManager.GetIndexer(indexerString);
|
||||||
|
jsonReply["name"] = indexer.DisplayName;
|
||||||
|
await indexer.ApplyConfiguration(postData["config"]);
|
||||||
|
await indexer.VerifyConnection();
|
||||||
|
jsonReply["result"] = "success";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
jsonReply["result"] = "error";
|
||||||
|
jsonReply["error"] = ex.Message;
|
||||||
|
if (ex is ExceptionWithConfigData)
|
||||||
|
{
|
||||||
|
jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonReply;
|
||||||
|
}
|
||||||
|
|
||||||
|
Task<JToken> HandleGetIndexers(HttpListenerContext context)
|
||||||
|
{
|
||||||
|
return Task<JToken>.Run(() =>
|
||||||
|
{
|
||||||
|
JToken jsonReply = new JObject();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
jsonReply["result"] = "success";
|
||||||
|
jsonReply["api_key"] = ApiKey.CurrentKey;
|
||||||
|
JArray items = new JArray();
|
||||||
|
foreach (var i in indexerManager.Indexers)
|
||||||
|
{
|
||||||
|
var indexer = i.Value;
|
||||||
|
var item = new JObject();
|
||||||
|
item["id"] = i.Key;
|
||||||
|
item["name"] = indexer.DisplayName;
|
||||||
|
item["description"] = indexer.DisplayDescription;
|
||||||
|
item["configured"] = indexer.IsConfigured;
|
||||||
|
item["site_link"] = indexer.SiteLink;
|
||||||
|
items.Add(item);
|
||||||
|
}
|
||||||
|
jsonReply["items"] = items;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
jsonReply["result"] = "error";
|
||||||
|
jsonReply["error"] = ex.Message;
|
||||||
|
}
|
||||||
|
return jsonReply;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<JToken> HandleTestIndexer(HttpListenerContext context)
|
||||||
|
{
|
||||||
|
JToken jsonReply = new JObject();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var postData = await ReadPostDataJson(context.Request.InputStream);
|
||||||
|
string indexerString = (string)postData["indexer"];
|
||||||
|
var indexer = indexerManager.GetIndexer(indexerString);
|
||||||
|
jsonReply["name"] = indexer.DisplayName;
|
||||||
|
await indexer.VerifyConnection();
|
||||||
|
jsonReply["result"] = "success";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
jsonReply["result"] = "error";
|
||||||
|
jsonReply["error"] = ex.Message;
|
||||||
|
}
|
||||||
|
return jsonReply;
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<JToken> HandleDeleteIndexer(HttpListenerContext context)
|
||||||
|
{
|
||||||
|
JToken jsonReply = new JObject();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var postData = await ReadPostDataJson(context.Request.InputStream);
|
||||||
|
string indexerString = (string)postData["indexer"];
|
||||||
|
indexerManager.DeleteIndexer(indexerString);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
jsonReply["result"] = "error";
|
||||||
|
jsonReply["error"] = ex.Message;
|
||||||
|
}
|
||||||
|
return jsonReply;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
|
@ -13,7 +13,7 @@
|
||||||
<title>Jackett</title>
|
<title>Jackett</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background-image: url("congruent_outline.png");
|
background-image: url("crissXcross.png");
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,6 @@
|
||||||
|
|
||||||
.indexer-add-content > .glyphicon {
|
.indexer-add-content > .glyphicon {
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
margin-top: 40%;
|
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,12 +176,12 @@
|
||||||
<h3>Configured Indexers</h3>
|
<h3>Configured Indexers</h3>
|
||||||
<div id="indexers">
|
<div id="indexers">
|
||||||
|
|
||||||
<a class="indexer card" id="add-indexer" href="#" data-toggle="modal" data-target="#select-indexer-modal">
|
<button class="indexer card" id="add-indexer" data-toggle="modal" data-target="#select-indexer-modal">
|
||||||
<div class="indexer-add-content">
|
<div class="indexer-add-content">
|
||||||
<span class="glyphicon glyphicon glyphicon-plus" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||||
<div class="light-text">Add</div>
|
<div class="light-text">Add</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -230,10 +229,18 @@
|
||||||
<div class="indexer-logo"><img src="logos/{{id}}.png" /></div>
|
<div class="indexer-logo"><img src="logos/{{id}}.png" /></div>
|
||||||
<div class="indexer-name"><h3>{{name}}</h3></div>
|
<div class="indexer-name"><h3>{{name}}</h3></div>
|
||||||
<div class="indexer-buttons">
|
<div class="indexer-buttons">
|
||||||
<a class="btn btn-info btn-sm" target="_blank" href="{{site_link}}">Visit <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a>
|
<a class="btn btn-info btn-sm" target="_blank" href="{{site_link}}">
|
||||||
<a class="btn btn-warning btn-sm indexer-button-test" href="#" data-id="{{id}}">Test <span class="glyphicon glyphicon-screenshot" aria-hidden="true"></span></a>
|
Visit <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
|
||||||
<a class="btn btn-danger btn-sm" href="#">Delete <span class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
|
</a>
|
||||||
<a class="btn btn-primary btn-sm" href="#">Configure <span class="glyphicon glyphicon-wrench" aria-hidden="true"></span></a>
|
<button class="btn btn-warning btn-sm indexer-button-test" data-id="{{id}}">
|
||||||
|
Test <span class="glyphicon glyphicon-screenshot" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger btn-sm indexer-button-delete" data-id="{{id}}">
|
||||||
|
Delete <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-primary btn-sm" data-id="{{id}}">
|
||||||
|
Configure <span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="indexer-host">
|
<div class="indexer-host">
|
||||||
<b>Torznab Host:</b>
|
<b>Torznab Host:</b>
|
||||||
|
@ -300,6 +307,28 @@
|
||||||
$('#indexers').fadeIn();
|
$('#indexers').fadeIn();
|
||||||
prepareSetupButtons();
|
prepareSetupButtons();
|
||||||
prepareTestButtons();
|
prepareTestButtons();
|
||||||
|
prepareDeleteButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareDeleteButtons() {
|
||||||
|
$(".indexer-button-delete").each(function (i, btn) {
|
||||||
|
var $btn = $(btn);
|
||||||
|
var id = $btn.data("id");
|
||||||
|
$btn.click(function () {
|
||||||
|
var jqxhr = $.post("delete_indexer", JSON.stringify({ indexer: id }), function (data) {
|
||||||
|
if (data.result == "error") {
|
||||||
|
doNotify("Delete error for " + id + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
doNotify("Deleted " + id, "success", "glyphicon glyphicon-ok");
|
||||||
|
}
|
||||||
|
}).fail(function () {
|
||||||
|
doNotify("Error deleting indexer, request to Jackett server error", "danger", "glyphicon glyphicon-alert");
|
||||||
|
}).always(function () {
|
||||||
|
reloadIndexers();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareSetupButtons() {
|
function prepareSetupButtons() {
|
||||||
|
|
Loading…
Reference in New Issue