From 49a059bdea9e2f71707e0d508cc3cfe38d7c73a1 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 10 May 2011 23:46:26 -0700 Subject: [PATCH] AutoConfigure for SAB is setup, it works for systems with NzbDrone and SABnzbd on the same server only. --- NzbDrone.Core/Model/ConnectionInfoModel.cs | 13 +++ NzbDrone.Core/Model/SabnzbdInfoModel.cs | 5 +- NzbDrone.Core/NzbDrone.Core.csproj | 1 + .../Providers/AutoConfigureProvider.cs | 110 ++++++++++++------ .../Controllers/SettingsController.cs | 14 +-- NzbDrone.Web/NzbDrone.Web.csproj | 2 - NzbDrone.Web/Views/Settings/Downloads.cshtml | 11 +- 7 files changed, 97 insertions(+), 59 deletions(-) create mode 100644 NzbDrone.Core/Model/ConnectionInfoModel.cs diff --git a/NzbDrone.Core/Model/ConnectionInfoModel.cs b/NzbDrone.Core/Model/ConnectionInfoModel.cs new file mode 100644 index 000000000..d193ccc0d --- /dev/null +++ b/NzbDrone.Core/Model/ConnectionInfoModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NzbDrone.Core.Model +{ + public class ConnectionInfoModel + { + public string Address { get; set; } + public int Port { get; set; } + } +} diff --git a/NzbDrone.Core/Model/SabnzbdInfoModel.cs b/NzbDrone.Core/Model/SabnzbdInfoModel.cs index ecfd4c4c2..a903e7626 100644 --- a/NzbDrone.Core/Model/SabnzbdInfoModel.cs +++ b/NzbDrone.Core/Model/SabnzbdInfoModel.cs @@ -7,9 +7,8 @@ namespace NzbDrone.Core.Model { public class SabnzbdInfoModel { - public string ApiKey { get; set; } + public string Host { get; set; } public int Port { get; set; } - public string Username { get; set; } - public string Password { get; set; } + public string ApiKey { get; set; } } } diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 80e069d7b..1e699d4b2 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -166,6 +166,7 @@ + diff --git a/NzbDrone.Core/Providers/AutoConfigureProvider.cs b/NzbDrone.Core/Providers/AutoConfigureProvider.cs index be3d96ecf..8357ba1e7 100644 --- a/NzbDrone.Core/Providers/AutoConfigureProvider.cs +++ b/NzbDrone.Core/Providers/AutoConfigureProvider.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Net; +using System.Net.NetworkInformation; using System.Text; using System.Text.RegularExpressions; using NzbDrone.Core.Model; @@ -10,58 +13,91 @@ namespace NzbDrone.Core.Providers { public class AutoConfigureProvider { - private HttpProvider _httpProvider; - private ConfigProvider _configProvider; - - public AutoConfigureProvider(HttpProvider httpProvider, ConfigProvider configProvider) + public AutoConfigureProvider() { - _httpProvider = httpProvider; - _configProvider = configProvider; } - public SabnzbdInfoModel AutoConfigureSab(string username, string password) + public SabnzbdInfoModel AutoConfigureSab() { - //Get Output from Netstat - var netStatOutput = String.Empty; - //var port = GetSabnzbdPort(netStatOutput); - var port = 2222; - var apiKey = GetSabnzbdApiKey(port); + var info = GetConnectionList(); + return FindApiKey(info); + } - if (port > 0 && !String.IsNullOrEmpty(apiKey)) + private List GetConnectionList() + { + IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); + var info = + ipProperties.GetActiveTcpListeners().Select( + p => + new ConnectionInfoModel + {Address = p.Address.ToString().Replace("0.0.0.0", "127.0.0.1"), Port = p.Port}).Distinct(). + ToList(); + + info.RemoveAll(i => i.Port == 135); + info.RemoveAll(i => i.Port == 139); + info.RemoveAll(i => i.Port == 445); + info.RemoveAll(i => i.Port == 3389); + info.RemoveAll(i => i.Port == 5900); + info.RemoveAll(i => i.Address.Contains("::")); + + info.Reverse(); + + return info; + } + + private SabnzbdInfoModel FindApiKey(List info) + { + foreach (var connection in info) { - return new SabnzbdInfoModel - { - ApiKey = apiKey, - Port = port, - Username = username, - Password = password - }; + var apiKey = GetApiKey(connection.Address, connection.Port); + if (!String.IsNullOrEmpty(apiKey)) + return new SabnzbdInfoModel { + Host = connection.Address, + Port = connection.Port, + ApiKey = apiKey + }; } - return null; } - private int GetSabnzbdPort(string netstatOutput) - { - Regex regex = new Regex(@"^(?:TCP\W+127.0.0.1:(?\d+\W+).+?\r\n\W+\[sabnzbd.exe\])", RegexOptions.IgnoreCase - | RegexOptions.Compiled); - var match = regex.Match(netstatOutput); - var port = 0; - Int32.TryParse(match.Groups["port"].Value, out port); - - return port; - } - - private string GetSabnzbdApiKey(int port, string ipAddress = "127.0.0.1") + private string GetApiKey(string ipAddress, int port) { var request = String.Format("http://{0}:{1}/config/general/", ipAddress, port); - var result = _httpProvider.DownloadString(request); + var result = DownloadString(request); - Regex regex = new Regex("\\\\w+)\\W", RegexOptions.IgnoreCase - | RegexOptions.Compiled); + Regex regex = + new Regex("\\\\w+)\\W", + RegexOptions.IgnoreCase + | RegexOptions.Compiled); var match = regex.Match(result); - return match.Groups["apikey"].Value; + if (match.Success) + { + return match.Groups["apikey"].Value; + } + + return String.Empty; + } + + private string DownloadString(string url) + { + try + { + var request = WebRequest.Create(url); + request.Timeout = 2000; + + var response = request.GetResponse(); + + var reader = new StreamReader(response.GetResponseStream()); + return reader.ReadToEnd(); + } + catch (Exception ex) + { + Console.WriteLine("Failed to get response from: {0}", url); + Console.WriteLine(ex.Message, ex); + } + + return String.Empty; } } } diff --git a/NzbDrone.Web/Controllers/SettingsController.cs b/NzbDrone.Web/Controllers/SettingsController.cs index d7a551f04..06015b008 100644 --- a/NzbDrone.Web/Controllers/SettingsController.cs +++ b/NzbDrone.Web/Controllers/SettingsController.cs @@ -296,26 +296,18 @@ namespace NzbDrone.Web.Controllers return new JsonResult { Data = "ok" }; } - public JsonResult AutoConfigureSab(string username, string password) + public JsonResult AutoConfigureSab() { - SabnzbdInfoModel info; - try { - //info = _autoConfigureProvider.AutoConfigureSab(username, password); - info = new SabnzbdInfoModel - { - ApiKey = "123456", - Port = 2222 - }; + var info = _autoConfigureProvider.AutoConfigureSab(); + return Json(info, JsonRequestBehavior.AllowGet); } catch (Exception) { return new JsonResult { Data = "failed" }; } - - return Json(info); } [HttpPost] diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index 70b56a10d..06adcc1e3 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -599,7 +599,6 @@ - @@ -643,7 +642,6 @@ - diff --git a/NzbDrone.Web/Views/Settings/Downloads.cshtml b/NzbDrone.Web/Views/Settings/Downloads.cshtml index 2bd6c27d8..51aef83d8 100644 --- a/NzbDrone.Web/Views/Settings/Downloads.cshtml +++ b/NzbDrone.Web/Views/Settings/Downloads.cshtml @@ -113,7 +113,7 @@
SABnzbd - @**@ +
@@ -223,9 +223,9 @@ function autoConfigureSab() { $.ajax({ - type: "POST", + type: "GET", url: autoConfigureSabUrl, - data: jQuery.param({ username: $('#SabUsername').val(), password: $('#SabPassword').val() }), + //data: jQuery.param({ username: $('#SabUsername').val(), password: $('#SabPassword').val() }), error: function (req, status, error) { alert("Sorry! We could not autoconfigure SABnzbd for you"); }, @@ -233,10 +233,9 @@ }); function autoConfigureSuccess(data) { - $('#SabApiKey').val(data.ApiKey); + $('#SabHost').val(data.Host); $('#SabPort').val(data.Port); - $('#SabUsername').val(data.Username); - $('#SabPassword').val(data.Password); + $('#SabApiKey').val(data.ApiKey); } } \ No newline at end of file