diff --git a/src/Jackett/ApiKey.cs b/src/Jackett/ApiKey.cs new file mode 100644 index 000000000..9cd8419d9 --- /dev/null +++ b/src/Jackett/ApiKey.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace Jackett +{ + public class ApiKey + { + const string chars = "abcdefghijklmnopqrstuvwxyz0123456789"; + + public static string Generate() + { + var randBytes = new byte[32]; + var rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(randBytes); + var key = ""; + foreach (var b in randBytes) + { + key += chars[b % chars.Length]; + } + return key; + + } + } +} diff --git a/src/Jackett/Indexers/BitMeTV.cs b/src/Jackett/Indexers/BitMeTV.cs index 243307c4f..611eab408 100644 --- a/src/Jackett/Indexers/BitMeTV.cs +++ b/src/Jackett/Indexers/BitMeTV.cs @@ -58,7 +58,7 @@ namespace Jackett client = new HttpClient(handler); } - public string DisplayName { get { return "BitMeTV.org"; } } + public string DisplayName { get { return "BitMeTV"; } } public string DisplayDescription { get { return "TV Episode specialty tracker"; } } public Uri SiteLink { get { return new Uri("https://bitmetv.org"); } } @@ -102,6 +102,7 @@ namespace Jackett var errorMessage = messageEl.Text(); var captchaImage = await client.GetByteArrayAsync(CaptchaUrl); config.CaptchaImage.Value = captchaImage; + config.CaptchaText.Value = ""; throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config); } else @@ -114,6 +115,8 @@ namespace Jackett if (OnSaveConfigurationRequested != null) OnSaveConfigurationRequested(configSaveData); + + IsConfigured = true; } }); } @@ -123,6 +126,8 @@ namespace Jackett return Task.Run(async () => { var result = await client.GetStringAsync(new Uri(SearchUrl)); + if (result.Contains("

Not logged in!

")) + throw new Exception("Detected as not logged in"); }); } diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 83c86cc5d..366507780 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -67,6 +67,7 @@ + @@ -91,7 +92,7 @@ - + PreserveNewest @@ -105,15 +106,15 @@ + + PreserveNewest + PreserveNewest PreserveNewest - - PreserveNewest - PreserveNewest @@ -129,6 +130,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/src/Jackett/WebApi.cs b/src/Jackett/WebApi.cs index 3ff1bb8a8..85a71b59a 100644 --- a/src/Jackett/WebApi.cs +++ b/src/Jackett/WebApi.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Web; @@ -19,13 +20,15 @@ namespace Jackett { GetConfigForm, ConfigureIndexer, - GetIndexers + GetIndexers, + TestIndexer } static Dictionary WebApiMethods = new Dictionary { { "get_config_form", WebApiMethod.GetConfigForm }, { "configure_indexer", WebApiMethod.ConfigureIndexer }, - { "get_indexers", WebApiMethod.GetIndexers } + { "get_indexers", WebApiMethod.GetIndexers }, + { "test_indexer", WebApiMethod.TestIndexer} }; IndexerManager indexerManager; @@ -63,8 +66,12 @@ namespace Jackett var contentFile = File.ReadAllBytes(Path.Combine(WebContentFolder, file)); context.Response.ContentType = MimeMapping.GetMimeMapping(file); context.Response.StatusCode = (int)HttpStatusCode.OK; - await context.Response.OutputStream.WriteAsync(contentFile, 0, contentFile.Length); - context.Response.OutputStream.Close(); + try + { + await context.Response.OutputStream.WriteAsync(contentFile, 0, contentFile.Length); + context.Response.OutputStream.Close(); + } + catch (HttpListenerException) { } } async Task ReadPostDataJson(Stream stream) @@ -92,6 +99,7 @@ namespace Jackett var indexer = indexerManager.GetIndexer(indexerString); var config = await indexer.GetConfigurationForSetup(); jsonReply["config"] = config.ToJson(); + jsonReply["name"] = indexer.DisplayName; jsonReply["result"] = "success"; } catch (Exception ex) @@ -106,6 +114,7 @@ namespace Jackett 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"; @@ -124,15 +133,16 @@ namespace Jackett try { 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["display_name"] = indexer.DisplayName; - item["display_description"] = indexer.DisplayDescription; - item["is_configured"] = indexer.IsConfigured; + item["name"] = indexer.DisplayName; + item["description"] = indexer.DisplayDescription; + item["configured"] = indexer.IsConfigured; item["site_link"] = indexer.SiteLink; items.Add(item); } @@ -144,6 +154,22 @@ namespace Jackett jsonReply["error"] = ex.Message; } break; + case WebApiMethod.TestIndexer: + 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; + } + break; default: jsonReply["result"] = "error"; jsonReply["error"] = "Invalid API method"; diff --git a/src/Jackett/WebContent/congruent_outline.png b/src/Jackett/WebContent/congruent_outline.png new file mode 100644 index 000000000..441ce0ac8 Binary files /dev/null and b/src/Jackett/WebContent/congruent_outline.png differ diff --git a/src/Jackett/WebContent/bootstrap/glyphicons-halflings-regular.woff b/src/Jackett/WebContent/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from src/Jackett/WebContent/bootstrap/glyphicons-halflings-regular.woff rename to src/Jackett/WebContent/fonts/glyphicons-halflings-regular.woff diff --git a/src/Jackett/WebContent/index.html b/src/Jackett/WebContent/index.html index 2e82dd0aa..29a9c1cf6 100644 --- a/src/Jackett/WebContent/index.html +++ b/src/Jackett/WebContent/index.html @@ -9,36 +9,353 @@ Jackett -
-
+
+ +
+ API Key: + + (Same key works for all indexers) +
+
+ +
+ +

Configured Indexers

+ +
-
-
-
{{name}}
-
{{description}}
- -
- {{#if configured}} - Configred - {{else}} - Not configured - {{/if}} + + + +
+ +
+ +

{{name}}

+ +
+ Torznab Host: + +
+
+ +
+ +

{{name}}

+
+ Visit + +
+
+ + +
+
{{name}}
+
{{{value_element}}}
+
+ +

{{name}}

+ +
+ {{#if value}} + + {{else}} + + {{/if}} +
+ + {{{value}}} + +
+ + \ No newline at end of file diff --git a/src/Jackett/WebContent/logos/freshon.png b/src/Jackett/WebContent/logos/freshon.png index 0b0c771dd..5d2bd74e3 100644 Binary files a/src/Jackett/WebContent/logos/freshon.png and b/src/Jackett/WebContent/logos/freshon.png differ