diff --git a/src/Jackett.Console/App.config b/src/Jackett.Console/App.config
new file mode 100644
index 000000000..da396d090
--- /dev/null
+++ b/src/Jackett.Console/App.config
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Jackett.Console/Jackett.Console.csproj b/src/Jackett.Console/Jackett.Console.csproj
new file mode 100644
index 000000000..54ba94594
--- /dev/null
+++ b/src/Jackett.Console/Jackett.Console.csproj
@@ -0,0 +1,130 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {4E2A81DA-E235-4A88-AD20-38AABBFBF33C}
+ Exe
+ Properties
+ Jackett.Console
+ JackettConsole
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ jackett.ico
+
+
+ JackettConsole.Program
+
+
+
+ False
+ ..\packages\Autofac.3.5.0\lib\net40\Autofac.dll
+
+
+ ..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll
+
+
+ False
+ ..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll
+
+
+ ..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll
+
+
+ ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.Host.HttpListener.2.0.2\lib\net45\Microsoft.Owin.Host.HttpListener.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll
+ True
+
+
+ ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+ True
+
+
+
+
+ ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
+ True
+
+
+ ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
+ True
+
+
+ ..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}
+ Jackett
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Jackett.Console/Program.cs b/src/Jackett.Console/Program.cs
new file mode 100644
index 000000000..d1d4c9429
--- /dev/null
+++ b/src/Jackett.Console/Program.cs
@@ -0,0 +1,78 @@
+using Jackett;
+using Jackett.Indexers;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace JackettConsole
+{
+ public class Program
+ {
+ static void Main(string[] args)
+ {
+
+
+ Server.Start();
+ Console.ReadKey();
+
+
+ /* var serverTask = Task.Run(async () =>
+ {
+ ServerInstance = new Server();
+ await ServerInstance.Start();
+ });
+
+ try
+ {
+ if (Program.IsWindows)
+ {
+#if !__MonoCS__
+ Application.Run(new Main());
+#endif
+ }
+ }
+ catch (Exception)
+ {
+
+ }*/
+
+ Console.WriteLine("Running in headless mode.");
+
+
+
+ // Task.WaitAll(serverTask);
+ 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 public void RestartAsAdmin()
+ {
+ // var startInfo = new ProcessStartInfo(Application.ExecutablePath.ToString()) { Verb = "runas" };
+ // Process.Start(startInfo);
+ Environment.Exit(0);
+ }
+ }
+}
+
diff --git a/src/Jackett.Console/Properties/AssemblyInfo.cs b/src/Jackett.Console/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..0c11610e1
--- /dev/null
+++ b/src/Jackett.Console/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Jackett.Console")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Jackett.Console")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("4e2a81da-e235-4a88-ad20-38aabbfbf33c")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Jackett/jacket_large.ico b/src/Jackett.Console/jackett.ico
similarity index 100%
rename from src/Jackett/jacket_large.ico
rename to src/Jackett.Console/jackett.ico
diff --git a/src/Jackett.Console/packages.config b/src/Jackett.Console/packages.config
new file mode 100644
index 000000000..4878b92aa
--- /dev/null
+++ b/src/Jackett.Console/packages.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Jackett.Service/App.config b/src/Jackett.Service/App.config
new file mode 100644
index 000000000..88fa4027b
--- /dev/null
+++ b/src/Jackett.Service/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Jackett.Service/Jackett.Service.csproj b/src/Jackett.Service/Jackett.Service.csproj
new file mode 100644
index 000000000..6e2370814
--- /dev/null
+++ b/src/Jackett.Service/Jackett.Service.csproj
@@ -0,0 +1,73 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}
+ WinExe
+ Properties
+ Jackett.Service
+ JackettService
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ jackett.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Component
+
+
+ Service.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Jackett.Service/Program.cs b/src/Jackett.Service/Program.cs
new file mode 100644
index 000000000..22c25af4b
--- /dev/null
+++ b/src/Jackett.Service/Program.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.ServiceProcess;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Service
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ static void Main()
+ {
+ ServiceBase[] ServicesToRun;
+ ServicesToRun = new ServiceBase[]
+ {
+ new Service()
+ };
+ ServiceBase.Run(ServicesToRun);
+ }
+ }
+}
diff --git a/src/Jackett.Service/Properties/AssemblyInfo.cs b/src/Jackett.Service/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..246a632ba
--- /dev/null
+++ b/src/Jackett.Service/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Jackett.Service")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Jackett.Service")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("bf611f7b-4658-4cb8-aa9e-0736fadaa3ba")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Jackett.Service/Service.Designer.cs b/src/Jackett.Service/Service.Designer.cs
new file mode 100644
index 000000000..c0310557f
--- /dev/null
+++ b/src/Jackett.Service/Service.Designer.cs
@@ -0,0 +1,37 @@
+namespace Jackett.Service
+{
+ partial class Service
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ this.ServiceName = "Service1";
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Jackett.Service/Service.cs b/src/Jackett.Service/Service.cs
new file mode 100644
index 000000000..d1e29db74
--- /dev/null
+++ b/src/Jackett.Service/Service.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Linq;
+using System.ServiceProcess;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Service
+{
+ public partial class Service : ServiceBase
+ {
+ public Service()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnStart(string[] args)
+ {
+ }
+
+ protected override void OnStop()
+ {
+ }
+ }
+}
diff --git a/src/Jackett.Service/jackett.ico b/src/Jackett.Service/jackett.ico
new file mode 100644
index 000000000..6392acc61
Binary files /dev/null and b/src/Jackett.Service/jackett.ico differ
diff --git a/src/Jackett.Tray/App.config b/src/Jackett.Tray/App.config
new file mode 100644
index 000000000..88fa4027b
--- /dev/null
+++ b/src/Jackett.Tray/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Jackett.Tray/Jackett.Tray.csproj b/src/Jackett.Tray/Jackett.Tray.csproj
new file mode 100644
index 000000000..0e3f38375
--- /dev/null
+++ b/src/Jackett.Tray/Jackett.Tray.csproj
@@ -0,0 +1,96 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {FF9025B1-EC14-4AA9-8081-9F69C5E35B63}
+ WinExe
+ Properties
+ Jackett.Tray
+ JackettTray
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ jackett.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Main.cs
+
+
+
+
+ Main.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Jackett/Main.Designer.cs b/src/Jackett.Tray/Main.Designer.cs
similarity index 98%
rename from src/Jackett/Main.Designer.cs
rename to src/Jackett.Tray/Main.Designer.cs
index d881a2821..71457c20d 100644
--- a/src/Jackett/Main.Designer.cs
+++ b/src/Jackett.Tray/Main.Designer.cs
@@ -1,6 +1,4 @@
-#if !__MonoCS__
-
-namespace Jackett
+namespace JackettTray
{
partial class Main
{
@@ -99,5 +97,4 @@ namespace Jackett
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemShutdown;
}
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/Jackett/Main.cs b/src/Jackett.Tray/Main.cs
similarity index 89%
rename from src/Jackett/Main.cs
rename to src/Jackett.Tray/Main.cs
index 250aff2ce..a1a51b09f 100644
--- a/src/Jackett/Main.cs
+++ b/src/Jackett.Tray/Main.cs
@@ -13,7 +13,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
-namespace Jackett
+namespace JackettTray
{
public partial class Main : Form
{
@@ -28,13 +28,13 @@ namespace Jackett
toolStripMenuItemWebUI.Click += toolStripMenuItemWebUI_Click;
toolStripMenuItemShutdown.Click += toolStripMenuItemShutdown_Click;
- if (Program.IsFirstRun)
- AutoStart = true;
+ //if (Server.IsFirstRun)
+ // AutoStart = true;
}
void toolStripMenuItemWebUI_Click(object sender, EventArgs e)
{
- Process.Start("http://127.0.0.1:" + Server.Port);
+ // Process.Start("http://127.0.0.1:" + Server.Port);
}
void toolStripMenuItemShutdown_Click(object sender, EventArgs e)
@@ -84,12 +84,12 @@ namespace Jackett
private void CreateShortcut()
{
- var appPath = Assembly.GetExecutingAssembly().Location;
+ /* var appPath = Assembly.GetExecutingAssembly().Location;
var shell = new IWshRuntimeLibrary.WshShell();
var shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(ShortcutPath);
shortcut.Description = Assembly.GetExecutingAssembly().GetName().Name;
shortcut.TargetPath = appPath;
- shortcut.Save();
+ shortcut.Save();*/
}
}
}
diff --git a/src/Jackett/Main.resx b/src/Jackett.Tray/Main.resx
similarity index 100%
rename from src/Jackett/Main.resx
rename to src/Jackett.Tray/Main.resx
diff --git a/src/Jackett.Tray/Program.cs b/src/Jackett.Tray/Program.cs
new file mode 100644
index 000000000..ddcd715a9
--- /dev/null
+++ b/src/Jackett.Tray/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Jackett.Tray
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ // Application.Run(new Form1());
+ }
+ }
+}
diff --git a/src/Jackett.Tray/Properties/AssemblyInfo.cs b/src/Jackett.Tray/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..0f6590c99
--- /dev/null
+++ b/src/Jackett.Tray/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Jackett.Tray")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Jackett.Tray")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("ff9025b1-ec14-4aa9-8081-9f69c5e35b63")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Jackett.Tray/Properties/Resources.Designer.cs b/src/Jackett.Tray/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..b6ce33f0b
--- /dev/null
+++ b/src/Jackett.Tray/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Jackett.Tray.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Jackett.Tray.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/src/Jackett.Tray/Properties/Resources.resx b/src/Jackett.Tray/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/src/Jackett.Tray/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/Jackett.Tray/Properties/Settings.Designer.cs b/src/Jackett.Tray/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..c110e9e5e
--- /dev/null
+++ b/src/Jackett.Tray/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Jackett.Tray.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/src/Jackett.Tray/Properties/Settings.settings b/src/Jackett.Tray/Properties/Settings.settings
new file mode 100644
index 000000000..39645652a
--- /dev/null
+++ b/src/Jackett.Tray/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/Jackett.Tray/jackett.ico b/src/Jackett.Tray/jackett.ico
new file mode 100644
index 000000000..6392acc61
Binary files /dev/null and b/src/Jackett.Tray/jackett.ico differ
diff --git a/src/Jackett.sln b/src/Jackett.sln
index a7c6e3384..7e7f1ea9b 100644
--- a/src/Jackett.sln
+++ b/src/Jackett.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
+# Visual Studio 14
+VisualStudioVersion = 14.0.22823.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett", "Jackett\Jackett.csproj", "{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}"
EndProject
@@ -13,6 +13,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\README.md = ..\README.md
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Console", "Jackett.Console\Jackett.Console.csproj", "{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Service", "Jackett.Service\Jackett.Service.csproj", "{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Tray", "Jackett.Tray\Jackett.Tray.csproj", "{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +33,18 @@ Global
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/Jackett/App.config b/src/Jackett/App.config
index 56ebf3f29..547fa70d5 100644
--- a/src/Jackett/App.config
+++ b/src/Jackett/App.config
@@ -9,7 +9,27 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Jackett/Controllers/AdminController.cs b/src/Jackett/Controllers/AdminController.cs
new file mode 100644
index 000000000..bac229054
--- /dev/null
+++ b/src/Jackett/Controllers/AdminController.cs
@@ -0,0 +1,265 @@
+using Autofac;
+using Jackett.Models;
+using Jackett.Services;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web.Http;
+
+namespace Jackett.Controllers
+{
+ [RoutePrefix("admin")]
+ public class AdminController : ApiController
+ {
+ private IConfigurationService config;
+ private ISonarrApi sonarrApi;
+ private IIndexerManagerService indexerService;
+
+ public AdminController(IConfigurationService config, ISonarrApi s, IIndexerManagerService i)
+ {
+ this.config = config;
+ sonarrApi = s;
+ indexerService = i;
+ }
+
+ private async Task ReadPostDataJson()
+ {
+ var content = await Request.Content.ReadAsStringAsync();
+ return JObject.Parse(content);
+ }
+
+ [Route("get_config_form")]
+ [HttpGet]
+ public async Task GetConfigForm()
+ {
+ var jsonReply = new JObject();
+ try
+ {
+ var postData = await ReadPostDataJson();
+ var indexer = indexerService.GetIndexer((string)postData["indexer"]);
+ 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 Json(jsonReply);
+ }
+
+ [Route("configure_indexer")]
+ [HttpPost]
+ public async Task Configure()
+ {
+ JToken jsonReply = new JObject();
+ try
+ {
+ var postData = await ReadPostDataJson();
+ string indexerString = (string)postData["indexer"];
+ var indexer = indexerService.GetIndexer((string)postData["indexer"]);
+ jsonReply["name"] = indexer.DisplayName;
+ await indexer.ApplyConfiguration(postData["config"]);
+ indexerService.TestIndexer((string)postData["indexer"]);
+ jsonReply["result"] = "success";
+ }
+ catch (Exception ex)
+ {
+ jsonReply["result"] = "error";
+ jsonReply["error"] = ex.Message;
+ if (ex is ExceptionWithConfigData)
+ {
+ jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson();
+ }
+ }
+ return Json(jsonReply);
+ }
+
+
+
+ [Route("get_indexers")]
+ [HttpGet]
+ public IHttpActionResult Indexers()
+ {
+ var jsonReply = new JObject();
+ try
+ {
+ jsonReply["result"] = "success";
+ jsonReply["api_key"] = ApiKey.CurrentKey;
+ jsonReply["app_version"] = config.GetVersion();
+ JArray items = new JArray();
+
+ foreach (var indexer in indexerService.GetAllIndexers())
+ {
+ var item = new JObject();
+ item["id"] = indexer.GetType().Name.ToLowerInvariant();
+ 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 Json(jsonReply);
+ }
+
+ [Route("test_indexer")]
+ [HttpPost]
+ public async Task Test()
+ {
+ JToken jsonReply = new JObject();
+ try
+ {
+ var postData = await ReadPostDataJson();
+ string indexerString = (string)postData["indexer"];
+ indexerService.TestIndexer(indexerString);
+ jsonReply["result"] = "success";
+ }
+ catch (Exception ex)
+ {
+ jsonReply["result"] = "error";
+ jsonReply["error"] = ex.Message;
+ }
+ return Json(jsonReply);
+ }
+
+ [Route("delete_indexer")]
+ [HttpPost]
+ public async Task Delete()
+ {
+ var jsonReply = new JObject();
+ try
+ {
+ var postData = await ReadPostDataJson();
+ string indexerString = (string)postData["indexer"];
+ indexerService.DeleteIndexer(indexerString);
+ }
+ catch (Exception ex)
+ {
+ jsonReply["result"] = "error";
+ jsonReply["error"] = ex.Message;
+ }
+ return Json(jsonReply);
+ }
+
+ [Route("get_sonarr_config")]
+ [HttpGet]
+ public IHttpActionResult Sonarr()
+ {
+ JObject jsonReply = new JObject();
+ try
+ {
+ jsonReply["config"] = sonarrApi.GetConfiguration().ToJson();
+ jsonReply["result"] = "success";
+ }
+ catch (Exception ex)
+ {
+ jsonReply["result"] = "error";
+ jsonReply["error"] = ex.Message;
+ }
+ return Json(jsonReply);
+ }
+
+ [Route("apply_sonarr_config")]
+ [HttpPost]
+ public async Task SonarrEdit()
+ {
+ var jsonReply = new JObject();
+ try
+ {
+ var postData = await ReadPostDataJson();
+ await sonarrApi.ApplyConfiguration(postData);
+ jsonReply["result"] = "success";
+ }
+ catch (Exception ex)
+ {
+ jsonReply["result"] = "error";
+ jsonReply["error"] = ex.Message;
+ }
+ return Json(jsonReply);
+ }
+
+ [Route("test_sonarr")]
+ [HttpPost]
+ public async Task SonarrTest()
+ {
+ JToken jsonReply = new JObject();
+ try
+ {
+ await sonarrApi.TestConnection();
+ jsonReply["result"] = "success";
+ }
+ catch (Exception ex)
+ {
+ jsonReply["result"] = "error";
+ jsonReply["error"] = ex.Message;
+ }
+ return Json(jsonReply);
+ }
+
+ [Route("get_jackett_config")]
+ [HttpGet]
+ public IHttpActionResult GetConfig()
+ {
+ var jsonReply = new JObject();
+ try
+ {
+ jsonReply["config"] = config.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 Json(jsonReply);
+ }
+
+ [Route("apply_jackett_config")]
+ [HttpPost]
+ public async Task SetConfig()
+ {
+ var jsonReply = new JObject();
+ try
+ {
+ var postData = await ReadPostDataJson();
+ // int port = await WebServer.ApplyPortConfiguration(postData);
+ jsonReply["result"] = "success";
+ // jsonReply["port"] = port;
+ }
+ catch (Exception ex)
+ {
+ jsonReply["result"] = "error";
+ jsonReply["error"] = ex.Message;
+ }
+ return Json(jsonReply);
+ }
+
+
+ [Route("jackett_restart")]
+ [HttpPost]
+ public IHttpActionResult Restart()
+ {
+ return null;
+ }
+ }
+}
+
diff --git a/src/Jackett/CookieContainerExtensions.cs b/src/Jackett/CookieContainerExtensions.cs
index 447c3be30..8d7343a35 100644
--- a/src/Jackett/CookieContainerExtensions.cs
+++ b/src/Jackett/CookieContainerExtensions.cs
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -12,7 +13,7 @@ namespace Jackett
public static class CookieContainerExtensions
{
- public static void FillFromJson(this CookieContainer cookies, Uri uri, JToken json)
+ public static void FillFromJson(this CookieContainer cookies, Uri uri, JToken json, Logger logger)
{
if (json["cookies"] != null)
{
@@ -43,7 +44,7 @@ namespace Jackett
}
catch (CookieException ex)
{
- Program.LoggerInstance.Info("(Non-critical) Problem loading cookie {0}, {1}, {2}", uri, c, ex.Message);
+ logger.Info("(Non-critical) Problem loading cookie {0}, {1}, {2}", uri, c, ex.Message);
}
}
}
diff --git a/src/Jackett/ExceptionWithConfigData.cs b/src/Jackett/ExceptionWithConfigData.cs
index 60cf8deae..9280d5f14 100644
--- a/src/Jackett/ExceptionWithConfigData.cs
+++ b/src/Jackett/ExceptionWithConfigData.cs
@@ -1,4 +1,5 @@
-using System;
+using Jackett.Models;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/src/Jackett/IndexerInterface.cs b/src/Jackett/IndexerInterface.cs
index 1e4e2e583..f8629b4c4 100644
--- a/src/Jackett/IndexerInterface.cs
+++ b/src/Jackett/IndexerInterface.cs
@@ -1,4 +1,5 @@
-using Newtonsoft.Json.Linq;
+using Jackett.Models;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/src/Jackett/IndexerManager.cs b/src/Jackett/IndexerManager.cs
index e5f3d8f62..edb59d674 100644
--- a/src/Jackett/IndexerManager.cs
+++ b/src/Jackett/IndexerManager.cs
@@ -8,10 +8,10 @@ using System.Threading.Tasks;
namespace Jackett
{
- public class IndexerManager
+ /*public class IndexerManager
{
- static string IndexerConfigDirectory = Path.Combine(Program.AppConfigDirectory, "Indexers");
+ static string IndexerConfigDirectory = Path.Combine(WebServer.AppConfigDirectory, "Indexers");
public Dictionary Indexers { get; private set; }
@@ -60,7 +60,7 @@ namespace Jackett
var fileName = string.Format("Error on {0} for {1}.txt", DateTime.Now.ToString("yyyyMMddHHmmss"), indexer.DisplayName);
var spacing = string.Join("", Enumerable.Repeat(Environment.NewLine, 5));
var fileContents = string.Format("{0}{1}{2}", ex, spacing, results);
- File.WriteAllText(Path.Combine(Program.AppConfigDirectory, fileName), fileContents);
+ File.WriteAllText(Path.Combine(WebServer.AppConfigDirectory, fileName), fileContents);
}
string GetIndexerConfigFilePath(IndexerInterface indexer)
@@ -97,11 +97,11 @@ namespace Jackett
{
var browseQuery = new TorznabQuery();
var results = await indexer.PerformQuery(browseQuery);
- Program.LoggerInstance.Debug(string.Format("Found {0} releases from {1}", results.Length, indexer.DisplayName));
+ WebServer.LoggerInstance.Debug(string.Format("Found {0} releases from {1}", results.Length, indexer.DisplayName));
if (results.Length == 0)
throw new Exception("Found no results while trying to browse this tracker");
}
- }
+ }*/
}
diff --git a/src/Jackett/Indexers/AlphaRatio.cs b/src/Jackett/Indexers/AlphaRatio.cs
index e4c3c93ec..b75fc7539 100644
--- a/src/Jackett/Indexers/AlphaRatio.cs
+++ b/src/Jackett/Indexers/AlphaRatio.cs
@@ -9,6 +9,9 @@ using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Net.Http.Headers;
+using Jackett.Utils;
+using Jackett.Models;
+using NLog;
namespace Jackett.Indexers
{
@@ -50,11 +53,13 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
string cookieHeader;
- public AlphaRatio()
+ public AlphaRatio(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -98,7 +103,7 @@ namespace Jackett.Indexers
configSaveData = new JObject();
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
// If Windows use .net http
var response = await client.SendAsync(message);
@@ -142,7 +147,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(SiteLink, jsonConfig);
+ cookies.FillFromJson(SiteLink, jsonConfig, logger);
cookieHeader = cookies.GetCookieHeader(SiteLink);
IsConfigured = true;
}
@@ -169,7 +174,7 @@ namespace Jackett.Indexers
var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
string results;
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
var request = CreateHttpRequest(new Uri(episodeSearchUrl));
request.Method = HttpMethod.Get;
@@ -237,7 +242,7 @@ namespace Jackett.Indexers
public async Task Download(Uri link)
{
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
return await client.GetByteArrayAsync(link);
}
diff --git a/src/Jackett/Indexers/AnimeBytes.cs b/src/Jackett/Indexers/AnimeBytes.cs
index 46b744bc6..9726e32e3 100644
--- a/src/Jackett/Indexers/AnimeBytes.cs
+++ b/src/Jackett/Indexers/AnimeBytes.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -69,9 +72,11 @@ namespace Jackett.Indexers
CookieContainer cookieContainer;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
- public AnimeBytes()
+ public AnimeBytes(Logger l)
{
+ logger = l;
IsConfigured = false;
cookieContainer = new CookieContainer();
handler = new HttpClientHandler
@@ -162,7 +167,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookieContainer.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookieContainer.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
AllowRaws = jsonConfig["raws"].Value();
}
diff --git a/src/Jackett/Indexers/BeyondHD.cs b/src/Jackett/Indexers/BeyondHD.cs
index f8c4fe955..f7578bf21 100644
--- a/src/Jackett/Indexers/BeyondHD.cs
+++ b/src/Jackett/Indexers/BeyondHD.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -41,9 +44,11 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
- public BeyondHD()
+ public BeyondHD(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -68,7 +73,7 @@ namespace Jackett.Indexers
var jsonCookie = new JObject();
jsonCookie["cookie_header"] = config.CookieHeader;
- cookies.FillFromJson(new Uri(BaseUrl), jsonCookie);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonCookie, logger);
var responseContent = await client.GetStringAsync(BaseUrl);
@@ -92,7 +97,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/BitHdtv.cs b/src/Jackett/Indexers/BitHdtv.cs
index fc16b16f9..b22259c2b 100644
--- a/src/Jackett/Indexers/BitHdtv.cs
+++ b/src/Jackett/Indexers/BitHdtv.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -39,9 +42,11 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger loggger;
- public BitHdtv()
+ public BitHdtv(Logger l)
{
+ loggger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -101,7 +106,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, loggger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/BitMeTV.cs b/src/Jackett/Indexers/BitMeTV.cs
index 109ff8c03..abed435a9 100644
--- a/src/Jackett/Indexers/BitMeTV.cs
+++ b/src/Jackett/Indexers/BitMeTV.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -48,12 +51,14 @@ namespace Jackett
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
public event Action OnSaveConfigurationRequested;
public event Action OnResultParsingError;
- public BitMeTV()
+ public BitMeTV(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -122,7 +127,7 @@ namespace Jackett
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/FrenchTorrentDb.cs b/src/Jackett/Indexers/FrenchTorrentDb.cs
index 6a2d92528..c2fa7abfc 100644
--- a/src/Jackett/Indexers/FrenchTorrentDb.cs
+++ b/src/Jackett/Indexers/FrenchTorrentDb.cs
@@ -1,4 +1,6 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
diff --git a/src/Jackett/Indexers/Freshon.cs b/src/Jackett/Indexers/Freshon.cs
index 29fcca3f2..936194e19 100644
--- a/src/Jackett/Indexers/Freshon.cs
+++ b/src/Jackett/Indexers/Freshon.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -38,9 +41,11 @@ namespace Jackett
public Uri SiteLink { get { return new Uri(BaseUrl); } }
public event Action OnSaveConfigurationRequested;
+ Logger logger;
- public Freshon()
+ public Freshon(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -101,7 +106,7 @@ namespace Jackett
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/HDTorrents.cs b/src/Jackett/Indexers/HDTorrents.cs
index 6d691d256..342f00053 100644
--- a/src/Jackett/Indexers/HDTorrents.cs
+++ b/src/Jackett/Indexers/HDTorrents.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -29,9 +32,11 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
- public HDTorrents()
+ public HDTorrents(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -122,7 +127,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(SiteLink, jsonConfig);
+ cookies.FillFromJson(SiteLink, jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/IPTorrents.cs b/src/Jackett/Indexers/IPTorrents.cs
index bcf43b311..d72a1fbb9 100644
--- a/src/Jackett/Indexers/IPTorrents.cs
+++ b/src/Jackett/Indexers/IPTorrents.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -36,9 +39,11 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
- public IPTorrents()
+ public IPTorrents(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -110,7 +115,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(Newtonsoft.Json.Linq.JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/TVRage.cs b/src/Jackett/Indexers/Master.cs
similarity index 54%
rename from src/Jackett/TVRage.cs
rename to src/Jackett/Indexers/Master.cs
index ed871114e..b563b69cd 100644
--- a/src/Jackett/TVRage.cs
+++ b/src/Jackett/Indexers/Master.cs
@@ -1,12 +1,16 @@
-using System;
+using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Indexers
{
- class TVRage
+ class Master
{
+
+
+
}
}
diff --git a/src/Jackett/Indexers/MoreThanTV.cs b/src/Jackett/Indexers/MoreThanTV.cs
index a05c7ae9f..e2ef6459f 100644
--- a/src/Jackett/Indexers/MoreThanTV.cs
+++ b/src/Jackett/Indexers/MoreThanTV.cs
@@ -1,5 +1,7 @@
using CsQuery;
+using Jackett.Models;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.IO;
@@ -48,12 +50,14 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
string cookieHeader;
int retries = 3;
- public MoreThanTV()
+ public MoreThanTV(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -89,7 +93,7 @@ namespace Jackett.Indexers
var configSaveData = new JObject();
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
// If Windows use .net http
var response = await client.PostAsync(LoginUrl, content);
@@ -125,7 +129,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(SiteLink, jsonConfig);
+ cookies.FillFromJson(SiteLink, jsonConfig, logger);
cookieHeader = cookies.GetCookieHeader(SiteLink);
IsConfigured = true;
}
@@ -152,7 +156,7 @@ namespace Jackett.Indexers
var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
string results;
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
results = await client.GetStringAsync(episodeSearchUrl, retries);
}
@@ -220,7 +224,7 @@ namespace Jackett.Indexers
public async Task Download(Uri link)
{
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
return await client.GetByteArrayAsync(link);
}
diff --git a/src/Jackett/Indexers/Rarbg.cs b/src/Jackett/Indexers/Rarbg.cs
index ce40972c7..61bf3929c 100644
--- a/src/Jackett/Indexers/Rarbg.cs
+++ b/src/Jackett/Indexers/Rarbg.cs
@@ -1,4 +1,6 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
diff --git a/src/Jackett/Indexers/SceneAccess.cs b/src/Jackett/Indexers/SceneAccess.cs
index d29372658..f4f9053db 100644
--- a/src/Jackett/Indexers/SceneAccess.cs
+++ b/src/Jackett/Indexers/SceneAccess.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -46,9 +49,11 @@ namespace Jackett.Indexers
HttpClientHandler handler;
HttpClient client;
string cookieHeader;
+ Logger logger;
- public SceneAccess()
+ public SceneAccess(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -82,7 +87,7 @@ namespace Jackett.Indexers
string responseContent;
var configSaveData = new JObject();
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
// If Windows use .net http
var response = await client.PostAsync(LoginUrl, content);
@@ -116,7 +121,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
cookieHeader = cookies.GetCookieHeader(SiteLink);
IsConfigured = true;
}
@@ -134,7 +139,7 @@ namespace Jackett.Indexers
var searchUrl = string.Format(SearchUrl, searchSection, searchCategory, searchString);
string results;
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
results = await client.GetStringAsync(searchUrl);
}
@@ -190,7 +195,7 @@ namespace Jackett.Indexers
public async Task Download(Uri link)
{
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
return await client.GetByteArrayAsync(link);
}
diff --git a/src/Jackett/Indexers/SceneTime.cs b/src/Jackett/Indexers/SceneTime.cs
index 853faaffc..4f192bad1 100644
--- a/src/Jackett/Indexers/SceneTime.cs
+++ b/src/Jackett/Indexers/SceneTime.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -43,10 +46,12 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
- public SceneTime()
+ public SceneTime(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -99,7 +104,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/ShowRSS.cs b/src/Jackett/Indexers/ShowRSS.cs
index 3702c4e65..415c7bc32 100644
--- a/src/Jackett/Indexers/ShowRSS.cs
+++ b/src/Jackett/Indexers/ShowRSS.cs
@@ -1,4 +1,6 @@
-using Newtonsoft.Json.Linq;
+using Jackett.Models;
+using Jackett.Utils;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/src/Jackett/Indexers/Strike.cs b/src/Jackett/Indexers/Strike.cs
index b30eac578..a8e39f06f 100644
--- a/src/Jackett/Indexers/Strike.cs
+++ b/src/Jackett/Indexers/Strike.cs
@@ -1,4 +1,5 @@
-using Newtonsoft.Json.Linq;
+using Jackett.Models;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/src/Jackett/Indexers/T411.cs b/src/Jackett/Indexers/T411.cs
index 450a65867..d763581d2 100644
--- a/src/Jackett/Indexers/T411.cs
+++ b/src/Jackett/Indexers/T411.cs
@@ -1,4 +1,6 @@
-using Newtonsoft.Json.Linq;
+using Jackett.Models;
+using Jackett.Utils;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/src/Jackett/Indexers/ThePirateBay.cs b/src/Jackett/Indexers/ThePirateBay.cs
index fa248b68c..0c50851bb 100644
--- a/src/Jackett/Indexers/ThePirateBay.cs
+++ b/src/Jackett/Indexers/ThePirateBay.cs
@@ -1,4 +1,6 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
@@ -108,7 +110,7 @@ namespace Jackett.Indexers
string results;
- if (Program.IsWindows)
+ if (WebServer.IsWindows)
{
results = await client.GetStringAsync(episodeSearchUrl);
}
diff --git a/src/Jackett/Indexers/TorrentDay.cs b/src/Jackett/Indexers/TorrentDay.cs
index a270bc3bc..f71ed7903 100644
--- a/src/Jackett/Indexers/TorrentDay.cs
+++ b/src/Jackett/Indexers/TorrentDay.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -45,9 +48,11 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
- public TorrentDay()
+ public TorrentDay(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -118,7 +123,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/TorrentLeech.cs b/src/Jackett/Indexers/TorrentLeech.cs
index c865059a3..95dfe08da 100644
--- a/src/Jackett/Indexers/TorrentLeech.cs
+++ b/src/Jackett/Indexers/TorrentLeech.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -43,9 +46,11 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
- public TorrentLeech()
+ public TorrentLeech(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -101,7 +106,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/TorrentShack.cs b/src/Jackett/Indexers/TorrentShack.cs
index d7b88c705..3492cae86 100644
--- a/src/Jackett/Indexers/TorrentShack.cs
+++ b/src/Jackett/Indexers/TorrentShack.cs
@@ -1,5 +1,8 @@
using CsQuery;
+using Jackett.Models;
+using Jackett.Utils;
using Newtonsoft.Json.Linq;
+using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -41,11 +44,13 @@ namespace Jackett.Indexers
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
+ Logger logger;
public bool IsConfigured { get; private set; }
- public TorrentShack()
+ public TorrentShack(Logger l)
{
+ logger = l;
IsConfigured = false;
cookies = new CookieContainer();
handler = new HttpClientHandler
@@ -103,7 +108,7 @@ namespace Jackett.Indexers
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
- cookies.FillFromJson(new Uri(BaseUrl), jsonConfig);
+ cookies.FillFromJson(new Uri(BaseUrl), jsonConfig, logger);
IsConfigured = true;
}
diff --git a/src/Jackett/Indexers/Torrentz.cs b/src/Jackett/Indexers/Torrentz.cs
index d822f93a8..3c3cbe1de 100644
--- a/src/Jackett/Indexers/Torrentz.cs
+++ b/src/Jackett/Indexers/Torrentz.cs
@@ -1,4 +1,6 @@
-using Newtonsoft.Json.Linq;
+using Jackett.Models;
+using Jackett.Utils;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj
index c0044dbf4..b04a292f6 100644
--- a/src/Jackett/Jackett.csproj
+++ b/src/Jackett/Jackett.csproj
@@ -5,7 +5,7 @@
Debug
AnyCPU
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}
- WinExe
+ Library
Properties
Jackett
Jackett
@@ -48,25 +48,77 @@
4
- jacket_large.ico
+
+
- Jackett.Program
+
+
+
+ ..\packages\Autofac.3.5.2\lib\net40\Autofac.dll
+ True
+
+
+ ..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll
+
+
+ False
+ ..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll
+
+
+ ..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll
+
..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll
+
+ ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.Host.HttpListener.2.0.2\lib\net45\Microsoft.Owin.Host.HttpListener.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll
+ True
+
..\packages\NLog.Windows.Forms.2.0.0.0\lib\net35\NLog.Windows.Forms.dll
True
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+ True
+
+
+ ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
+ True
+
+
+ ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
+ True
+
+
+ ..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
+ True
+
@@ -81,14 +133,15 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -102,6 +155,7 @@
+
@@ -115,30 +169,27 @@
-
- Form
-
-
- Main.cs
-
-
-
+
+
True
True
Resources.resx
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
@@ -151,9 +202,6 @@
-
- Main.cs
-
ResXFileCodeGenerator
Resources.Designer.cs
@@ -196,7 +244,6 @@
PreserveNewest
-
PreserveNewest
@@ -242,7 +289,6 @@
PreserveNewest
-
PreserveNewest
@@ -327,4 +373,4 @@
-
+
\ No newline at end of file
diff --git a/src/Jackett/JackettModule.cs b/src/Jackett/JackettModule.cs
new file mode 100644
index 000000000..1aa607ebb
--- /dev/null
+++ b/src/Jackett/JackettModule.cs
@@ -0,0 +1,29 @@
+using Autofac;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autofac.Integration.WebApi;
+
+namespace Jackett
+{
+ public class JackettModule: Module
+ {
+ protected override void Load(ContainerBuilder builder)
+ {
+ // Just register everything!
+ var thisAssembly = typeof(JackettModule).Assembly;
+ builder.RegisterAssemblyTypes(thisAssembly).AsImplementedInterfaces().SingleInstance();
+ builder.RegisterApiControllers(thisAssembly).InstancePerRequest();
+
+ // Register indexers
+ foreach(var indexer in thisAssembly.GetTypes()
+ .Where(p => typeof(IndexerInterface).IsAssignableFrom(p) && !p.IsInterface)
+ .ToArray())
+ {
+ builder.RegisterType(indexer).Named(indexer.Name.ToLowerInvariant()).SingleInstance();
+ }
+ }
+ }
+}
diff --git a/src/Jackett/ApiKey.cs b/src/Jackett/Models/ApiKey.cs
similarity index 96%
rename from src/Jackett/ApiKey.cs
rename to src/Jackett/Models/ApiKey.cs
index 86848899a..aec36e33e 100644
--- a/src/Jackett/ApiKey.cs
+++ b/src/Jackett/Models/ApiKey.cs
@@ -5,7 +5,7 @@ using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public class ApiKey
{
diff --git a/src/Jackett/CachedResult.cs b/src/Jackett/Models/CachedResult.cs
similarity index 96%
rename from src/Jackett/CachedResult.cs
rename to src/Jackett/Models/CachedResult.cs
index 925d9a139..24feea319 100644
--- a/src/Jackett/CachedResult.cs
+++ b/src/Jackett/Models/CachedResult.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public class CachedResult
{
diff --git a/src/Jackett/ChannelInfo.cs b/src/Jackett/Models/ChannelInfo.cs
similarity index 96%
rename from src/Jackett/ChannelInfo.cs
rename to src/Jackett/Models/ChannelInfo.cs
index a42421e01..e9afa5112 100644
--- a/src/Jackett/ChannelInfo.cs
+++ b/src/Jackett/Models/ChannelInfo.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public class ChannelInfo
{
diff --git a/src/Jackett/ConfigurationData.cs b/src/Jackett/Models/ConfigurationData.cs
similarity index 99%
rename from src/Jackett/ConfigurationData.cs
rename to src/Jackett/Models/ConfigurationData.cs
index 971698b0c..41b6b0055 100644
--- a/src/Jackett/ConfigurationData.cs
+++ b/src/Jackett/Models/ConfigurationData.cs
@@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public abstract class ConfigurationData
{
diff --git a/src/Jackett/ConfigurationDataBasicLogin.cs b/src/Jackett/Models/ConfigurationDataBasicLogin.cs
similarity index 96%
rename from src/Jackett/ConfigurationDataBasicLogin.cs
rename to src/Jackett/Models/ConfigurationDataBasicLogin.cs
index 19a2ab0ff..66afbffe3 100644
--- a/src/Jackett/ConfigurationDataBasicLogin.cs
+++ b/src/Jackett/Models/ConfigurationDataBasicLogin.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public class ConfigurationDataBasicLogin : ConfigurationData
{
diff --git a/src/Jackett/ConfigurationDataCookie.cs b/src/Jackett/Models/ConfigurationDataCookie.cs
similarity index 98%
rename from src/Jackett/ConfigurationDataCookie.cs
rename to src/Jackett/Models/ConfigurationDataCookie.cs
index c184dfc5a..afa3e46e5 100644
--- a/src/Jackett/ConfigurationDataCookie.cs
+++ b/src/Jackett/Models/ConfigurationDataCookie.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public class ConfigurationDataCookie : ConfigurationData
diff --git a/src/Jackett/ConfigurationDataUrl.cs b/src/Jackett/Models/ConfigurationDataUrl.cs
similarity index 96%
rename from src/Jackett/ConfigurationDataUrl.cs
rename to src/Jackett/Models/ConfigurationDataUrl.cs
index e302cf2fd..08e80a76a 100644
--- a/src/Jackett/ConfigurationDataUrl.cs
+++ b/src/Jackett/Models/ConfigurationDataUrl.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public class ConfigurationDataUrl : ConfigurationData
{
diff --git a/src/Jackett/ReleaseInfo.cs b/src/Jackett/Models/ReleaseInfo.cs
similarity index 99%
rename from src/Jackett/ReleaseInfo.cs
rename to src/Jackett/Models/ReleaseInfo.cs
index a6845102a..b81d810e7 100644
--- a/src/Jackett/ReleaseInfo.cs
+++ b/src/Jackett/Models/ReleaseInfo.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public class ReleaseInfo: ICloneable
diff --git a/src/Jackett/ResultPage.cs b/src/Jackett/Models/ResultPage.cs
similarity index 99%
rename from src/Jackett/ResultPage.cs
rename to src/Jackett/Models/ResultPage.cs
index f9d4b9b2e..fe238e225 100644
--- a/src/Jackett/ResultPage.cs
+++ b/src/Jackett/Models/ResultPage.cs
@@ -9,7 +9,7 @@ using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
-namespace Jackett
+namespace Jackett.Models
{
public class ResultPage
{
diff --git a/src/Jackett/TorznabQuery.cs b/src/Jackett/Models/TorznabQuery.cs
similarity index 97%
rename from src/Jackett/TorznabQuery.cs
rename to src/Jackett/Models/TorznabQuery.cs
index 06a5651d9..40e63f794 100644
--- a/src/Jackett/TorznabQuery.cs
+++ b/src/Jackett/Models/TorznabQuery.cs
@@ -1,4 +1,5 @@
-using System;
+using Jackett.Utils;
+using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
@@ -6,7 +7,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Models
{
public class TorznabQuery
{
diff --git a/src/Jackett/Program.cs b/src/Jackett/Program.cs
deleted file mode 100644
index 4d7134dbd..000000000
--- a/src/Jackett/Program.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-using Jackett.Indexers;
-using Newtonsoft.Json.Linq;
-using NLog;
-using NLog.Config;
-using NLog.Targets;
-using NLog.Windows.Forms;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows.Forms;
-
-namespace Jackett
-{
- class Program
- {
- public static string AppConfigDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett");
-
- public static Server ServerInstance { get; private set; }
-
- public static bool IsFirstRun { get; private set; }
-
- public static Logger LoggerInstance { get; private set; }
-
- public static ManualResetEvent ExitEvent { get; private set; }
-
- public static bool IsWindows { get { return Environment.OSVersion.Platform == PlatformID.Win32NT; } }
-
-
-
- static void Main(string[] args)
- {
- ExitEvent = new ManualResetEvent(false);
-
- MigrateSettingsDirectory();
-
- try
- {
- if (!Directory.Exists(AppConfigDirectory))
- {
- IsFirstRun = true;
- Directory.CreateDirectory(AppConfigDirectory);
- }
- Console.WriteLine("App config/log directory: " + AppConfigDirectory);
- }
- catch (Exception ex)
- {
- MessageBox.Show("Could not create settings directory. " + ex.Message);
- Application.Exit();
- return;
- }
-
- var logConfig = new LoggingConfiguration();
-
- var logFile = new FileTarget();
- logConfig.AddTarget("file", logFile);
- logFile.Layout = "${longdate} ${level} ${message} \n ${exception:format=ToString}\n";
- logFile.FileName = Path.Combine(AppConfigDirectory, "log.txt");
- logFile.ArchiveFileName = "log.{#####}.txt";
- logFile.ArchiveAboveSize = 500000;
- logFile.MaxArchiveFiles = 1;
- logFile.KeepFileOpen = false;
- logFile.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
- var logFileRule = new LoggingRule("*", LogLevel.Debug, logFile);
- logConfig.LoggingRules.Add(logFileRule);
-
- if (Program.IsWindows)
- {
-#if !__MonoCS__
- var logAlert = new MessageBoxTarget();
- logConfig.AddTarget("alert", logAlert);
- logAlert.Layout = "${message}";
- logAlert.Caption = "Alert";
- var logAlertRule = new LoggingRule("*", LogLevel.Fatal, logAlert);
- logConfig.LoggingRules.Add(logAlertRule);
-#endif
- }
-
- var logConsole = new ConsoleTarget();
- logConfig.AddTarget("console", logConsole);
- logConsole.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
- var logConsoleRule = new LoggingRule("*", LogLevel.Debug, logConsole);
- logConfig.LoggingRules.Add(logConsoleRule);
-
- LogManager.Configuration = logConfig;
- LoggerInstance = LogManager.GetCurrentClassLogger();
-
- ReadSettingsFile();
-
- var serverTask = Task.Run(async () =>
- {
- ServerInstance = new Server();
- await ServerInstance.Start();
- });
-
- try
- {
- if (Program.IsWindows)
- {
-#if !__MonoCS__
- Application.Run(new Main());
-#endif
- }
- }
- catch (Exception)
- {
-
- }
-
- Console.WriteLine("Running in headless mode.");
-
-
-
- Task.WaitAll(serverTask);
- 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
- {
- string oldDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Jackett");
- if (Directory.Exists(oldDir) && !Directory.Exists(AppConfigDirectory))
- {
- Directory.Move(oldDir, AppConfigDirectory);
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine("ERROR could not migrate settings directory " + ex);
- }
- }
-
- static void ReadSettingsFile()
- {
- var path = Path.Combine(AppConfigDirectory, "config.json");
- if (!File.Exists(path))
- {
- JObject f = new JObject();
- f.Add("port", Server.DefaultPort);
- f.Add("public", true);
- File.WriteAllText(path, f.ToString());
- }
-
- var configJson = JObject.Parse(File.ReadAllText(path));
- int port = (int)configJson.GetValue("port");
- Server.Port = port;
-
- Server.ListenPublic = (bool)configJson.GetValue("public");
-
- Console.WriteLine("Config file path: " + path);
- }
-
- static public void RestartAsAdmin()
- {
- var startInfo = new ProcessStartInfo(Application.ExecutablePath.ToString()) { Verb = "runas" };
- Process.Start(startInfo);
- Environment.Exit(0);
- }
- }
-}
diff --git a/src/Jackett/Server.cs b/src/Jackett/Server.cs
index ed4b26111..8d7732ab0 100644
--- a/src/Jackett/Server.cs
+++ b/src/Jackett/Server.cs
@@ -1,305 +1,93 @@
-using Newtonsoft.Json.Linq;
+using Autofac;
+using Jackett.Services;
+using Microsoft.Owin.Hosting;
+using NLog;
+using NLog.Config;
+using NLog.Targets;
+using NLog.Windows.Forms;
using System;
using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Diagnostics;
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;
namespace Jackett
{
public class Server
{
- public const int DefaultPort = 9117;
- public static int Port = DefaultPort;
- public static bool ListenPublic = true;
+ private static IContainer container = null;
+ private static string baseAddress = "http://localhost:9000/";
+ private static IDisposable _server = null;
- HttpListener listener;
- IndexerManager indexerManager;
- WebApi webApi;
- SonarrApi sonarrApi;
-
-
- public Server()
+ static Server()
{
- // Allow all SSL.. sucks I know but mono on linux is having problems without it..
- ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
-
- ReadServerSettingsFile();
- LoadApiKey();
+ var builder = new ContainerBuilder();
+ builder.RegisterModule();
+ container = builder.Build();
- indexerManager = new IndexerManager();
- sonarrApi = new SonarrApi();
- webApi = new WebApi(indexerManager, sonarrApi);
-
+ // Register the container in itself to allow for late resolves
+ var secondaryBuilder = new ContainerBuilder();
+ secondaryBuilder.RegisterInstance(container);
+ SetupLogging(secondaryBuilder, container.Resolve());
+ secondaryBuilder.Update(container);
}
- void LoadApiKey()
+ private static void SetupLogging(ContainerBuilder builder, IConfigurationService config)
{
- var apiKeyFile = Path.Combine(Program.AppConfigDirectory, "api_key.txt");
- if (File.Exists(apiKeyFile))
- ApiKey.CurrentKey = File.ReadAllText(apiKeyFile).Trim();
- else
+ var logConfig = new LoggingConfiguration();
+
+ var logFile = new FileTarget();
+ logConfig.AddTarget("file", logFile);
+ logFile.Layout = "${longdate} ${level} ${message} \n ${exception:format=ToString}\n";
+ logFile.FileName = Path.Combine(config.GetAppDataFolder(), "log.txt");
+ logFile.ArchiveFileName = "log.{#####}.txt";
+ logFile.ArchiveAboveSize = 500000;
+ logFile.MaxArchiveFiles = 1;
+ logFile.KeepFileOpen = false;
+ logFile.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
+ var logFileRule = new LoggingRule("*", LogLevel.Debug, logFile);
+ logConfig.LoggingRules.Add(logFileRule);
+
+ /* if (WebServer.IsWindows)
{
- ApiKey.CurrentKey = ApiKey.Generate();
- File.WriteAllText(apiKeyFile, ApiKey.CurrentKey);
+#if !__MonoCS__
+ var logAlert = new MessageBoxTarget();
+ logConfig.AddTarget("alert", logAlert);
+ logAlert.Layout = "${message}";
+ logAlert.Caption = "Alert";
+ var logAlertRule = new LoggingRule("*", LogLevel.Fatal, logAlert);
+ logConfig.LoggingRules.Add(logAlertRule);
+#endif
+ }*/
+
+ var logConsole = new ConsoleTarget();
+ logConfig.AddTarget("console", logConsole);
+ logConsole.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
+ var logConsoleRule = new LoggingRule("*", LogLevel.Debug, logConsole);
+ logConfig.LoggingRules.Add(logConsoleRule);
+
+ LogManager.Configuration = logConfig;
+ builder.RegisterInstance(LogManager.GetCurrentClassLogger()).SingleInstance();
+ }
+
+ public static void Start()
+ {
+ _server = WebApp.Start(url: baseAddress);
+ }
+
+ public static void Stop()
+ {
+ if (_server != null)
+ {
+ _server.Dispose();
}
}
- public async Task Start()
+ public static IContainer GetContainer()
{
- Program.LoggerInstance.Info("Starting HTTP server on port " + Port + " listening " + (ListenPublic ? "publicly" : "privately"));
-
- try
- {
- listener = new HttpListener();
-
- if (ListenPublic)
- {
- listener.Prefixes.Add(string.Format("http://*:{0}/", Port));
- }
- else
- {
- listener.Prefixes.Add(string.Format("http://127.0.0.1:{0}/", Port));
- }
-
- listener.Start();
- webApi.server = this;
- }
- catch (HttpListenerException ex)
- {
- if (ex.ErrorCode == 5)
- {
- var errorStr = "App must be ran as admin for permission to use port "
- + Port + Environment.NewLine + "Restart app with admin privileges?";
- if (Program.IsWindows)
- {
- var dialogResult = MessageBox.Show(errorStr, "Error", MessageBoxButtons.YesNo);
- if (dialogResult == DialogResult.No)
- {
- Application.Exit();
- return;
- }
- else
- {
- Program.RestartAsAdmin();
- }
- }
- }
- else
- {
- Program.LoggerInstance.FatalException("Failed to start HTTP server. " + ex.Message, ex);
- }
- }
- catch (Exception ex)
- {
- Program.LoggerInstance.ErrorException("Error starting HTTP server: " + ex.Message, ex);
- return;
- }
-
- Program.LoggerInstance.Info("Server started on port " + Port);
- Program.LoggerInstance.Info("Accepting only requests from local system: " + (!ListenPublic));
-
- while (true)
- {
- Exception error = null;
- try
- {
- error = null;
- var context = await listener.GetContextAsync();
- ProcessHttpRequest(context);
- }
- catch (ObjectDisposedException ex)
- {
- Program.LoggerInstance.ErrorException("Critical error, HTTP listener was destroyed", ex);
- Process.GetCurrentProcess().Kill();
- }
- catch (Exception ex)
- {
- error = ex;
- Program.LoggerInstance.ErrorException("Error processing HTTP request", ex);
- }
-
- if (error != null)
- await Task.Delay(TimeSpan.FromSeconds(5));
- }
+ return container;
}
-
- public void Stop()
- {
- listener.Stop();
- listener.Abort();
- }
-
- async void ProcessHttpRequest(HttpListenerContext context)
- {
- Program.LoggerInstance.Trace("Received request: " + context.Request.Url.ToString());
- Exception exception = null;
- try
- {
- if (await webApi.HandleRequest(context))
- {
-
- }
- else if (context.Request.Url.AbsolutePath.StartsWith("/api/"))
- {
- await ProcessTorznab(context);
- }
- else
- {
- var responseBytes = Encoding.UTF8.GetBytes("Invalid request");
- await context.Response.OutputStream.WriteAsync(responseBytes, 0, responseBytes.Length);
- }
- }
- catch (Exception ex)
- {
- exception = ex;
- Program.LoggerInstance.ErrorException(ex.Message + ex.ToString(), ex);
- }
-
- if (exception != null)
- {
- try
- {
- var errorBytes = Encoding.UTF8.GetBytes(exception.Message);
- await context.Response.OutputStream.WriteAsync(errorBytes, 0, errorBytes.Length);
- }
- catch (Exception)
- {
- }
- }
-
- try
- {
- context.Response.Close();
- }
- catch (Exception)
- {
- }
-
- }
-
- async Task ProcessTorznab(HttpListenerContext context)
- {
-
- var query = HttpUtility.ParseQueryString(context.Request.Url.Query);
- var inputStream = context.Request.InputStream;
-
- var indexerId = context.Request.Url.Segments[2].TrimEnd('/').ToLower();
- var indexer = indexerManager.GetIndexer(indexerId);
-
- if (context.Request.Url.Segments.Length > 4 && context.Request.Url.Segments[3] == "download/")
- {
- var downloadSegment = HttpServerUtility.UrlTokenDecode(context.Request.Url.Segments[4].TrimEnd('/'));
- var downloadLink = Encoding.UTF8.GetString(downloadSegment);
- var downloadBytes = await indexer.Download(new Uri(downloadLink));
- await context.Response.OutputStream.WriteAsync(downloadBytes, 0, downloadBytes.Length);
- return;
- }
-
- var torznabQuery = TorznabQuery.FromHttpQuery(query);
-
- if (torznabQuery.RageID != 0)
- torznabQuery.ShowTitles = await sonarrApi.GetShowTitle(torznabQuery.RageID);
- else if (!string.IsNullOrEmpty(torznabQuery.SearchTerm))
- torznabQuery.ShowTitles = new string[] { torznabQuery.SearchTerm };
-
- var releases = await indexer.PerformQuery(torznabQuery);
-
- Program.LoggerInstance.Debug(string.Format("Found {0} releases from {1}", releases.Length, indexer.DisplayName));
-
- var severUrl = string.Format("{0}://{1}:{2}/", context.Request.Url.Scheme, context.Request.Url.Host, context.Request.Url.Port);
-
- var resultPage = new ResultPage(new ChannelInfo
- {
- Title = indexer.DisplayName,
- Description = indexer.DisplayDescription,
- Link = indexer.SiteLink,
- ImageUrl = new Uri(severUrl + "logos/" + indexerId + ".png"),
- ImageTitle = indexer.DisplayName,
- ImageLink = indexer.SiteLink,
- ImageDescription = indexer.DisplayName
- });
-
- // add Jackett proxy to download links...
- foreach (var release in releases)
- {
- if (release.Link == null || release.Link.Scheme == "magnet")
- continue;
- var originalLink = release.Link;
- var encodedLink = HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(originalLink.ToString())) + "/download.torrent";
- var proxyLink = string.Format("{0}api/{1}/download/{2}", severUrl, indexerId, encodedLink);
- release.Link = new Uri(proxyLink);
- }
-
- resultPage.Releases.AddRange(releases);
-
- var xml = resultPage.ToXml(new Uri(severUrl));
-
- var responseBytes = Encoding.UTF8.GetBytes(xml);
- context.Response.ContentEncoding = Encoding.UTF8;
- context.Response.ContentLength64 = responseBytes.LongLength;
- context.Response.ContentType = "application/rss+xml";
- await context.Response.OutputStream.WriteAsync(responseBytes, 0, responseBytes.Length);
-
- }
-
-
-
-
- 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 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());
- }
-
}
}
diff --git a/src/Jackett/Services/ConfigurationService.cs b/src/Jackett/Services/ConfigurationService.cs
new file mode 100644
index 000000000..d01cc6477
--- /dev/null
+++ b/src/Jackett/Services/ConfigurationService.cs
@@ -0,0 +1,84 @@
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Jackett.Services
+{
+ public interface IConfigurationService
+ {
+ string GetContentFolder();
+ string GetVersion();
+ string GetIndexerConfigDir();
+ string GetAppDataFolder();
+ JObject ReadServerSettingsFile();
+ string GetSonarrConfigFile();
+ }
+
+ public class ConfigurationService: IConfigurationService
+ {
+ public string GetContentFolder()
+ {
+ var baseDir = Path.GetDirectoryName(Application.ExecutablePath);
+ // If we are debugging we can use the non copied content.
+ if (Debugger.IsAttached)
+ {
+ return Path.Combine(baseDir, "..\\..\\..\\Jackett\\WebContent");
+ }
+ else
+ {
+ return Path.Combine(baseDir, "WebContent");
+ }
+ }
+
+ public string GetVersion()
+ {
+ return Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ }
+
+ public string GetAppDataFolder()
+ {
+ return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett"); ;
+ }
+
+ public string GetIndexerConfigDir()
+ {
+ return Path.Combine(GetAppDataFolder(), "Indexers");
+ }
+
+ public string GetConfigFile()
+ {
+ return Path.Combine(GetAppDataFolder(), "config.json");
+ }
+
+ public string GetSonarrConfigFile()
+ {
+ return Path.Combine(GetAppDataFolder(), "sonarr_api.json");
+ }
+
+
+ public JObject ReadServerSettingsFile()
+ {
+ var path = GetConfigFile();
+ 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;
+ }
+ }
+}
diff --git a/src/Jackett/Services/IndexerManagerService.cs b/src/Jackett/Services/IndexerManagerService.cs
new file mode 100644
index 000000000..b5e1fa966
--- /dev/null
+++ b/src/Jackett/Services/IndexerManagerService.cs
@@ -0,0 +1,68 @@
+using Autofac;
+using Jackett.Models;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Services
+{
+ public interface IIndexerManagerService
+ {
+ void TestIndexer(string name);
+ void DeleteIndexer(string name);
+ IndexerInterface GetIndexer(string name);
+ IEnumerable GetAllIndexers();
+ }
+
+ public class IndexerManagerService : IIndexerManagerService
+ {
+ private IContainer container;
+ private IConfigurationService configService;
+ private Logger logger;
+
+ public IndexerManagerService(IContainer c, IConfigurationService config, Logger l)
+ {
+ container = c;
+ configService = config;
+ logger = l;
+ }
+
+ public IndexerInterface GetIndexer(string name)
+ {
+ return container.ResolveNamed(name.ToLowerInvariant());
+ }
+
+ public IEnumerable GetAllIndexers()
+ {
+ return container.Resolve>().OrderBy(_ => _.DisplayName);
+ }
+
+ public async void TestIndexer(string name)
+ {
+ var indexer = GetIndexer(name);
+ var browseQuery = new TorznabQuery();
+ var results = await indexer.PerformQuery(browseQuery);
+ logger.Debug(string.Format("Found {0} releases from {1}", results.Length, indexer.DisplayName));
+ if (results.Length == 0)
+ throw new Exception("Found no results while trying to browse this tracker");
+ }
+
+ public void DeleteIndexer(string name)
+ {
+ var indexer = GetIndexer(name);
+ var configPath = configService.GetIndexerConfigDir();
+ File.Delete(configPath);
+ //Indexers.Remove(name);
+ //LoadMissingIndexers();
+ }
+
+ private string GetIndexerConfigFilePath(IndexerInterface indexer)
+ {
+ return Path.Combine(configService.GetIndexerConfigDir(), indexer.GetType().Name.ToLower() + ".json");
+ }
+ }
+}
diff --git a/src/Jackett/SonarApi.cs b/src/Jackett/Services/SonarApi.cs
similarity index 87%
rename from src/Jackett/SonarApi.cs
rename to src/Jackett/Services/SonarApi.cs
index cf7178c91..ed54e6b2c 100644
--- a/src/Jackett/SonarApi.cs
+++ b/src/Jackett/Services/SonarApi.cs
@@ -1,4 +1,7 @@
-using Newtonsoft.Json.Linq;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -11,7 +14,14 @@ using System.Threading.Tasks;
namespace Jackett
{
- public class SonarrApi
+ public interface ISonarrApi
+ {
+ Task TestConnection();
+ SonarrApi.ConfigurationSonarr GetConfiguration();
+ Task ApplyConfiguration(JToken configJson);
+ }
+
+ public class SonarrApi: ISonarrApi
{
public class ConfigurationSonarr : ConfigurationData
{
@@ -36,7 +46,7 @@ namespace Jackett
}
- static string SonarrConfigFile = Path.Combine(Program.AppConfigDirectory, "sonarr_api.json");
+
string Host;
int Port;
@@ -48,7 +58,9 @@ namespace Jackett
ConcurrentDictionary IdNameMappings;
- public SonarrApi()
+ private IConfigurationService configService;
+
+ public SonarrApi(IConfigurationService c)
{
LoadSettings();
@@ -62,6 +74,8 @@ namespace Jackett
client = new HttpClient(handler);
IdNameMappings = new ConcurrentDictionary();
+
+ configService = c;
}
async Task ReloadNameMappings(string host, int port, string apiKey)
@@ -101,9 +115,9 @@ namespace Jackett
{
try
{
- if (File.Exists(SonarrConfigFile))
+ if (File.Exists(configService.GetSonarrConfigFile()))
{
- var json = JObject.Parse(File.ReadAllText(SonarrConfigFile));
+ var json = JObject.Parse(File.ReadAllText(configService.GetSonarrConfigFile()));
Host = (string)json["host"];
Port = (int)json["port"];
ApiKey = (string)json["api_key"];
@@ -118,7 +132,7 @@ namespace Jackett
json["host"] = Host;
json["port"] = Port;
json["api_key"] = ApiKey;
- File.WriteAllText(SonarrConfigFile, json.ToString());
+ File.WriteAllText(configService.GetSonarrConfigFile(), json.ToString());
}
public ConfigurationSonarr GetConfiguration()
diff --git a/src/Jackett/Startup.cs b/src/Jackett/Startup.cs
new file mode 100644
index 000000000..e30cfb85d
--- /dev/null
+++ b/src/Jackett/Startup.cs
@@ -0,0 +1,52 @@
+using Owin;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web.Http;
+using Autofac.Integration.WebApi;
+using Microsoft.Owin;
+using Jackett;
+using Microsoft.Owin.StaticFiles;
+using Microsoft.Owin.FileSystems;
+using Autofac;
+using Jackett.Services;
+
+[assembly: OwinStartup(typeof(Startup))]
+namespace Jackett
+{
+ public class Startup
+ {
+ public void Configuration(IAppBuilder appBuilder)
+ {
+ // Configure Web API for self-host.
+ var config = new HttpConfiguration();
+
+ config.DependencyResolver = new AutofacWebApiDependencyResolver(Server.GetContainer());
+
+
+
+ // Enable attribute based routing
+ // http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
+ config.MapHttpAttributeRoutes();
+
+ config.Routes.MapHttpRoute(
+ name: "Content",
+ routeTemplate: "{controller}/{action}",
+ defaults: new { controller = "Admin"}
+ );
+
+ appBuilder.UseFileServer(new FileServerOptions
+ {
+ RequestPath = new PathString(string.Empty),
+ FileSystem = new PhysicalFileSystem(Server.GetContainer().Resolve().GetContentFolder()),
+ EnableDirectoryBrowsing = true,
+ });
+
+ appBuilder.UseWebApi(config);
+
+ }
+ }
+}
diff --git a/src/Jackett/BrowserUtil.cs b/src/Jackett/Utils/BrowserUtil.cs
similarity index 94%
rename from src/Jackett/BrowserUtil.cs
rename to src/Jackett/Utils/BrowserUtil.cs
index 82154b176..669b1e346 100644
--- a/src/Jackett/BrowserUtil.cs
+++ b/src/Jackett/Utils/BrowserUtil.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Utils
{
public static class BrowserUtil
{
diff --git a/src/Jackett/ParseUtil.cs b/src/Jackett/Utils/ParseUtil.cs
similarity index 98%
rename from src/Jackett/ParseUtil.cs
rename to src/Jackett/Utils/ParseUtil.cs
index 9b62c0027..c96e2be7a 100644
--- a/src/Jackett/ParseUtil.cs
+++ b/src/Jackett/Utils/ParseUtil.cs
@@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Utils
{
public static class ParseUtil
{
diff --git a/src/Jackett/ServerUtil.cs b/src/Jackett/Utils/ServerUtil.cs
similarity index 99%
rename from src/Jackett/ServerUtil.cs
rename to src/Jackett/Utils/ServerUtil.cs
index 8f3e6c02f..a65f1f2f7 100644
--- a/src/Jackett/ServerUtil.cs
+++ b/src/Jackett/Utils/ServerUtil.cs
@@ -5,7 +5,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
-namespace Jackett
+namespace Jackett.Utils
{
public static class ServerUtil
{
diff --git a/src/Jackett/WebApi.cs b/src/Jackett/WebApi.cs
index ef8f46c0e..8ec3ca645 100644
--- a/src/Jackett/WebApi.cs
+++ b/src/Jackett/WebApi.cs
@@ -12,11 +12,11 @@ using System.Web;
namespace Jackett
{
- public class WebApi
+ /*public class WebApi
{
static string WebContentFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WebContent");
static string[] StaticFiles = Directory.EnumerateFiles(WebContentFolder, "*", SearchOption.AllDirectories).ToArray();
- public Server server;
+ public WebServer server;
public enum WebApiMethod
{
@@ -140,8 +140,8 @@ namespace Jackett
case WebApiMethod.GetJackettConfig:
handlerTask = HandleJackettConfig;
break;
- case WebApiMethod.JackettRestart:
- handlerTask = HandleJackettRestart;
+ // case WebApiMethod.JackettRestart:
+ // handlerTask = HandleJackettRestart;
break;
default:
handlerTask = HandleInvalidApiMethod;
@@ -341,7 +341,7 @@ namespace Jackett
JObject jsonReply = new JObject();
try
{
- jsonReply["config"] = server.ReadServerSettingsFile();
+ jsonReply["config"] = WebServer.ReadServerSettingsFile();
jsonReply["result"] = "success";
}
catch (CustomException ex)
@@ -364,7 +364,7 @@ namespace Jackett
try
{
var postData = await ReadPostDataJson(context.Request.InputStream);
- int port = await server.ApplyPortConfiguration(postData);
+ int port = await WebServer.ApplyPortConfiguration(postData);
jsonReply["result"] = "success";
jsonReply["port"] = port;
}
@@ -378,10 +378,8 @@ namespace Jackett
async Task HandleJackettRestart(HttpListenerContext context)
{
- Program.RestartServer();
- return null;
+ // WebServer.RestartServer();
+ * null;
}
-
-
- }
+ }*/
}
diff --git a/src/Jackett/WebContent/custom.js b/src/Jackett/WebContent/custom.js
index 35dd07e04..74dc7a529 100644
--- a/src/Jackett/WebContent/custom.js
+++ b/src/Jackett/WebContent/custom.js
@@ -14,14 +14,14 @@ $("#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) {
+ var jqxhr = $.post("admin/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) { });
+ var jqxhr0 = $.post("admin/jackett_restart", null, function (data_restart) { });
window.setTimeout(function () {
url = window.location.href;
@@ -36,7 +36,7 @@ $("#change-jackett-port").click(function () {
});
function getJackettConfig(callback) {
- var jqxhr = $.get("get_jackett_config", function (data) {
+ var jqxhr = $.get("admin/get_jackett_config", function (data) {
callback(data);
}).fail(function () {
@@ -66,7 +66,7 @@ function loadSonarrInfo() {
}
function getSonarrConfig(callback) {
- var jqxhr = $.get("get_sonarr_config", function (data) {
+ var jqxhr = $.get("admin/get_sonarr_config", function (data) {
callback(data);
}).fail(function () {
doNotify("Error loading Sonarr API configuration, request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
@@ -74,7 +74,7 @@ function getSonarrConfig(callback) {
}
$("#sonarr-test").click(function () {
- var jqxhr = $.get("get_indexers", function (data) {
+ var jqxhr = $.get("admin/get_indexers", function (data) {
if (data.result == "error")
doNotify("Test failed for Sonarr API\n" + data.error, "danger", "glyphicon glyphicon-alert");
else
@@ -98,7 +98,7 @@ $("#sonarr-settings").click(function () {
$goButton.prop('disabled', true);
$goButton.html($('#templates > .spinner')[0].outerHTML);
- var jqxhr = $.post("apply_sonarr_config", JSON.stringify(data), function (data) {
+ var jqxhr = $.post("admin/apply_sonarr_config", JSON.stringify(data), function (data) {
if (data.result == "error") {
if (data.config) {
populateSetupForm(data.indexer, data.name, data.config);
@@ -128,7 +128,7 @@ function reloadIndexers() {
$('#indexers').hide();
$('#indexers > .indexer').remove();
$('#unconfigured-indexers').empty();
- var jqxhr = $.get("get_indexers", function (data) {
+ var jqxhr = $.get("admin/get_indexers", function (data) {
$("#api-key-input").val(data.api_key);
$("#app-version").html(data.app_version);
displayIndexers(data.items);
@@ -163,7 +163,7 @@ function prepareDeleteButtons() {
var $btn = $(btn);
var id = $btn.data("id");
$btn.click(function () {
- var jqxhr = $.post("delete_indexer", JSON.stringify({ indexer: id }), function (data) {
+ var jqxhr = $.post("admin/delete_indexer", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") {
doNotify("Delete error for " + id + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
}
@@ -195,7 +195,7 @@ function prepareTestButtons() {
var id = $btn.data("id");
$btn.click(function () {
doNotify("Test started for " + id, "info", "glyphicon glyphicon-transfer");
- var jqxhr = $.post("test_indexer", JSON.stringify({ indexer: id }), function (data) {
+ var jqxhr = $.post("admin/test_indexer", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") {
doNotify("Test failed for " + data.name + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
}
@@ -211,7 +211,7 @@ function prepareTestButtons() {
function displayIndexerSetup(id) {
- var jqxhr = $.post("get_config_form", JSON.stringify({ indexer: id }), function (data) {
+ var jqxhr = $.post("admin/get_config_form", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
return;
@@ -281,7 +281,7 @@ function populateSetupForm(indexerId, name, config) {
$goButton.prop('disabled', true);
$goButton.html($('#templates > .spinner')[0].outerHTML);
- var jqxhr = $.post("configure_indexer", JSON.stringify(data), function (data) {
+ var jqxhr = $.post("admin/configure_indexer", JSON.stringify(data), function (data) {
if (data.result == "error") {
if (data.config) {
populateConfigItems(configForm, data.config);
diff --git a/src/Jackett/WebServer.cs b/src/Jackett/WebServer.cs
new file mode 100644
index 000000000..da9374600
--- /dev/null
+++ b/src/Jackett/WebServer.cs
@@ -0,0 +1,409 @@
+using Newtonsoft.Json.Linq;
+using NLog;
+using NLog.Config;
+using NLog.Targets;
+using NLog.Windows.Forms;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Diagnostics;
+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;
+
+namespace Jackett
+{
+ public class WebServer
+ {
+ public static bool IsWindows { get { return Environment.OSVersion.Platform == PlatformID.Win32NT; } }
+ }
+ /*
+ public const int DefaultPort = 9117;
+ public static int Port = DefaultPort;
+ public static bool ListenPublic = true;
+
+ public static Server ServerInstance { get; private set; }
+ public static bool IsFirstRun { get; private set; }
+ public static Logger LoggerInstance { get; private set; }
+ public static bool IsWindows { get { return Environment.OSVersion.Platform == PlatformID.Win32NT; } }
+ public static string AppConfigDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett");
+
+ HttpListener listener;
+ IndexerManager indexerManager;
+ WebApi webApi;
+ SonarrApi sonarrApi;
+
+
+ public WebServer()
+ {
+ // 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);
+
+ }
+
+
+ public static void SetupLogging()
+ {
+ var logConfig = new LoggingConfiguration();
+
+ var logFile = new FileTarget();
+ logConfig.AddTarget("file", logFile);
+ logFile.Layout = "${longdate} ${level} ${message} \n ${exception:format=ToString}\n";
+ logFile.FileName = Path.Combine(AppConfigDirectory, "log.txt");
+ logFile.ArchiveFileName = "log.{#####}.txt";
+ logFile.ArchiveAboveSize = 500000;
+ logFile.MaxArchiveFiles = 1;
+ logFile.KeepFileOpen = false;
+ logFile.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
+ var logFileRule = new LoggingRule("*", LogLevel.Debug, logFile);
+ logConfig.LoggingRules.Add(logFileRule);
+
+ if (WebServer.IsWindows)
+ {
+#if !__MonoCS__
+ var logAlert = new MessageBoxTarget();
+ logConfig.AddTarget("alert", logAlert);
+ logAlert.Layout = "${message}";
+ logAlert.Caption = "Alert";
+ var logAlertRule = new LoggingRule("*", LogLevel.Fatal, logAlert);
+ logConfig.LoggingRules.Add(logAlertRule);
+#endif
+ }
+
+ var logConsole = new ConsoleTarget();
+ logConfig.AddTarget("console", logConsole);
+ logConsole.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
+ var logConsoleRule = new LoggingRule("*", LogLevel.Debug, logConsole);
+ logConfig.LoggingRules.Add(logConsoleRule);
+
+ LogManager.Configuration = logConfig;
+ LoggerInstance = LogManager.GetCurrentClassLogger();
+ }
+
+ void LoadApiKey()
+ {
+ var apiKeyFile = Path.Combine(WebServer.AppConfigDirectory, "api_key.txt");
+ if (File.Exists(apiKeyFile))
+ ApiKey.CurrentKey = File.ReadAllText(apiKeyFile).Trim();
+ else
+ {
+ ApiKey.CurrentKey = ApiKey.Generate();
+ File.WriteAllText(apiKeyFile, ApiKey.CurrentKey);
+ }
+ }
+
+ static void CreateOrMigrateSettings()
+ {
+ try
+ {
+ if (!Directory.Exists(AppConfigDirectory))
+ {
+ IsFirstRun = true;
+ Directory.CreateDirectory(AppConfigDirectory);
+ }
+ Console.WriteLine("App config/log directory: " + AppConfigDirectory);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Could not create settings directory. " + ex.Message);
+ Application.Exit();
+ return;
+ }
+
+ try
+ {
+ string oldDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Jackett");
+ if (Directory.Exists(oldDir) && !Directory.Exists(AppConfigDirectory))
+ {
+ Directory.Move(oldDir, AppConfigDirectory);
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("ERROR could not migrate settings directory " + ex);
+ }
+ }
+
+
+ public async Task Start()
+ {
+ CreateOrMigrateSettings();
+ WebServer.LoggerInstance.Info("Starting HTTP server on port " + Port + " listening " + (ListenPublic ? "publicly" : "privately"));
+
+ try
+ {
+ listener = new HttpListener();
+
+ if (ListenPublic)
+ {
+ listener.Prefixes.Add(string.Format("http://*:{0}/", Port));
+ }
+ else
+ {
+ listener.Prefixes.Add(string.Format("http://127.0.0.1:{0}/", Port));
+ }
+
+ listener.Start();
+ webApi.server = this;
+ }
+ catch (HttpListenerException ex)
+ {
+ if (ex.ErrorCode == 5)
+ {
+ var errorStr = "App must be ran as admin for permission to use port "
+ + Port + Environment.NewLine + "Restart app with admin privileges?";
+ if (WebServer.IsWindows)
+ {
+ var dialogResult = MessageBox.Show(errorStr, "Error", MessageBoxButtons.YesNo);
+ if (dialogResult == DialogResult.No)
+ {
+ Application.Exit();
+ return;
+ }
+ else
+ {
+ // WebServer.RestartAsAdmin();
+ }
+ }
+ }
+ else
+ {
+ WebServer.LoggerInstance.Fatal("Failed to start HTTP WebServer. " + ex.Message, ex);
+ }
+ }
+ catch (Exception ex)
+ {
+ WebServer.LoggerInstance.Error(ex, "Error starting HTTP server: " + ex.Message);
+ return;
+ }
+
+ WebServer.LoggerInstance.Info("Server started on port " + Port);
+ WebServer.LoggerInstance.Info("Accepting only requests from local system: " + (!ListenPublic));
+
+ while (true)
+ {
+ Exception error = null;
+ try
+ {
+ error = null;
+ var context = await listener.GetContextAsync();
+ ProcessHttpRequest(context);
+ }
+ catch (ObjectDisposedException ex)
+ {
+ WebServer.LoggerInstance.Error(ex, "Critical error, HTTP listener was destroyed");
+ Process.GetCurrentProcess().Kill();
+ }
+ catch (Exception ex)
+ {
+ error = ex;
+ WebServer.LoggerInstance.Error(ex, "Error processing HTTP request");
+ }
+
+ if (error != null)
+ await Task.Delay(TimeSpan.FromSeconds(5));
+ }
+ }
+
+
+ static void ReadSettingsFile()
+ {
+ var path = Path.Combine(AppConfigDirectory, "config.json");
+ if (!File.Exists(path))
+ {
+ JObject f = new JObject();
+ f.Add("port", WebServer.DefaultPort);
+ f.Add("public", true);
+ File.WriteAllText(path, f.ToString());
+ }
+
+ var configJson = JObject.Parse(File.ReadAllText(path));
+ int port = (int)configJson.GetValue("port");
+ WebServer.Port = port;
+
+ WebServer.ListenPublic = (bool)configJson.GetValue("public");
+
+ Console.WriteLine("Config file path: " + path);
+ }
+
+ public void Stop()
+ {
+ listener.Stop();
+ listener.Abort();
+ }
+
+ async void ProcessHttpRequest(HttpListenerContext context)
+ {
+ WebServer.LoggerInstance.Trace("Received request: " + context.Request.Url.ToString());
+ Exception exception = null;
+ try
+ {
+ if (await webApi.HandleRequest(context))
+ {
+
+ }
+ else if (context.Request.Url.AbsolutePath.StartsWith("/api/"))
+ {
+ await ProcessTorznab(context);
+ }
+ else
+ {
+ var responseBytes = Encoding.UTF8.GetBytes("Invalid request");
+ await context.Response.OutputStream.WriteAsync(responseBytes, 0, responseBytes.Length);
+ }
+ }
+ catch (Exception ex)
+ {
+ exception = ex;
+ WebServer.LoggerInstance.Error(ex, ex.Message + ex.ToString());
+ }
+
+ if (exception != null)
+ {
+ try
+ {
+ var errorBytes = Encoding.UTF8.GetBytes(exception.Message);
+ await context.Response.OutputStream.WriteAsync(errorBytes, 0, errorBytes.Length);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ try
+ {
+ context.Response.Close();
+ }
+ catch (Exception)
+ {
+ }
+
+ }
+
+ async Task ProcessTorznab(HttpListenerContext context)
+ {
+
+ var query = HttpUtility.ParseQueryString(context.Request.Url.Query);
+ var inputStream = context.Request.InputStream;
+
+ var indexerId = context.Request.Url.Segments[2].TrimEnd('/').ToLower();
+ var indexer = indexerManager.GetIndexer(indexerId);
+
+ if (context.Request.Url.Segments.Length > 4 && context.Request.Url.Segments[3] == "download/")
+ {
+ var downloadSegment = HttpServerUtility.UrlTokenDecode(context.Request.Url.Segments[4].TrimEnd('/'));
+ var downloadLink = Encoding.UTF8.GetString(downloadSegment);
+ var downloadBytes = await indexer.Download(new Uri(downloadLink));
+ await context.Response.OutputStream.WriteAsync(downloadBytes, 0, downloadBytes.Length);
+ return;
+ }
+
+ var torznabQuery = TorznabQuery.FromHttpQuery(query);
+
+ if (torznabQuery.RageID != 0)
+ torznabQuery.ShowTitles = await sonarrApi.GetShowTitle(torznabQuery.RageID);
+ else if (!string.IsNullOrEmpty(torznabQuery.SearchTerm))
+ torznabQuery.ShowTitles = new string[] { torznabQuery.SearchTerm };
+
+ var releases = await indexer.PerformQuery(torznabQuery);
+
+ WebServer.LoggerInstance.Debug(string.Format("Found {0} releases from {1}", releases.Length, indexer.DisplayName));
+
+ var severUrl = string.Format("{0}://{1}:{2}/", context.Request.Url.Scheme, context.Request.Url.Host, context.Request.Url.Port);
+
+ var resultPage = new ResultPage(new ChannelInfo
+ {
+ Title = indexer.DisplayName,
+ Description = indexer.DisplayDescription,
+ Link = indexer.SiteLink,
+ ImageUrl = new Uri(severUrl + "logos/" + indexerId + ".png"),
+ ImageTitle = indexer.DisplayName,
+ ImageLink = indexer.SiteLink,
+ ImageDescription = indexer.DisplayName
+ });
+
+ // add Jackett proxy to download links...
+ foreach (var release in releases)
+ {
+ if (release.Link == null || release.Link.Scheme == "magnet")
+ continue;
+ var originalLink = release.Link;
+ var encodedLink = HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(originalLink.ToString())) + "/download.torrent";
+ var proxyLink = string.Format("{0}api/{1}/download/{2}", severUrl, indexerId, encodedLink);
+ release.Link = new Uri(proxyLink);
+ }
+
+ resultPage.Releases.AddRange(releases);
+
+ var xml = resultPage.ToXml(new Uri(severUrl));
+
+ var responseBytes = Encoding.UTF8.GetBytes(xml);
+ context.Response.ContentEncoding = Encoding.UTF8;
+ context.Response.ContentLength64 = responseBytes.LongLength;
+ context.Response.ContentType = "application/rss+xml";
+ await context.Response.OutputStream.WriteAsync(responseBytes, 0, responseBytes.Length);
+
+ }
+
+ public static 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 static Task 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(WebServer.AppConfigDirectory, "config.json");
+
+ private static void SaveSettings(int jacketPort)
+ {
+ JObject json = new JObject();
+ json["port"] = jacketPort;
+ json["public"] = ListenPublic;
+ File.WriteAllText(ServerConfigFile, json.ToString());
+ }
+
+ }*/
+ }
diff --git a/src/Jackett/packages.config b/src/Jackett/packages.config
index efab650c9..a4f77e87c 100644
--- a/src/Jackett/packages.config
+++ b/src/Jackett/packages.config
@@ -1,7 +1,22 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file