mirror of https://github.com/Jackett/Jackett
commit
64daefb2b6
|
@ -15,5 +15,13 @@ namespace Jackett
|
|||
{
|
||||
ConfigData = data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class CustomException : Exception
|
||||
{
|
||||
public CustomException(string message)
|
||||
: base(message)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,7 @@
|
|||
<Compile Include="ReleaseInfo.cs" />
|
||||
<Compile Include="ResultPage.cs" />
|
||||
<Compile Include="Server.cs" />
|
||||
<Compile Include="ServerUtil.cs" />
|
||||
<Compile Include="SonarApi.cs" />
|
||||
<Compile Include="TorznabQuery.cs" />
|
||||
<Compile Include="TVRage.cs" />
|
||||
|
|
|
@ -120,6 +120,19 @@ namespace Jackett
|
|||
Console.WriteLine("Server thread exit");
|
||||
}
|
||||
|
||||
public static void RestartServer()
|
||||
{
|
||||
|
||||
ServerInstance.Stop();
|
||||
ServerInstance = null;
|
||||
var serverTask = Task.Run(async () =>
|
||||
{
|
||||
ServerInstance = new Server();
|
||||
await ServerInstance.Start();
|
||||
});
|
||||
Task.WaitAll(serverTask);
|
||||
}
|
||||
|
||||
static void MigrateSettingsDirectory()
|
||||
{
|
||||
try
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Windows.Forms;
|
||||
|
@ -30,8 +31,10 @@ namespace Jackett
|
|||
// Allow all SSL.. sucks I know but mono on linux is having problems without it..
|
||||
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
|
||||
|
||||
ReadServerSettingsFile();
|
||||
LoadApiKey();
|
||||
|
||||
|
||||
indexerManager = new IndexerManager();
|
||||
sonarrApi = new SonarrApi();
|
||||
webApi = new WebApi(indexerManager, sonarrApi);
|
||||
|
@ -68,6 +71,7 @@ namespace Jackett
|
|||
}
|
||||
|
||||
listener.Start();
|
||||
webApi.server = this;
|
||||
}
|
||||
catch (HttpListenerException ex)
|
||||
{
|
||||
|
@ -249,5 +253,53 @@ namespace Jackett
|
|||
|
||||
|
||||
|
||||
|
||||
public JObject ReadServerSettingsFile()
|
||||
{
|
||||
var path = ServerConfigFile;
|
||||
JObject jsonReply = new JObject();
|
||||
if (File.Exists(path))
|
||||
{
|
||||
jsonReply = JObject.Parse(File.ReadAllText(path));
|
||||
Port = (int)jsonReply["port"];
|
||||
ListenPublic = (bool)jsonReply["public"];
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonReply["port"] = Port;
|
||||
jsonReply["public"] = ListenPublic;
|
||||
}
|
||||
return jsonReply;
|
||||
}
|
||||
|
||||
public Task<int> ApplyPortConfiguration(JToken json)
|
||||
{
|
||||
JObject jsonObject = (JObject)json;
|
||||
JToken jJackettPort = jsonObject.GetValue("port");
|
||||
int jackettPort;
|
||||
if (!ServerUtil.IsPort(jJackettPort.ToString()))
|
||||
throw new CustomException("The value entered is not a valid port");
|
||||
else
|
||||
jackettPort = int.Parse(jJackettPort.ToString());
|
||||
|
||||
if (jackettPort == Port)
|
||||
throw new CustomException("The current port is the same as the one being used now.");
|
||||
else if (ServerUtil.RestrictedPorts.Contains(jackettPort))
|
||||
throw new CustomException("This port is not allowed due to it not being safe.");
|
||||
SaveSettings(jackettPort);
|
||||
|
||||
return Task.FromResult(jackettPort);
|
||||
}
|
||||
|
||||
private static string ServerConfigFile = Path.Combine(Program.AppConfigDirectory, "config.json");
|
||||
|
||||
private void SaveSettings(int jacketPort)
|
||||
{
|
||||
JObject json = new JObject();
|
||||
json["port"] = jacketPort;
|
||||
json["public"] = ListenPublic;
|
||||
File.WriteAllText(ServerConfigFile, json.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett
|
||||
{
|
||||
public static class ServerUtil
|
||||
{
|
||||
public static int[] RestrictedPorts = new int[] {
|
||||
1, // tcpmux
|
||||
7, // echo
|
||||
9, // discard
|
||||
11, // systat
|
||||
13, // daytime
|
||||
15, // netstat
|
||||
17, // qotd
|
||||
19, // chargen
|
||||
20, // ftp data
|
||||
21, // ftp access
|
||||
22, // ssh
|
||||
23, // telnet
|
||||
25, // smtp
|
||||
37, // time
|
||||
42, // name
|
||||
43, // nicname
|
||||
53, // domain
|
||||
77, // priv-rjs
|
||||
79, // finger
|
||||
87, // ttylink
|
||||
95, // supdup
|
||||
101, // hostriame
|
||||
102, // iso-tsap
|
||||
103, // gppitnp
|
||||
104, // acr-nema
|
||||
109, // pop2
|
||||
110, // pop3
|
||||
111, // sunrpc
|
||||
113, // auth
|
||||
115, // sftp
|
||||
117, // uucp-path
|
||||
119, // nntp
|
||||
123, // NTP
|
||||
135, // loc-srv /epmap
|
||||
139, // netbios
|
||||
143, // imap2
|
||||
179, // BGP
|
||||
389, // ldap
|
||||
465, // smtp+ssl
|
||||
512, // print / exec
|
||||
513, // login
|
||||
514, // shell
|
||||
515, // printer
|
||||
526, // tempo
|
||||
530, // courier
|
||||
531, // chat
|
||||
532, // netnews
|
||||
540, // uucp
|
||||
556, // remotefs
|
||||
563, // nntp+ssl
|
||||
587, // stmp?
|
||||
601, // ??
|
||||
636, // ldap+ssl
|
||||
993, // ldap+ssl
|
||||
995, // pop3+ssl
|
||||
2049, // nfs
|
||||
3659, // apple-sasl / PasswordServer
|
||||
4045, // lockd
|
||||
6000, // X11
|
||||
6665, // Alternate IRC [Apple addition]
|
||||
6666, // Alternate IRC [Apple addition]
|
||||
6667, // Standard IRC [Apple addition]
|
||||
6668, // Alternate IRC [Apple addition]
|
||||
6669, // Alternate IRC [Apple addition]};
|
||||
};
|
||||
public static bool IsPort(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return false;
|
||||
|
||||
Regex numeric = new Regex(@"^[0-9]+$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
if (numeric.IsMatch(value))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Convert.ToInt32(value) < 65536)
|
||||
return true;
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ namespace Jackett
|
|||
{
|
||||
static string WebContentFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WebContent");
|
||||
static string[] StaticFiles = Directory.EnumerateFiles(WebContentFolder, "*", SearchOption.AllDirectories).ToArray();
|
||||
public Server server;
|
||||
|
||||
public enum WebApiMethod
|
||||
{
|
||||
|
@ -26,7 +27,10 @@ namespace Jackett
|
|||
DeleteIndexer,
|
||||
GetSonarrConfig,
|
||||
ApplySonarrConfig,
|
||||
TestSonarr
|
||||
TestSonarr,
|
||||
GetJackettConfig,
|
||||
ApplyJackettConfig,
|
||||
JackettRestart,
|
||||
}
|
||||
|
||||
static Dictionary<string, WebApiMethod> WebApiMethods = new Dictionary<string, WebApiMethod> {
|
||||
|
@ -37,7 +41,10 @@ namespace Jackett
|
|||
{ "delete_indexer", WebApiMethod.DeleteIndexer },
|
||||
{ "get_sonarr_config", WebApiMethod.GetSonarrConfig },
|
||||
{ "apply_sonarr_config", WebApiMethod.ApplySonarrConfig },
|
||||
{ "test_sonarr", WebApiMethod.TestSonarr }
|
||||
{ "test_sonarr", WebApiMethod.TestSonarr },
|
||||
{ "get_jackett_config",WebApiMethod.GetJackettConfig},
|
||||
{ "apply_jackett_config",WebApiMethod.ApplyJackettConfig},
|
||||
{ "jackett_restart", WebApiMethod.JackettRestart },
|
||||
};
|
||||
|
||||
IndexerManager indexerManager;
|
||||
|
@ -127,6 +134,15 @@ namespace Jackett
|
|||
case WebApiMethod.TestSonarr:
|
||||
handlerTask = HandleTestSonarr;
|
||||
break;
|
||||
case WebApiMethod.ApplyJackettConfig:
|
||||
handlerTask = HandleApplyJackettConfig;
|
||||
break;
|
||||
case WebApiMethod.GetJackettConfig:
|
||||
handlerTask = HandleJackettConfig;
|
||||
break;
|
||||
case WebApiMethod.JackettRestart:
|
||||
handlerTask = HandleJackettRestart;
|
||||
break;
|
||||
default:
|
||||
handlerTask = HandleInvalidApiMethod;
|
||||
break;
|
||||
|
@ -318,5 +334,54 @@ namespace Jackett
|
|||
return jsonReply;
|
||||
}
|
||||
|
||||
|
||||
//Jacket port functions
|
||||
Task<JToken> HandleJackettConfig(HttpListenerContext context)
|
||||
{
|
||||
JObject jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
jsonReply["config"] = server.ReadServerSettingsFile();
|
||||
jsonReply["result"] = "success";
|
||||
}
|
||||
catch (CustomException ex)
|
||||
{
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
return Task.FromResult<JToken>(jsonReply);
|
||||
}
|
||||
|
||||
async Task<JToken> HandleApplyJackettConfig(HttpListenerContext context)
|
||||
{
|
||||
JToken jsonReply = new JObject();
|
||||
|
||||
try
|
||||
{
|
||||
var postData = await ReadPostDataJson(context.Request.InputStream);
|
||||
int port = await server.ApplyPortConfiguration(postData);
|
||||
jsonReply["result"] = "success";
|
||||
jsonReply["port"] = port;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
return jsonReply;
|
||||
}
|
||||
|
||||
async Task<JToken> HandleJackettRestart(HttpListenerContext context)
|
||||
{
|
||||
Program.RestartServer();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,49 @@
|
|||
|
||||
|
||||
reloadIndexers();
|
||||
loadJackettSettings();
|
||||
loadSonarrInfo();
|
||||
|
||||
function loadJackettSettings() {
|
||||
getJackettConfig(function (data) {
|
||||
$("#jackett-port").val(data.config.port);
|
||||
});
|
||||
}
|
||||
|
||||
$("#change-jackett-port").click(function () {
|
||||
var jackett_port = $("#jackett-port").val();
|
||||
var jsonObject = JSON.parse('{"port":"' + jackett_port + '"}');
|
||||
|
||||
var jqxhr = $.post("apply_jackett_config", JSON.stringify(jsonObject), function (data) {
|
||||
|
||||
if (data.result == "error") {
|
||||
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
|
||||
return;
|
||||
} else {
|
||||
doNotify("The port has been changed. Jackett will now restart...", "success", "glyphicon glyphicon-ok");
|
||||
var jqxhr0 = $.post("jackett_restart", null, function (data_restart) { });
|
||||
|
||||
window.setTimeout(function () {
|
||||
url = window.location.href;
|
||||
window.location.href = url.substr(0, url.lastIndexOf(":") + 1) + data.port;
|
||||
|
||||
}, 3000);
|
||||
|
||||
}
|
||||
}).fail(function () {
|
||||
doNotify("Request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
|
||||
});
|
||||
});
|
||||
|
||||
function getJackettConfig(callback) {
|
||||
var jqxhr = $.get("get_jackett_config", function (data) {
|
||||
|
||||
callback(data);
|
||||
}).fail(function () {
|
||||
doNotify("Error loading Jackett settings, request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
|
||||
});
|
||||
}
|
||||
|
||||
function loadSonarrInfo() {
|
||||
getSonarrConfig(function (data) {
|
||||
$("#sonarr-host").val("");
|
||||
|
|
|
@ -45,6 +45,12 @@
|
|||
<span class="input-header">Jackett API Key: </span>
|
||||
<input id="api-key-input" class="form-control input-right" type="text" value="" placeholder="API Key" readonly="">
|
||||
<p>Use this key when adding indexers to Sonarr. This key works for all indexers.</p>
|
||||
<span class="input-header">Jackett port: </span>
|
||||
<input id="jackett-port" class="form-control input-right" type="text" value="" placeholder="9117">
|
||||
<button id="change-jackett-port" class="btn btn-primary btn-sm">
|
||||
Configure <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
|
||||
</button>
|
||||
<span title="Jackett will restart after changing the port" class="glyphicon glyphicon-info-sign"></span>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
|
Loading…
Reference in New Issue