mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Added UI for allowing external access, stop server listening on the old port when changing ports. Config migration bug fixes.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
|
||||
rmdir /s /q build
|
||||
rmdir /s /q Output
|
||||
cd src
|
||||
Msbuild Jackett.sln /t:Clean,Build /p:Configuration=Release
|
||||
cd ..
|
||||
@@ -9,6 +10,8 @@ copy /Y src\Jackett.Service\bin\Release\JackettService.exe build\JackettService.
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe.config build\JackettService.exe.config
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe build\JackettTray.exe
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe.config build\JackettTray.exe.config
|
||||
copy /Y LICENSE build\LICENSE
|
||||
copy /Y README.md build\README.md
|
||||
cd build
|
||||
del *.pdb
|
||||
del *.xml
|
||||
|
@@ -9,8 +9,6 @@ namespace Jackett.Console
|
||||
{
|
||||
public class ConsoleOptions
|
||||
{
|
||||
private bool listenPublic = false;
|
||||
|
||||
[Option('i', "Install", HelpText = "Install Jackett windows service (Must be admin)")]
|
||||
public bool Install { get; set; }
|
||||
|
||||
@@ -47,5 +45,7 @@ namespace Jackett.Console
|
||||
[Option('p', "Port", HelpText = "Web server port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[Option('m', "MigrateSettings", HelpText = "Migrate settings manually (Must be admin on Windows)")]
|
||||
public bool MigrateSettings { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -54,6 +54,7 @@ namespace JackettConsole
|
||||
// Reserve urls
|
||||
if (options.ReserveUrls)
|
||||
{
|
||||
Engine.ConfigService.CreateOrMigrateSettings();
|
||||
Engine.Server.ReserveUrls(doInstall: true);
|
||||
return;
|
||||
}
|
||||
@@ -78,6 +79,16 @@ namespace JackettConsole
|
||||
return;
|
||||
}
|
||||
|
||||
// Migrate settings
|
||||
if (options.MigrateSettings)
|
||||
{
|
||||
if (Engine.ServiceConfig.ServiceRunning())
|
||||
{
|
||||
Engine.ConfigService.PerformMigration();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Show Version
|
||||
if (options.ShowVersion)
|
||||
@@ -125,6 +136,8 @@ namespace JackettConsole
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Engine.Server.SaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +160,8 @@ namespace JackettConsole
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Engine.Server.SaveConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -203,3 +203,7 @@ hr {
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#jackett-allowext {
|
||||
width: 25px;
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ function loadJackettSettings() {
|
||||
$("#api-key-input").val(data.config.api_key);
|
||||
$("#app-version").html(data.app_version);
|
||||
$("#jackett-port").val(data.config.port);
|
||||
$("#jackett-allowext").attr('checked', data.config.external);
|
||||
var password = data.config.password;
|
||||
$("#jackett-adminpwd").val(password);
|
||||
if (password != null && password != '') {
|
||||
@@ -17,20 +18,21 @@ function loadJackettSettings() {
|
||||
|
||||
$("#change-jackett-port").click(function () {
|
||||
var jackett_port = $("#jackett-port").val();
|
||||
var jsonObject = { port: jackett_port};
|
||||
var jackett_external = $("#jackett-allowext").is(':checked');
|
||||
var jsonObject = { port: jackett_port, external: jackett_external};
|
||||
var jqxhr = $.post("/admin/set_port", 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. Redirecting you to the new port.", "success", "glyphicon glyphicon-ok");
|
||||
var jqxhr0 = $.post("admin/jackett_restart", null, function (data_restart) { });
|
||||
|
||||
window.setTimeout(function () {
|
||||
url = window.location.href;
|
||||
window.location.href = url.substr(0, url.lastIndexOf(":") + 1) + data.port;
|
||||
|
||||
if (data.external) {
|
||||
window.location.href = url.substr(0, url.lastIndexOf(":") + 1) + data.port;
|
||||
} else {
|
||||
window.location.href = 'http://127.0.0.1:' + data.port;
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
}
|
||||
|
@@ -35,26 +35,33 @@
|
||||
<span class="input-header">API Key: </span>
|
||||
<input id="api-key-input" class="form-control input-right" type="text" value="" placeholder="API Key" readonly="">
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<h3>Configured Indexers</h3>
|
||||
<div id="indexers"> </div>
|
||||
<hr />
|
||||
<h3>Jackett Configuration</h3>
|
||||
<div class="input-area">
|
||||
<span class="input-header">Admin Password: </span>
|
||||
<input id="jackett-adminpwd" class="form-control input-right" type="password" value="" placeholder="Blank to disable">
|
||||
<input id="jackett-adminpwd" class="form-control input-right" type="password" value="" placeholder="Blank to disable" />
|
||||
<button id="change-jackett-password" class="btn btn-primary btn-sm">
|
||||
Set Password <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
|
||||
</button>
|
||||
<a href="Dashboard?logout=true" id="logoutBtn" style="display:none" class="btn btn-danger btn-sm">
|
||||
Logout
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
<div class="input-area">
|
||||
<span class="input-header">Server 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">
|
||||
Change Port <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
|
||||
Apply server settings <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<hr />
|
||||
<h3>Configured Indexers</h3>
|
||||
<div id="indexers"> </div>
|
||||
<div class="input-area">
|
||||
<span class="input-header">External access: </span>
|
||||
<input id="jackett-allowext" class="form-control input-right" type="checkbox" />
|
||||
</div>
|
||||
<hr />
|
||||
<div id="footer">
|
||||
Jackett Version <span id="app-version"></span>
|
||||
|
BIN
src/Jackett/Content/logos/BakaBT.png
Normal file
BIN
src/Jackett/Content/logos/BakaBT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
@@ -44,12 +44,21 @@ namespace Jackett.Controllers
|
||||
|
||||
if (!string.Equals(torznabQuery.ApiKey, serverService.Config.APIKey, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
logger.Warn(string.Format("A request from {0} was made with an incorrect API key.", Request.GetOwinContext().Request.RemoteIpAddress));
|
||||
return Request.CreateResponse(HttpStatusCode.Forbidden, "Incorrect API key");
|
||||
}
|
||||
|
||||
var releases = await indexer.PerformQuery(torznabQuery);
|
||||
|
||||
logger.Info(string.Format("Found {0} releases from {1}", releases.Length, indexer.DisplayName));
|
||||
if (string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
|
||||
{
|
||||
logger.Info(string.Format("Found {0} releases from {1}", releases.Length, indexer.DisplayName));
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info(string.Format("Found {0} releases from {1} for: {2}", releases.Length, indexer.DisplayName, torznabQuery.SanitizedSearchTerm));
|
||||
}
|
||||
|
||||
var severUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
|
||||
|
||||
var resultPage = new ResultPage(new ChannelInfo
|
||||
|
@@ -260,6 +260,7 @@ namespace Jackett.Controllers
|
||||
{
|
||||
var cfg = new JObject();
|
||||
cfg["port"] = serverService.Config.Port;
|
||||
cfg["external"] = serverService.Config.AllowExternal;
|
||||
cfg["api_key"] = serverService.Config.APIKey;
|
||||
cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword )? string.Empty:serverService.Config.AdminPassword.Substring(0,10);
|
||||
|
||||
@@ -285,13 +286,15 @@ namespace Jackett.Controllers
|
||||
public async Task<IHttpActionResult> SetConfig()
|
||||
{
|
||||
var originalPort = Engine.Server.Config.Port;
|
||||
var originalAllowExternal = Engine.Server.Config.AllowExternal;
|
||||
var jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
var postData = await ReadPostDataJson();
|
||||
int port = (int)postData["port"];
|
||||
bool external = (bool)postData["external"];
|
||||
|
||||
if (port != Engine.Server.Config.Port)
|
||||
if (port != Engine.Server.Config.Port || external != Engine.Server.Config.AllowExternal)
|
||||
{
|
||||
if (ServerUtil.RestrictedPorts.Contains(port))
|
||||
{
|
||||
@@ -300,6 +303,8 @@ namespace Jackett.Controllers
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
// Save port to the config so it can be picked up by the if needed when running as admin below.
|
||||
Engine.Server.Config.AllowExternal = external;
|
||||
Engine.Server.Config.Port = port;
|
||||
Engine.Server.SaveConfig();
|
||||
|
||||
@@ -311,6 +316,7 @@ namespace Jackett.Controllers
|
||||
catch
|
||||
{
|
||||
Engine.Server.Config.Port = originalPort;
|
||||
Engine.Server.Config.AllowExternal = originalAllowExternal;
|
||||
Engine.Server.SaveConfig();
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = "Failed to acquire admin permissions to reserve the new port.";
|
||||
@@ -323,12 +329,16 @@ namespace Jackett.Controllers
|
||||
|
||||
(new Thread(() => {
|
||||
Thread.Sleep(500);
|
||||
serverService.Start();
|
||||
serverService.Stop();
|
||||
Engine.BuildContainer();
|
||||
Engine.Server.Initalize();
|
||||
Engine.Server.Start();
|
||||
})).Start();
|
||||
}
|
||||
|
||||
jsonReply["result"] = "success";
|
||||
jsonReply["port"] = port;
|
||||
jsonReply["external"] = external;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using Jackett.Services;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.LayoutRenderers;
|
||||
using NLog.Targets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -107,8 +108,10 @@ namespace Jackett
|
||||
|
||||
private static void SetupLogging(ContainerBuilder builder)
|
||||
{
|
||||
var logConfig = new LoggingConfiguration();
|
||||
// Add custom date time format renderer as the default is too long
|
||||
ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("simpledatetime", typeof(SimpleDateTimeRenderer));
|
||||
|
||||
var logConfig = new LoggingConfiguration();
|
||||
var logFile = new FileTarget();
|
||||
logConfig.AddTarget("file", logFile);
|
||||
logFile.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
|
||||
@@ -124,7 +127,7 @@ namespace Jackett
|
||||
var logConsole = new ColoredConsoleTarget();
|
||||
logConfig.AddTarget("console", logConsole);
|
||||
|
||||
logConsole.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
|
||||
logConsole.Layout = "${simpledatetime} ${level} ${message} ${exception:format=ToString}";
|
||||
var logConsoleRule = new LoggingRule("*", Startup.TracingEnabled ? LogLevel.Debug : LogLevel.Info, logConsole);
|
||||
logConfig.LoggingRules.Add(logConsoleRule);
|
||||
|
||||
@@ -132,4 +135,13 @@ namespace Jackett
|
||||
builder.RegisterInstance<Logger>(LogManager.GetCurrentClassLogger()).SingleInstance();
|
||||
}
|
||||
}
|
||||
|
||||
[LayoutRenderer("simpledatetime")]
|
||||
public class SimpleDateTimeRenderer : LayoutRenderer
|
||||
{
|
||||
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
|
||||
{
|
||||
builder.Append(DateTime.Now.ToString("MM-dd HH:mm:ss"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -103,12 +103,27 @@ namespace Jackett.Indexers
|
||||
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
|
||||
var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
|
||||
|
||||
var response = await webclient.GetString(new Utils.Clients.WebRequest()
|
||||
WebClientStringResult response = null;
|
||||
|
||||
// Their web server is fairly flakey - try up to three times.
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
Url = episodeSearchUrl,
|
||||
Referer = SiteLink.ToString(),
|
||||
Cookies = cookieHeader
|
||||
});
|
||||
try
|
||||
{
|
||||
response = await webclient.GetString(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = episodeSearchUrl,
|
||||
Referer = SiteLink.ToString(),
|
||||
Cookies = cookieHeader
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("On attempt " + (i + 1) + " checking for results from IPTorrents: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
var results = response.Content;
|
||||
try
|
||||
|
@@ -138,7 +138,7 @@ namespace Jackett.Indexers
|
||||
break;
|
||||
}
|
||||
catch (Exception e){
|
||||
logger.Error(e, "Error checking for results from MoreThanTv.");
|
||||
logger.Error("On attempt " + (i+1) + " checking for results from MoreThanTv: " + e.Message );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -272,6 +272,7 @@
|
||||
<Content Include="Content\logos\animebytes.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\BakaBT.png" />
|
||||
<Content Include="Content\logos\bb.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Jackett.Utils;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -22,21 +23,25 @@ namespace Jackett.Services
|
||||
T GetConfig<T>();
|
||||
void SaveConfig<T>(T config);
|
||||
string ApplicationFolder();
|
||||
void CreateOrMigrateSettings();
|
||||
void PerformMigration();
|
||||
}
|
||||
|
||||
public class ConfigurationService : IConfigurationService
|
||||
{
|
||||
private ISerializeService serializeService;
|
||||
private Logger logger;
|
||||
private IProcessService processService;
|
||||
|
||||
public ConfigurationService(ISerializeService s, Logger l)
|
||||
public ConfigurationService(ISerializeService s, IProcessService p, Logger l)
|
||||
{
|
||||
serializeService = s;
|
||||
logger = l;
|
||||
processService = p;
|
||||
CreateOrMigrateSettings();
|
||||
}
|
||||
|
||||
private void CreateOrMigrateSettings()
|
||||
public void CreateOrMigrateSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -57,20 +62,30 @@ namespace Jackett.Services
|
||||
string oldDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett");
|
||||
if (Directory.Exists(oldDir))
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(oldDir, "*", SearchOption.AllDirectories))
|
||||
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
{
|
||||
var path = file.Replace(oldDir, "");
|
||||
var destFolder = GetAppDataFolder() + path;
|
||||
if (!Directory.Exists(Path.GetDirectoryName(destFolder)))
|
||||
// On Windows we need admin permissions to migrate as they were made with admin permissions.
|
||||
if (ServerUtil.IsUserAdministrator())
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFolder));
|
||||
PerformMigration();
|
||||
}
|
||||
if (!File.Exists(destFolder))
|
||||
else
|
||||
{
|
||||
File.Move(file, destFolder);
|
||||
try
|
||||
{
|
||||
processService.StartProcessAndLog(Application.ExecutablePath, "--MigrateSettings", true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Engine.Logger.Error("Unable to migrate settings when not running as administrator.");
|
||||
Environment.ExitCode = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
PerformMigration();
|
||||
}
|
||||
Directory.Delete(oldDir, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -79,6 +94,25 @@ namespace Jackett.Services
|
||||
}
|
||||
}
|
||||
|
||||
public void PerformMigration()
|
||||
{
|
||||
var oldDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett");
|
||||
foreach (var file in Directory.GetFiles(oldDir, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
var path = file.Replace(oldDir, "");
|
||||
var destFolder = GetAppDataFolder() + path;
|
||||
if (!Directory.Exists(Path.GetDirectoryName(destFolder)))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFolder));
|
||||
}
|
||||
if (!File.Exists(destFolder))
|
||||
{
|
||||
File.Copy(file, destFolder);
|
||||
}
|
||||
}
|
||||
Directory.Delete(oldDir, true);
|
||||
}
|
||||
|
||||
public T GetConfig<T>()
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
@@ -131,7 +131,7 @@ namespace Jackett.Services
|
||||
if (doInstall)
|
||||
{
|
||||
logger.Debug("Reserving Urls");
|
||||
config.GetListenAddresses(true).ToList().ForEach(u => RunNetSh(string.Format("http add urlacl {0} sddl=D:(A;;GX;;;S-1-1-0)", u)));
|
||||
config.GetListenAddresses(config.AllowExternal).ToList().ForEach(u => RunNetSh(string.Format("http add urlacl {0} sddl=D:(A;;GX;;;S-1-1-0)", u)));
|
||||
logger.Debug("Urls reserved");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user