From 11c49c9260c38b2c61eeee25348e14b9cf66bfe2 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 23 Aug 2013 19:21:12 -0700 Subject: [PATCH 01/58] Using services to get updates now --- NzbDrone.Common/NzbDrone.Common.csproj | 1 + NzbDrone.Common/Serializer/Json.cs | 3 -- NzbDrone.Common/Services.cs | 18 ++++++++ .../Scene/SceneMappingProxyFixture.cs | 8 ---- .../UpdatePackageProviderFixture.cs | 8 +--- NzbDrone.Core/Configuration/ConfigService.cs | 5 --- NzbDrone.Core/Configuration/IConfigService.cs | 1 - .../DailySeries/DailySeriesDataProxy.cs | 8 ++-- .../Scene/SceneMappingProxy.cs | 8 +--- NzbDrone.Core/NzbDrone.Core.csproj | 1 + NzbDrone.Core/Update/UpdateCheckService.cs | 2 +- NzbDrone.Core/Update/UpdatePackage.cs | 11 ++++- .../Update/UpdatePackageAvailable.cs | 13 ++++++ NzbDrone.Core/Update/UpdatePackageProvider.cs | 43 ++++--------------- 14 files changed, 58 insertions(+), 72 deletions(-) create mode 100644 NzbDrone.Common/Services.cs create mode 100644 NzbDrone.Core/Update/UpdatePackageAvailable.cs diff --git a/NzbDrone.Common/NzbDrone.Common.csproj b/NzbDrone.Common/NzbDrone.Common.csproj index 42d7d0903..c1b17236f 100644 --- a/NzbDrone.Common/NzbDrone.Common.csproj +++ b/NzbDrone.Common/NzbDrone.Common.csproj @@ -93,6 +93,7 @@ + diff --git a/NzbDrone.Common/Serializer/Json.cs b/NzbDrone.Common/Serializer/Json.cs index 59c58946a..866776ec9 100644 --- a/NzbDrone.Common/Serializer/Json.cs +++ b/NzbDrone.Common/Serializer/Json.cs @@ -40,7 +40,6 @@ namespace NzbDrone.Common.Serializer return JsonConvert.SerializeObject(obj); } - public static void Serialize(TModel model, TextWriter outputStream) { var jsonTextWriter = new JsonTextWriter(outputStream); @@ -52,7 +51,5 @@ namespace NzbDrone.Common.Serializer { Serialize(model, new StreamWriter(outputStream)); } - - } } \ No newline at end of file diff --git a/NzbDrone.Common/Services.cs b/NzbDrone.Common/Services.cs new file mode 100644 index 000000000..bfa537901 --- /dev/null +++ b/NzbDrone.Common/Services.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NzbDrone.Common +{ + public class Services + { + public static String RootUrl + { + get + { + return "http://services.nzbdrone.com"; + } + } + } +} diff --git a/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs b/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs index 64c5cbc79..98ad8b504 100644 --- a/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs +++ b/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs @@ -15,14 +15,6 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene { private const string SCENE_MAPPING_URL = "http://services.nzbdrone.com/SceneMapping/Active"; - [SetUp] - public void Setup() - { - Mocker.GetMock().SetupGet(s => s.ServiceRootUrl) - .Returns("http://services.nzbdrone.com"); - - } - [Test] public void fetch_should_return_list_of_mappings() { diff --git a/NzbDrone.Core.Test/UpdateTests/UpdatePackageProviderFixture.cs b/NzbDrone.Core.Test/UpdateTests/UpdatePackageProviderFixture.cs index bbf0c5b9c..138e3b404 100644 --- a/NzbDrone.Core.Test/UpdateTests/UpdatePackageProviderFixture.cs +++ b/NzbDrone.Core.Test/UpdateTests/UpdatePackageProviderFixture.cs @@ -16,13 +16,7 @@ namespace NzbDrone.Core.Test.UpdateTests Mocker.GetMock().SetupGet(c => c.Branch).Returns("master"); - var updates = Subject.GetAvailablePackages().ToList(); - - updates.Should().NotBeEmpty(); - updates.Should().OnlyContain(c => !string.IsNullOrWhiteSpace(c.FileName)); - updates.Should().OnlyContain(c => !string.IsNullOrWhiteSpace(c.Url)); - updates.Should().OnlyContain(c => c.Version != null); - updates.Should().OnlyContain(c => c.Version.Major == 2); + Subject.GetLatestUpdate().Should().BeNull(); } } } diff --git a/NzbDrone.Core/Configuration/ConfigService.cs b/NzbDrone.Core/Configuration/ConfigService.cs index 0d9189fc6..e3ca0317b 100644 --- a/NzbDrone.Core/Configuration/ConfigService.cs +++ b/NzbDrone.Core/Configuration/ConfigService.cs @@ -172,11 +172,6 @@ namespace NzbDrone.Core.Configuration set { SetValue("BlackholeFolder", value); } } - public string ServiceRootUrl - { - get { return "http://services.nzbdrone.com"; } - } - public string PneumaticFolder { get { return GetValue("PneumaticFolder", String.Empty); } diff --git a/NzbDrone.Core/Configuration/IConfigService.cs b/NzbDrone.Core/Configuration/IConfigService.cs index 07e70d25b..d84ed272b 100644 --- a/NzbDrone.Core/Configuration/IConfigService.cs +++ b/NzbDrone.Core/Configuration/IConfigService.cs @@ -25,7 +25,6 @@ namespace NzbDrone.Core.Configuration int Retention { get; set; } DownloadClientType DownloadClient { get; set; } string BlackholeFolder { get; set; } - string ServiceRootUrl { get; } string PneumaticFolder { get; set; } string RecycleBin { get; set; } String NzbgetUsername { get; set; } diff --git a/NzbDrone.Core/DataAugmentation/DailySeries/DailySeriesDataProxy.cs b/NzbDrone.Core/DataAugmentation/DailySeries/DailySeriesDataProxy.cs index fc2a591a2..239afecc8 100644 --- a/NzbDrone.Core/DataAugmentation/DailySeries/DailySeriesDataProxy.cs +++ b/NzbDrone.Core/DataAugmentation/DailySeries/DailySeriesDataProxy.cs @@ -17,13 +17,11 @@ namespace NzbDrone.Core.DataAugmentation.DailySeries public class DailySeriesDataProxy : IDailySeriesDataProxy { private readonly IHttpProvider _httpProvider; - private readonly IConfigService _configService; private readonly Logger _logger; - public DailySeriesDataProxy(IHttpProvider httpProvider, IConfigService configService, Logger logger) + public DailySeriesDataProxy(IHttpProvider httpProvider, Logger logger) { _httpProvider = httpProvider; - _configService = configService; _logger = logger; } @@ -31,7 +29,7 @@ namespace NzbDrone.Core.DataAugmentation.DailySeries { try { - var dailySeriesIds = _httpProvider.DownloadString(_configService.ServiceRootUrl + "/DailySeries/AllIds"); + var dailySeriesIds = _httpProvider.DownloadString(Services.RootUrl + "/DailySeries/AllIds"); var seriesIds = Json.Deserialize>(dailySeriesIds); @@ -49,7 +47,7 @@ namespace NzbDrone.Core.DataAugmentation.DailySeries { try { - var result = _httpProvider.DownloadString(_configService.ServiceRootUrl + "/DailySeries/Check?seriesId=" + tvdbid); + var result = _httpProvider.DownloadString(Services.RootUrl + "/DailySeries/Check?seriesId=" + tvdbid); return Convert.ToBoolean(result); } catch (Exception ex) diff --git a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingProxy.cs b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingProxy.cs index c38cb4a58..2447a96ec 100644 --- a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingProxy.cs +++ b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingProxy.cs @@ -13,19 +13,15 @@ namespace NzbDrone.Core.DataAugmentation.Scene public class SceneMappingProxy : ISceneMappingProxy { private readonly IHttpProvider _httpProvider; - private readonly IConfigService _configService; - - public SceneMappingProxy(IHttpProvider httpProvider, IConfigService configService) + public SceneMappingProxy(IHttpProvider httpProvider) { _httpProvider = httpProvider; - _configService = configService; - } public List Fetch() { - var mappingsJson = _httpProvider.DownloadString(_configService.ServiceRootUrl + "/SceneMapping/Active"); + var mappingsJson = _httpProvider.DownloadString(Services.RootUrl + "/SceneMapping/Active"); return Json.Deserialize>(mappingsJson); } } diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 7adf989f7..9234720af 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -492,6 +492,7 @@ + diff --git a/NzbDrone.Core/Update/UpdateCheckService.cs b/NzbDrone.Core/Update/UpdateCheckService.cs index 36d43ea44..313f1ef58 100644 --- a/NzbDrone.Core/Update/UpdateCheckService.cs +++ b/NzbDrone.Core/Update/UpdateCheckService.cs @@ -26,7 +26,7 @@ namespace NzbDrone.Core.Update { var latestAvailable = _updatePackageProvider.GetLatestUpdate(); - if (latestAvailable == null || latestAvailable.Version <= BuildInfo.Version) + if (latestAvailable == null) { _logger.Debug("No update available."); return null; diff --git a/NzbDrone.Core/Update/UpdatePackage.cs b/NzbDrone.Core/Update/UpdatePackage.cs index e600e2a83..ce038ac99 100644 --- a/NzbDrone.Core/Update/UpdatePackage.cs +++ b/NzbDrone.Core/Update/UpdatePackage.cs @@ -1,11 +1,18 @@ using System; +using Newtonsoft.Json; namespace NzbDrone.Core.Update { public class UpdatePackage { - public string Url { get; set; } - public string FileName { get; set; } + public String Id { get; set; } + + [JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))] public Version Version { get; set; } + + public String Branch { get; set; } + public DateTime ReleaseDate { get; set; } + public String FileName { get; set; } + public String Url { get; set; } } } diff --git a/NzbDrone.Core/Update/UpdatePackageAvailable.cs b/NzbDrone.Core/Update/UpdatePackageAvailable.cs new file mode 100644 index 000000000..1d76e22d7 --- /dev/null +++ b/NzbDrone.Core/Update/UpdatePackageAvailable.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NzbDrone.Core.Update +{ + public class UpdatePackageAvailable + { + public Boolean Available { get; set; } + public UpdatePackage UpdatePackage { get; set; } + } +} diff --git a/NzbDrone.Core/Update/UpdatePackageProvider.cs b/NzbDrone.Core/Update/UpdatePackageProvider.cs index f85dc6e66..2456b5511 100644 --- a/NzbDrone.Core/Update/UpdatePackageProvider.cs +++ b/NzbDrone.Core/Update/UpdatePackageProvider.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using Newtonsoft.Json; using NLog; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; @@ -11,56 +12,30 @@ namespace NzbDrone.Core.Update { public interface IUpdatePackageProvider { - IEnumerable GetAvailablePackages(); UpdatePackage GetLatestUpdate(); } public class UpdatePackageProvider : IUpdatePackageProvider { - private readonly IConfigFileProvider _configService; + private readonly IConfigFileProvider _configFileProvider; private readonly IHttpProvider _httpProvider; private readonly Logger _logger; - private static readonly Regex ParseRegex = new Regex(@"(?:\>)(?NzbDrone.+?(?(?<=\.)\d+\.\d+\.\d+\.\d+).+?)(?:\<\/a\>)", - RegexOptions.IgnoreCase); - - public UpdatePackageProvider(IConfigFileProvider configService, IHttpProvider httpProvider, Logger logger) + public UpdatePackageProvider(IConfigFileProvider configFileProvider, IHttpProvider httpProvider, Logger logger) { - _configService = configService; + _configFileProvider = configFileProvider; _httpProvider = httpProvider; _logger = logger; } - public IEnumerable GetAvailablePackages() + public UpdatePackage GetLatestUpdate() { - var updateList = new List(); - - var branch = _configService.Branch; - var version = BuildInfo.Version; - var updateUrl = String.Format("http://update.nzbdrone.com/v{0}/{1}/", version.Major, branch); - - _logger.Debug("Getting a list of updates from {0}", updateUrl); - - var rawUpdateList = _httpProvider.DownloadString(updateUrl); - var matches = ParseRegex.Matches(rawUpdateList); + var url = String.Format("{0}/v1/update/{1}?{2}", Services.RootUrl, _configFileProvider.Branch, BuildInfo.Version); + var update = JsonConvert.DeserializeObject(_httpProvider.DownloadString(url)); - foreach (Match match in matches) - { - var updatePackage = new UpdatePackage(); - updatePackage.FileName = match.Groups["filename"].Value; - updatePackage.Url = updateUrl + updatePackage.FileName; - updatePackage.Version = new Version(match.Groups["version"].Value); - updateList.Add(updatePackage); - } + if (!update.Available) return null; - _logger.Debug("Found {0} update packages", updateUrl.Length); - - return updateList; - } - - public UpdatePackage GetLatestUpdate() - { - return GetAvailablePackages().OrderByDescending(c => c.Version).FirstOrDefault(); + return update.UpdatePackage; } } } \ No newline at end of file From c6bbc52631cf807682fa74362310005fb8582630 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 23 Aug 2013 19:42:45 -0700 Subject: [PATCH 02/58] Fixed UpdateResource --- NzbDrone.Api/Update/UpdateModule.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NzbDrone.Api/Update/UpdateModule.cs b/NzbDrone.Api/Update/UpdateModule.cs index 6fdb1ca50..8a95efa4b 100644 --- a/NzbDrone.Api/Update/UpdateModule.cs +++ b/NzbDrone.Api/Update/UpdateModule.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Newtonsoft.Json; using NzbDrone.Api.REST; using NzbDrone.Core.Update; using NzbDrone.Api.Mapping; @@ -32,7 +33,13 @@ namespace NzbDrone.Api.Update public class UpdateResource : RestResource { + public String Id { get; set; } + + [JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))] public Version Version { get; set; } + + public String Branch { get; set; } + public DateTime ReleaseDate { get; set; } public String FileName { get; set; } public String Url { get; set; } } From eefe44caa50b9ffb83b4f0e67a3e479316023204 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 23 Aug 2013 19:45:59 -0700 Subject: [PATCH 03/58] added version to query string --- NzbDrone.Core/Update/UpdatePackageProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NzbDrone.Core/Update/UpdatePackageProvider.cs b/NzbDrone.Core/Update/UpdatePackageProvider.cs index 2456b5511..e045a89fd 100644 --- a/NzbDrone.Core/Update/UpdatePackageProvider.cs +++ b/NzbDrone.Core/Update/UpdatePackageProvider.cs @@ -30,7 +30,7 @@ namespace NzbDrone.Core.Update public UpdatePackage GetLatestUpdate() { - var url = String.Format("{0}/v1/update/{1}?{2}", Services.RootUrl, _configFileProvider.Branch, BuildInfo.Version); + var url = String.Format("{0}/v1/update/{1}?version={2}", Services.RootUrl, _configFileProvider.Branch, BuildInfo.Version); var update = JsonConvert.DeserializeObject(_httpProvider.DownloadString(url)); if (!update.Available) return null; From 2a11d6bf31a0954fb5cab3d513a9662a3743381b Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 26 Aug 2013 13:05:13 -0700 Subject: [PATCH 04/58] Cache list of Xem Mapped series at start and recache every 12 hours --- NzbDrone.Core/Providers/XemProvider.cs | 46 +++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/NzbDrone.Core/Providers/XemProvider.cs b/NzbDrone.Core/Providers/XemProvider.cs index 0881f4edc..931793dfb 100644 --- a/NzbDrone.Core/Providers/XemProvider.cs +++ b/NzbDrone.Core/Providers/XemProvider.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Linq; using NLog; +using NzbDrone.Common.Cache; using NzbDrone.Common.Messaging; +using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Tv; using NzbDrone.Core.Tv.Events; @@ -12,31 +14,37 @@ namespace NzbDrone.Core.Providers { void UpdateMappings(); void UpdateMappings(int seriesId); + void UpdateMappings(Series series); void PerformUpdate(Series series); } - public class XemProvider : IXemProvider, IExecute, IHandle + public class XemProvider : IXemProvider, IExecute, IHandle, IHandleAsync { private readonly IEpisodeService _episodeService; private readonly IXemCommunicationProvider _xemCommunicationProvider; private readonly ISeriesService _seriesService; + private readonly ICached _cache; private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); - public XemProvider(IEpisodeService episodeService, IXemCommunicationProvider xemCommunicationProvider, ISeriesService seriesService) + public XemProvider(IEpisodeService episodeService, + IXemCommunicationProvider xemCommunicationProvider, + ISeriesService seriesService, ICacheManger cacheManger) { if (seriesService == null) throw new ArgumentNullException("seriesService"); _episodeService = episodeService; _xemCommunicationProvider = xemCommunicationProvider; _seriesService = seriesService; + _cache = cacheManger.GetCache(GetType()); } public void UpdateMappings() { _logger.Trace("Starting scene numbering update"); + try { - var ids = _xemCommunicationProvider.GetXemSeriesIds(); + var ids = GetXemSeriesIds(); var series = _seriesService.GetAllSeries(); var wantedSeries = series.Where(s => ids.Contains(s.TvdbId)).ToList(); @@ -64,12 +72,15 @@ namespace NzbDrone.Core.Providers _logger.Trace("Series could not be found: {0}", seriesId); return; } + + UpdateMappings(series); + } - var xemIds = _xemCommunicationProvider.GetXemSeriesIds(); - - if (!xemIds.Contains(series.TvdbId)) + public void UpdateMappings(Series series) + { + if (!_cache.Find(series.TvdbId.ToString())) { - _logger.Trace("Xem doesn't have a mapping for this series: {0}", series.TvdbId); + _logger.Trace("Scene numbering is not available for {0} [{1}]", series.Title, series.TvdbId); return; } @@ -125,6 +136,20 @@ namespace NzbDrone.Core.Providers } } + private List GetXemSeriesIds() + { + _cache.Clear(); + + var ids = _xemCommunicationProvider.GetXemSeriesIds(); + + foreach (var id in ids) + { + _cache.Set(id.ToString(), true); + } + + return ids; + } + public void Execute(UpdateXemMappingsCommand message) { if (message.SeriesId.HasValue) @@ -139,7 +164,12 @@ namespace NzbDrone.Core.Providers public void Handle(SeriesUpdatedEvent message) { - PerformUpdate(message.Series); + UpdateMappings(message.Series); + } + + public void HandleAsync(ApplicationStartedEvent message) + { + GetXemSeriesIds(); } } } From 6bea671a1a041858eeb27a610c4c7e31155ec3a2 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 26 Aug 2013 20:20:03 -0700 Subject: [PATCH 05/58] Episode and Season monitored toggling works again --- NzbDrone.Api/Episodes/EpisodeModule.cs | 7 ++ NzbDrone.Api/Seasons/SeasonModule.cs | 7 ++ NzbDrone.Core/Tv/SeasonService.cs | Bin 8428 -> 8572 bytes .../Client/ClientBase.cs | 16 ++++- .../Client/EpisodeClient.cs | 22 +++++++ .../Client/SeasonClient.cs | 22 +++++++ .../EpisodeIntegrationTests.cs | 60 ++++++++++++++++++ NzbDrone.Integration.Test/IntegrationTest.cs | 5 ++ .../NzbDrone.Integration.Test.csproj | 4 ++ .../SeasonIntegrationTests.cs | 60 ++++++++++++++++++ 10 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 NzbDrone.Integration.Test/Client/EpisodeClient.cs create mode 100644 NzbDrone.Integration.Test/Client/SeasonClient.cs create mode 100644 NzbDrone.Integration.Test/EpisodeIntegrationTests.cs create mode 100644 NzbDrone.Integration.Test/SeasonIntegrationTests.cs diff --git a/NzbDrone.Api/Episodes/EpisodeModule.cs b/NzbDrone.Api/Episodes/EpisodeModule.cs index 94874f57a..3d6684d19 100644 --- a/NzbDrone.Api/Episodes/EpisodeModule.cs +++ b/NzbDrone.Api/Episodes/EpisodeModule.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using NzbDrone.Api.Mapping; using NzbDrone.Api.REST; using NzbDrone.Core.Tv; @@ -15,6 +16,7 @@ namespace NzbDrone.Api.Episodes GetResourceAll = GetEpisodes; UpdateResource = SetMonitored; + GetResourceById = GetEpisode; } private List GetEpisodes() @@ -33,5 +35,10 @@ namespace NzbDrone.Api.Episodes { _episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored); } + + private EpisodeResource GetEpisode(int id) + { + return _episodeService.GetEpisode(id).InjectTo(); + } } } \ No newline at end of file diff --git a/NzbDrone.Api/Seasons/SeasonModule.cs b/NzbDrone.Api/Seasons/SeasonModule.cs index 8c6bf7d8b..0521b8518 100644 --- a/NzbDrone.Api/Seasons/SeasonModule.cs +++ b/NzbDrone.Api/Seasons/SeasonModule.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using NzbDrone.Api.Mapping; using NzbDrone.Core.Tv; namespace NzbDrone.Api.Seasons @@ -13,6 +14,7 @@ namespace NzbDrone.Api.Seasons _seasonService = seasonService; GetResourceAll = GetSeasons; + GetResourceById = GetSeason; UpdateResource = Update; Post["/pass"] = x => SetSeasonPass(); @@ -30,6 +32,11 @@ namespace NzbDrone.Api.Seasons return ToListResource(() => _seasonService.GetAllSeasons()); } + private SeasonResource GetSeason(int id) + { + return _seasonService.Get(id).InjectTo(); + } + private void Update(SeasonResource seasonResource) { _seasonService.SetMonitored(seasonResource.SeriesId, seasonResource.SeasonNumber, seasonResource.Monitored); diff --git a/NzbDrone.Core/Tv/SeasonService.cs b/NzbDrone.Core/Tv/SeasonService.cs index de0c4013de8646ad2eb640d4dfc6fca885572538..8cb3d0c75795638537f01c86fdb483b545701f5e 100644 GIT binary patch delta 108 zcmaFk_{WLAv^X;_T_L!#xFj{#nwM+CZ$?oCAP7!PEY8nUa8E7K$jmEI$V}P%nX!av t@&z7|&9y8^9D*3~lk0hm*}%$ECOhz&Z~n%k&B|E2*-&UV-(&|NZU8dtB+mc< delta 46 zcmV+}0MY;aLhM1Y5BmYLCjx8&lj98*v!?`N2$S>;7qf~DD+L7&3JnT(request); } + public TResource Put(TResource body) + { + var request = BuildRequest(); + request.AddBody(body); + return Put(request); + } + public TResource Get(int id, HttpStatusCode statusCode = HttpStatusCode.OK) { var request = BuildRequest(id.ToString()); return Get(request, statusCode); } - public void Delete(int id) { var request = BuildRequest(id.ToString()); @@ -82,6 +88,12 @@ namespace NzbDrone.Integration.Test.Client return Execute(request, statusCode); } + public T Put(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.Accepted) where T : class, new() + { + request.Method = Method.PUT; + return Execute(request, statusCode); + } + public void Delete(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.OK) { request.Method = Method.DELETE; @@ -109,13 +121,11 @@ namespace NzbDrone.Integration.Test.Client return Json.Deserialize(response.Content); } - private static void AssertDisableCache(IList headers) { headers.Single(c => c.Name == "Cache-Control").Value.Should().Be("no-cache, no-store, must-revalidate"); headers.Single(c => c.Name == "Pragma").Value.Should().Be("no-cache"); headers.Single(c => c.Name == "Expires").Value.Should().Be("0"); } - } } \ No newline at end of file diff --git a/NzbDrone.Integration.Test/Client/EpisodeClient.cs b/NzbDrone.Integration.Test/Client/EpisodeClient.cs new file mode 100644 index 000000000..675c38bd8 --- /dev/null +++ b/NzbDrone.Integration.Test/Client/EpisodeClient.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Net; +using NzbDrone.Api.Episodes; +using NzbDrone.Api.Series; +using RestSharp; + +namespace NzbDrone.Integration.Test.Client +{ + public class EpisodeClient : ClientBase + { + public EpisodeClient(IRestClient restClient) + : base(restClient, "episodes") + { + } + + public List GetEpisodesInSeries(int seriesId) + { + var request = BuildRequest("?seriesId=" + seriesId.ToString()); + return Get>(request); + } + } +} diff --git a/NzbDrone.Integration.Test/Client/SeasonClient.cs b/NzbDrone.Integration.Test/Client/SeasonClient.cs new file mode 100644 index 000000000..af0572a70 --- /dev/null +++ b/NzbDrone.Integration.Test/Client/SeasonClient.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Net; +using NzbDrone.Api.Episodes; +using NzbDrone.Api.Seasons; +using RestSharp; + +namespace NzbDrone.Integration.Test.Client +{ + public class SeasonClient : ClientBase + { + public SeasonClient(IRestClient restClient) + : base(restClient) + { + } + + public List GetSeasonsInSeries(int seriesId) + { + var request = BuildRequest("?seriesId=" + seriesId.ToString()); + return Get>(request); + } + } +} diff --git a/NzbDrone.Integration.Test/EpisodeIntegrationTests.cs b/NzbDrone.Integration.Test/EpisodeIntegrationTests.cs new file mode 100644 index 000000000..411023cac --- /dev/null +++ b/NzbDrone.Integration.Test/EpisodeIntegrationTests.cs @@ -0,0 +1,60 @@ +using System; +using System.Threading; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Api.Series; +using System.Linq; + +namespace NzbDrone.Integration.Test +{ + [TestFixture] + public class EpisodeIntegrationTests : IntegrationTest + { + private SeriesResource GivenSeriesWithEpisodes() + { + var series = Series.Lookup("archer").First(); + + series.QualityProfileId = 1; + series.Path = @"C:\Test\Archer"; + + series = Series.Post(series); + + while (true) + { + if (Episodes.GetEpisodesInSeries(series.Id).Count > 0) + { + return series; + } + + Thread.Sleep(1000); + } + } + + [Test] + public void should_be_able_to_get_all_episodes_in_series() + { + var series = GivenSeriesWithEpisodes(); + Episodes.GetEpisodesInSeries(series.Id).Count.Should().BeGreaterThan(0); + } + + [Test] + public void should_be_able_to_get_a_single_episode() + { + var series = GivenSeriesWithEpisodes(); + var episodes = Episodes.GetEpisodesInSeries(series.Id); + + Episodes.Get(episodes.First().Id).Should().NotBeNull(); + } + + [Test] + public void should_be_able_to_set_monitor_status_via_api() + { + var series = GivenSeriesWithEpisodes(); + var episodes = Episodes.GetEpisodesInSeries(series.Id); + var updatedEpisode = episodes.First(); + updatedEpisode.Monitored = false; + + Episodes.Put(updatedEpisode).Monitored.Should().BeFalse(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Integration.Test/IntegrationTest.cs b/NzbDrone.Integration.Test/IntegrationTest.cs index 313e58f5b..b705146b6 100644 --- a/NzbDrone.Integration.Test/IntegrationTest.cs +++ b/NzbDrone.Integration.Test/IntegrationTest.cs @@ -3,6 +3,7 @@ using NLog.Config; using NLog.Targets; using NUnit.Framework; using NzbDrone.Api.Commands; +using NzbDrone.Api.Episodes; using NzbDrone.Api.RootFolders; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Integration.Test.Client; @@ -22,6 +23,8 @@ namespace NzbDrone.Integration.Test protected ClientBase Commands; protected ReleaseClient Releases; protected IndexerClient Indexers; + protected EpisodeClient Episodes; + protected SeasonClient Seasons; private NzbDroneRunner _runner; @@ -57,6 +60,8 @@ namespace NzbDrone.Integration.Test RootFolders = new ClientBase(RestClient); Commands = new ClientBase(RestClient); Indexers = new IndexerClient(RestClient); + Episodes = new EpisodeClient(RestClient); + Seasons = new SeasonClient(RestClient); } [TearDown] diff --git a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj index a3d18d2b5..04ce2753c 100644 --- a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj +++ b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj @@ -93,10 +93,14 @@ + + + + diff --git a/NzbDrone.Integration.Test/SeasonIntegrationTests.cs b/NzbDrone.Integration.Test/SeasonIntegrationTests.cs new file mode 100644 index 000000000..c10146030 --- /dev/null +++ b/NzbDrone.Integration.Test/SeasonIntegrationTests.cs @@ -0,0 +1,60 @@ +using System; +using System.Threading; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Api.Series; +using System.Linq; + +namespace NzbDrone.Integration.Test +{ + [TestFixture] + public class SeasonIntegrationTests : IntegrationTest + { + private SeriesResource GivenSeriesWithEpisodes() + { + var series = Series.Lookup("archer").First(); + + series.QualityProfileId = 1; + series.Path = @"C:\Test\Archer"; + + series = Series.Post(series); + + while (true) + { + if (Seasons.GetSeasonsInSeries(series.Id).Count > 0) + { + return series; + } + + Thread.Sleep(1000); + } + } + + [Test] + public void should_be_able_to_get_all_seasons_in_series() + { + var series = GivenSeriesWithEpisodes(); + Seasons.GetSeasonsInSeries(series.Id).Count.Should().BeGreaterThan(0); + } + + [Test] + public void should_be_able_to_get_a_single_season() + { + var series = GivenSeriesWithEpisodes(); + var seasons = Seasons.GetSeasonsInSeries(series.Id); + + Seasons.Get(seasons.First().Id).Should().NotBeNull(); + } + + [Test] + public void should_be_able_to_set_monitor_status_via_api() + { + var series = GivenSeriesWithEpisodes(); + var seasons = Seasons.GetSeasonsInSeries(series.Id); + var updatedSeason = seasons.First(); + updatedSeason.Monitored = false; + + Seasons.Put(updatedSeason).Monitored.Should().BeFalse(); + } + } +} \ No newline at end of file From 0d4fc5513a6dcdbc1b9a458dd1aeb6c2995fa2b6 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 26 Aug 2013 22:16:22 -0700 Subject: [PATCH 06/58] Using OsAgnostic paths for episode/season integration tests --- NzbDrone.Integration.Test/EpisodeIntegrationTests.cs | 3 ++- NzbDrone.Integration.Test/SeasonIntegrationTests.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NzbDrone.Integration.Test/EpisodeIntegrationTests.cs b/NzbDrone.Integration.Test/EpisodeIntegrationTests.cs index 411023cac..d0f74844d 100644 --- a/NzbDrone.Integration.Test/EpisodeIntegrationTests.cs +++ b/NzbDrone.Integration.Test/EpisodeIntegrationTests.cs @@ -4,6 +4,7 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Api.Series; using System.Linq; +using NzbDrone.Test.Common; namespace NzbDrone.Integration.Test { @@ -15,7 +16,7 @@ namespace NzbDrone.Integration.Test var series = Series.Lookup("archer").First(); series.QualityProfileId = 1; - series.Path = @"C:\Test\Archer"; + series.Path = @"C:\Test\Archer".AsOsAgnostic(); series = Series.Post(series); diff --git a/NzbDrone.Integration.Test/SeasonIntegrationTests.cs b/NzbDrone.Integration.Test/SeasonIntegrationTests.cs index c10146030..9fa6177f3 100644 --- a/NzbDrone.Integration.Test/SeasonIntegrationTests.cs +++ b/NzbDrone.Integration.Test/SeasonIntegrationTests.cs @@ -4,6 +4,7 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Api.Series; using System.Linq; +using NzbDrone.Test.Common; namespace NzbDrone.Integration.Test { @@ -15,7 +16,7 @@ namespace NzbDrone.Integration.Test var series = Series.Lookup("archer").First(); series.QualityProfileId = 1; - series.Path = @"C:\Test\Archer"; + series.Path = @"C:\Test\Archer".AsOsAgnostic(); series = Series.Post(series); From dcb1b76917a72f934c03c968c3e84bdae8277cfd Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 26 Aug 2013 22:20:08 -0700 Subject: [PATCH 07/58] Added spaces so the split works --- NzbDrone.Core/MediaFiles/DiskScanService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NzbDrone.Core/MediaFiles/DiskScanService.cs b/NzbDrone.Core/MediaFiles/DiskScanService.cs index 17d7e6dc2..0fb6901fe 100644 --- a/NzbDrone.Core/MediaFiles/DiskScanService.cs +++ b/NzbDrone.Core/MediaFiles/DiskScanService.cs @@ -24,9 +24,9 @@ namespace NzbDrone.Core.MediaFiles private const string EXTENSIONS = //XBMC - ".m4v .3gp .nsv .ts .ty .strm .rm .rmvb .m3u .ifo .mov .qt .divx .xvid .bivx .vob .nrg .img" + + ".m4v .3gp .nsv .ts .ty .strm .rm .rmvb .m3u .ifo .mov .qt .divx .xvid .bivx .vob .nrg .img " + ".iso .pva .wmv .asf .asx .ogm .m2v .avi .bin .dat .dvr-ms .mpg .mpeg .mp4 .mkv .avc .vp3 " + - ".svq3 .nuv .viv .dv .fli .flv .wpl" + + ".svq3 .nuv .viv .dv .fli .flv .wpl " + //Other ".m2ts"; From 3c732f5a5e847f6c4b7ca76e645e9e6445ab2cbf Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 27 Aug 2013 07:08:00 -0700 Subject: [PATCH 08/58] 1080p releases without x264 or hdtv markers will be treated as HDTV instead of unknown --- NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs | 3 ++- NzbDrone.Core/Parser/Parser.cs | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs b/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs index 7f433c41e..e2704d186 100644 --- a/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs +++ b/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs @@ -79,7 +79,8 @@ namespace NzbDrone.Core.Test.ParserTests new object[] { "How I Met Your Mother S01E18 Nothing Good Happens After 2 A.M. 720p HDTV DD5.1 MPEG2-TrollHD", Quality.RAWHD, false }, new object[] { "Arrested.Development.S04E01.iNTERNAL.1080p.WEBRip.x264-QRUS", Quality.WEBDL1080p, false }, new object[] { "Arrested.Development.S04E01.720p.WEBRip.AAC2.0.x264-NFRiP", Quality.WEBDL720p, false }, - new object[] { "Sons.Of.Anarchy.S02E13.1080p.BluRay.x264-AVCDVD", Quality.Bluray1080p, false } + new object[] { "Sons.Of.Anarchy.S02E13.1080p.BluRay.x264-AVCDVD", Quality.Bluray1080p, false }, + new object[] { "Under the Dome S01E10 Let the Games Begin 1080p", Quality.HDTV1080p, false } }; public static object[] SelfQualityParserCases = diff --git a/NzbDrone.Core/Parser/Parser.cs b/NzbDrone.Core/Parser/Parser.cs index 2f88fe81e..15110894b 100644 --- a/NzbDrone.Core/Parser/Parser.cs +++ b/NzbDrone.Core/Parser/Parser.cs @@ -386,6 +386,12 @@ namespace NzbDrone.Core.Parser return result; } + if (normalizedName.Contains("1080p")) + { + result.Quality = Quality.HDTV1080p; + return result; + } + return result; } From e7b329a618fd0b673042567433de594ee103dce0 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 27 Aug 2013 07:22:14 -0700 Subject: [PATCH 09/58] favicon.ico is now served properly --- NzbDrone.Api/Frontend/Mappers/StaticResourceMapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NzbDrone.Api/Frontend/Mappers/StaticResourceMapper.cs b/NzbDrone.Api/Frontend/Mappers/StaticResourceMapper.cs index b97f63943..da9fac532 100644 --- a/NzbDrone.Api/Frontend/Mappers/StaticResourceMapper.cs +++ b/NzbDrone.Api/Frontend/Mappers/StaticResourceMapper.cs @@ -25,7 +25,7 @@ namespace NzbDrone.Api.Frontend.Mappers public override bool CanHandle(string resourceUrl) { - return resourceUrl.StartsWith("/Content") || resourceUrl.EndsWith(".js") || resourceUrl.EndsWith(".css"); + return resourceUrl.StartsWith("/Content") || resourceUrl.EndsWith(".js") || resourceUrl.EndsWith(".css") || resourceUrl.EndsWith(".ico"); } } } \ No newline at end of file From 0d6b9969d25f8748b840132d4dd63d623be45dc2 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 27 Aug 2013 12:13:11 -0700 Subject: [PATCH 10/58] FilterExistingFiles no longer converts paths to all lower case --- NzbDrone.Common/PathEqualityComparer.cs | 8 +++- .../MediaFileTests/MediaFileServiceTest.cs | 44 +++++++++++++++++-- NzbDrone.Core/MediaFiles/MediaFileService.cs | 4 +- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/NzbDrone.Common/PathEqualityComparer.cs b/NzbDrone.Common/PathEqualityComparer.cs index c70abb7b7..2bf854727 100644 --- a/NzbDrone.Common/PathEqualityComparer.cs +++ b/NzbDrone.Common/PathEqualityComparer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using NzbDrone.Common.EnvironmentInfo; namespace NzbDrone.Common { @@ -14,7 +15,12 @@ namespace NzbDrone.Common public int GetHashCode(string obj) { - return obj.CleanFilePath().GetHashCode(); + if (OsInfo.IsLinux) + { + return obj.CleanFilePath().GetHashCode(); + } + + return obj.CleanFilePath().ToLower().GetHashCode(); } } } diff --git a/NzbDrone.Core.Test/MediaFileTests/MediaFileServiceTest.cs b/NzbDrone.Core.Test/MediaFileTests/MediaFileServiceTest.cs index c97082e3d..1e1060239 100644 --- a/NzbDrone.Core.Test/MediaFileTests/MediaFileServiceTest.cs +++ b/NzbDrone.Core.Test/MediaFileTests/MediaFileServiceTest.cs @@ -81,12 +81,11 @@ namespace NzbDrone.Core.Test.MediaFileTests Subject.FilterExistingFiles(files, 10).Should().NotContain("c:\\file2.avi".AsOsAgnostic()); } - - - [Test] public void filter_should_return_none_existing_files_ignoring_case() { + WindowsOnly(); + var files = new List() { "c:\\file1.avi".AsOsAgnostic(), @@ -105,5 +104,44 @@ namespace NzbDrone.Core.Test.MediaFileTests Subject.FilterExistingFiles(files, 10).Should().HaveCount(2); Subject.FilterExistingFiles(files, 10).Should().NotContain("c:\\file2.avi".AsOsAgnostic()); } + + [Test] + public void filter_should_return_none_existing_files_not_ignoring_case() + { + LinuxOnly(); + + var files = new List() + { + "c:\\file1.avi".AsOsAgnostic(), + "c:\\FILE2.avi".AsOsAgnostic(), + "c:\\file3.avi".AsOsAgnostic() + }; + + Mocker.GetMock() + .Setup(c => c.GetFilesBySeries(It.IsAny())) + .Returns(new List + { + new EpisodeFile{Path = "c:\\file2.avi".AsOsAgnostic()} + }); + + Subject.FilterExistingFiles(files, 10).Should().HaveCount(3); + } + + [Test] + public void filter_should_not_change_casing() + { + var files = new List() + { + "c:\\FILE1.avi".AsOsAgnostic() + }; + + Mocker.GetMock() + .Setup(c => c.GetFilesBySeries(It.IsAny())) + .Returns(new List()); + + Subject.FilterExistingFiles(files, 10).Should().HaveCount(1); + Subject.FilterExistingFiles(files, 10).Should().NotContain(files.First().ToLower()); + Subject.FilterExistingFiles(files, 10).Should().Contain(files.First()); + } } } \ No newline at end of file diff --git a/NzbDrone.Core/MediaFiles/MediaFileService.cs b/NzbDrone.Core/MediaFiles/MediaFileService.cs index a2fe8ba22..54501c859 100644 --- a/NzbDrone.Core/MediaFiles/MediaFileService.cs +++ b/NzbDrone.Core/MediaFiles/MediaFileService.cs @@ -76,11 +76,11 @@ namespace NzbDrone.Core.MediaFiles public List FilterExistingFiles(List files, int seriesId) { - var seriesFiles = GetFilesBySeries(seriesId).Select(f => f.Path.CleanFilePath().ToLower()).ToList(); + var seriesFiles = GetFilesBySeries(seriesId).Select(f => f.Path.CleanFilePath()).ToList(); if (!seriesFiles.Any()) return files; - return files.Select(f => f.CleanFilePath().ToLower()).Except(seriesFiles).ToList(); + return files.Select(f => f.CleanFilePath()).Except(seriesFiles, new PathEqualityComparer()).ToList(); } public EpisodeFile Get(int id) From 8cb8345c3bcf6d9d4ee1d956d154f0b01b8bbf21 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Tue, 27 Aug 2013 14:31:45 -0700 Subject: [PATCH 11/58] updated deb package files --- debian/changelog | 10 +++++----- debian/control | 14 ++++++-------- debian/copyright | 50 ++++++++++++++++++++++++------------------------ debian/install | 3 +-- debian/rules | 2 +- 5 files changed, 38 insertions(+), 41 deletions(-) mode change 100644 => 100755 debian/copyright mode change 100644 => 100755 debian/install mode change 100644 => 100755 debian/rules diff --git a/debian/changelog b/debian/changelog index e15e9a293..d19fb36d6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ - nzbdrone (2.0.12-1) unstable; urgency=low -2 -3 * Initial release -4 -5 -- kay.one Mon, 22 Mar 2010 00:37:31 +0100 \ No newline at end of file +nzbdrone (2.0.0.0) UNRELEASED; urgency=low + + * Initial release. (Closes: #XXXXXX) + + -- Keivan Mon, 26 Aug 2013 17:31:17 -0700 diff --git a/debian/control b/debian/control index 174fecb48..55fdd31fe 100644 --- a/debian/control +++ b/debian/control @@ -1,14 +1,12 @@ -Package: nzbdrone -Standards-Version: 2.0.0.226 -Architecture: all -Maintainer: Keivan Beigi -Depends: mono-runtime (>= 2.10.1) +Source: nzbdrone Section: web Priority: optional - +Maintainer: Keivan Beigi +Depends: libmono-cil-dev (>= 2.10.1) Homepage: http://www.nzbdrone.com Vcs-Git: git@github.com:NzbDrone/NzbDrone.git Vcs-Browser: https://github.com/NzbDrone/NzbDrone -Description: NZBDrone is a PVR for newsgroup users. -It can monitor multiple RSS feeds for new episodes of your favourite shows and will grab, sorts and renames them. It can also be configured to automatically upgrade the quality of files already downloaded if a better quality format becomes available. \ No newline at end of file +Package: nzbdrone +Architecture: all +Description: NZBDrone is a PVR for newsgroup users diff --git a/debian/copyright b/debian/copyright old mode 100644 new mode 100755 index 28e595dc8..754e0d639 --- a/debian/copyright +++ b/debian/copyright @@ -1,25 +1,25 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: nzbdrone -Source: https://github.com/NzbDrone/NzbDrone - -Files: * -Copyright: 2010-2013 Keivan Beigi - 2010-2013 Mark McDowall - -License: GPL-3.0+ - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see . - . - On Debian systems, the complete text of the GNU General - Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". \ No newline at end of file +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: nzbdrone +Source: https://github.com/NzbDrone/NzbDrone + +Files: * +Copyright: 2010-2013 Keivan Beigi + 2010-2013 Mark McDowall + +License: GPL-3.0+ + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + . + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". diff --git a/debian/install b/debian/install old mode 100644 new mode 100755 index 46a453a03..c881aacae --- a/debian/install +++ b/debian/install @@ -1,2 +1 @@ -nzbdrone_226/* opt/nzbdrone -../nzbdrone.desktop usr/share/applications +* opt/NzbDrone diff --git a/debian/rules b/debian/rules old mode 100644 new mode 100755 index fcc2b6104..b760bee7f --- a/debian/rules +++ b/debian/rules @@ -7,7 +7,7 @@ # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 +#export DH_VERBOSE=1 %: dh $@ From 93715ff308a5d422defb0406126d8e98f8be792d Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Tue, 27 Aug 2013 15:08:05 -0700 Subject: [PATCH 12/58] fixed deb install file. --- debian/install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/install b/debian/install index c881aacae..13f97a304 100755 --- a/debian/install +++ b/debian/install @@ -1 +1 @@ -* opt/NzbDrone +nzbdrone/* opt/NzbDrone From e25ebf7cd2363221b501749b4dd0b1734a2ea807 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Tue, 27 Aug 2013 15:29:46 -0700 Subject: [PATCH 13/58] updated compat/install file for debian --- debian/compat | 1 + debian/install | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 debian/compat diff --git a/debian/compat b/debian/compat new file mode 100644 index 000000000..45a4fb75d --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +8 diff --git a/debian/install b/debian/install index 13f97a304..106b06a9b 100755 --- a/debian/install +++ b/debian/install @@ -1 +1 @@ -nzbdrone/* opt/NzbDrone +nzbdrone_bin/* opt/NzbDrone From 37d90a34196cfe5a58f5af348b2debf74016896c Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Tue, 27 Aug 2013 16:14:10 -0700 Subject: [PATCH 14/58] updated deb maintainer. --- debian/control | 2 +- debian/copyright | 3 +-- debian/files | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 debian/files diff --git a/debian/control b/debian/control index 55fdd31fe..ed77723ae 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: nzbdrone Section: web Priority: optional -Maintainer: Keivan Beigi +Maintainer: NzbDrone Depends: libmono-cil-dev (>= 2.10.1) Homepage: http://www.nzbdrone.com Vcs-Git: git@github.com:NzbDrone/NzbDrone.git diff --git a/debian/copyright b/debian/copyright index 754e0d639..cf281685c 100755 --- a/debian/copyright +++ b/debian/copyright @@ -3,8 +3,7 @@ Upstream-Name: nzbdrone Source: https://github.com/NzbDrone/NzbDrone Files: * -Copyright: 2010-2013 Keivan Beigi - 2010-2013 Mark McDowall +Copyright: 2010-2013 NzbDrone License: GPL-3.0+ diff --git a/debian/files b/debian/files deleted file mode 100644 index 5957c8b62..000000000 --- a/debian/files +++ /dev/null @@ -1 +0,0 @@ -nzbdrone_226_i386.deb unknown extra From 45d0bc0c88ccb9bf7f164f8ab799fc7d448e1018 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Tue, 27 Aug 2013 16:18:22 -0700 Subject: [PATCH 15/58] updated deb changelog --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index d19fb36d6..bacec772a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ nzbdrone (2.0.0.0) UNRELEASED; urgency=low - * Initial release. (Closes: #XXXXXX) + * Automatic release. - -- Keivan Mon, 26 Aug 2013 17:31:17 -0700 + -- NzbDrone Mon, 26 Aug 2013 12:00:00 -0700 From 1e3a308917699c24581dcf98513dd0e3d8507f50 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Tue, 27 Aug 2013 17:10:52 -0700 Subject: [PATCH 16/58] updated changelog to use token for build and branch --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index bacec772a..d908f062f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -nzbdrone (2.0.0.0) UNRELEASED; urgency=low +nzbdrone {version} {branch}; urgency=low * Automatic release. - -- NzbDrone Mon, 26 Aug 2013 12:00:00 -0700 + -- NzbDrone Mon, 27 Aug 2013 12:00:00 -0700 From dd37713a10bc21d9697e579ceac63d2b39ecf8e6 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 27 Aug 2013 17:16:24 -0700 Subject: [PATCH 17/58] Naming config fixed, with integration tests --- NzbDrone.Api/Config/NamingModule.cs | 10 ++++-- NzbDrone.Api/NzbDroneRestModule.cs | 2 -- .../Client/ClientBase.cs | 6 ++++ .../CommandIntegerationTests.cs | 2 -- NzbDrone.Integration.Test/IntegrationTest.cs | 7 ++-- .../NamingConfigTests.cs | 35 +++++++++++++++++++ .../NzbDrone.Integration.Test.csproj | 1 + 7 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 NzbDrone.Integration.Test/NamingConfigTests.cs diff --git a/NzbDrone.Api/Config/NamingModule.cs b/NzbDrone.Api/Config/NamingModule.cs index 65f674b49..726a268b5 100644 --- a/NzbDrone.Api/Config/NamingModule.cs +++ b/NzbDrone.Api/Config/NamingModule.cs @@ -22,10 +22,9 @@ namespace NzbDrone.Api.Config _namingConfigService = namingConfigService; _buildFileNames = buildFileNames; GetResourceSingle = GetNamingConfig; - + GetResourceById = GetNamingConfig; UpdateResource = UpdateNamingConfig; - Get["/samples"] = x => GetExamples(this.Bind()); SharedValidator.RuleFor(c => c.MultiEpisodeStyle).InclusiveBetween(0, 3); @@ -35,7 +34,7 @@ namespace NzbDrone.Api.Config private void UpdateNamingConfig(NamingConfigResource resource) { - GetNewId(_namingConfigService.Save, resource); + _namingConfigService.Save(resource.InjectTo()); } private NamingConfigResource GetNamingConfig() @@ -43,6 +42,11 @@ namespace NzbDrone.Api.Config return _namingConfigService.GetConfig().InjectTo(); } + private NamingConfigResource GetNamingConfig(int id) + { + return GetNamingConfig(); + } + private JsonResponse GetExamples(NamingConfigResource config) { var nameSpec = config.InjectTo(); diff --git a/NzbDrone.Api/NzbDroneRestModule.cs b/NzbDrone.Api/NzbDroneRestModule.cs index d8072c4b2..b4b01aee5 100644 --- a/NzbDrone.Api/NzbDroneRestModule.cs +++ b/NzbDrone.Api/NzbDroneRestModule.cs @@ -21,7 +21,6 @@ namespace NzbDrone.Api PutValidator.RuleFor(r => r.Id).ValidId(); } - protected int GetNewId(Func function, TResource resource) where TModel : ModelBase, new() { var model = resource.InjectTo(); @@ -35,7 +34,6 @@ namespace NzbDrone.Api return modelList.InjectTo>(); } - protected PagingResource ApplyToPage(Func, PagingSpec> function, PagingSpec pagingSpec) where TModel : ModelBase, new() { pagingSpec = function(pagingSpec); diff --git a/NzbDrone.Integration.Test/Client/ClientBase.cs b/NzbDrone.Integration.Test/Client/ClientBase.cs index 1483f9ad4..05ca16711 100644 --- a/NzbDrone.Integration.Test/Client/ClientBase.cs +++ b/NzbDrone.Integration.Test/Client/ClientBase.cs @@ -55,6 +55,12 @@ namespace NzbDrone.Integration.Test.Client return Get(request, statusCode); } + public TResource GetSingle(HttpStatusCode statusCode = HttpStatusCode.OK) + { + var request = BuildRequest(); + return Get(request, statusCode); + } + public void Delete(int id) { var request = BuildRequest(id.ToString()); diff --git a/NzbDrone.Integration.Test/CommandIntegerationTests.cs b/NzbDrone.Integration.Test/CommandIntegerationTests.cs index 7899393d8..c1e06bac1 100644 --- a/NzbDrone.Integration.Test/CommandIntegerationTests.cs +++ b/NzbDrone.Integration.Test/CommandIntegerationTests.cs @@ -11,7 +11,5 @@ namespace NzbDrone.Integration.Test { Commands.Post(new CommandResource {Command = "rsssync"}); } - - } } \ No newline at end of file diff --git a/NzbDrone.Integration.Test/IntegrationTest.cs b/NzbDrone.Integration.Test/IntegrationTest.cs index b705146b6..3ef126a98 100644 --- a/NzbDrone.Integration.Test/IntegrationTest.cs +++ b/NzbDrone.Integration.Test/IntegrationTest.cs @@ -3,7 +3,7 @@ using NLog.Config; using NLog.Targets; using NUnit.Framework; using NzbDrone.Api.Commands; -using NzbDrone.Api.Episodes; +using NzbDrone.Api.Config; using NzbDrone.Api.RootFolders; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Integration.Test.Client; @@ -25,10 +25,10 @@ namespace NzbDrone.Integration.Test protected IndexerClient Indexers; protected EpisodeClient Episodes; protected SeasonClient Seasons; + protected ClientBase NamingConfig; private NzbDroneRunner _runner; - public IntegrationTest() { new StartupArguments(); @@ -42,7 +42,6 @@ namespace NzbDrone.Integration.Test [SetUp] public void SmokeTestSetup() { - _runner = new NzbDroneRunner(); _runner.KillAll(); @@ -51,7 +50,6 @@ namespace NzbDrone.Integration.Test _runner.Start(); } - private void InitRestClients() { RestClient = new RestClient("http://localhost:8989/api"); @@ -62,6 +60,7 @@ namespace NzbDrone.Integration.Test Indexers = new IndexerClient(RestClient); Episodes = new EpisodeClient(RestClient); Seasons = new SeasonClient(RestClient); + NamingConfig = new ClientBase(RestClient, "config/naming"); } [TearDown] diff --git a/NzbDrone.Integration.Test/NamingConfigTests.cs b/NzbDrone.Integration.Test/NamingConfigTests.cs new file mode 100644 index 000000000..573eaf2ed --- /dev/null +++ b/NzbDrone.Integration.Test/NamingConfigTests.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using FluentAssertions; +using NUnit.Framework; + +namespace NzbDrone.Integration.Test +{ + [TestFixture] + public class NamingConfigTests : IntegrationTest + { + + [Test] + public void should_be_able_to_get() + { + NamingConfig.GetSingle().Should().NotBeNull(); + } + + [Test] + public void should_be_able_to_get_by_id() + { + var config = NamingConfig.GetSingle(); + NamingConfig.Get(config.Id).Should().NotBeNull(); + NamingConfig.Get(config.Id).Id.Should().Be(config.Id); + } + + [Test] + public void should_be_able_to_update() + { + var config = NamingConfig.GetSingle(); + config.RenameEpisodes = false; + + NamingConfig.Put(config).RenameEpisodes.Should().BeFalse(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj index 04ce2753c..2ffdbc7a9 100644 --- a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj +++ b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj @@ -99,6 +99,7 @@ + From 3a181e841c15958db3d268c0ca199d97b46e75da Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Tue, 27 Aug 2013 17:40:01 -0700 Subject: [PATCH 18/58] saved changefile in ubuntu --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index d908f062f..eb8f841a6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ nzbdrone {version} {branch}; urgency=low - * Automatic release. + * Automatic Release. - -- NzbDrone Mon, 27 Aug 2013 12:00:00 -0700 + -- NzbDrone Mon, 26 Aug 2013 00:00:00 -0700 From b75aad1268f3d6ebca4222bde09ffede283c7a3a Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Wed, 28 Aug 2013 13:55:44 -0700 Subject: [PATCH 19/58] updated Owin to 2.0 RC1 --- NzbDrone.Console/NzbDrone.Console.csproj | 8 ++++---- NzbDrone.Console/packages.config | 4 ++-- NzbDrone.Host/NzbDrone.Host.csproj | 12 ++++++------ NzbDrone.Host/packages.config | 6 +++--- .../NzbDrone.Integration.Test.csproj | 18 ++++++++++-------- NzbDrone.Integration.Test/packages.config | 8 ++++---- NzbDrone/NzbDrone.csproj | 8 ++++---- NzbDrone/packages.config | 4 ++-- 8 files changed, 35 insertions(+), 33 deletions(-) diff --git a/NzbDrone.Console/NzbDrone.Console.csproj b/NzbDrone.Console/NzbDrone.Console.csproj index cec173fe1..ced345799 100644 --- a/NzbDrone.Console/NzbDrone.Console.csproj +++ b/NzbDrone.Console/NzbDrone.Console.csproj @@ -71,13 +71,13 @@ False ..\packages\Microsoft.AspNet.SignalR.Owin.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Owin.dll - + False - ..\packages\Microsoft.Owin.1.1.0-beta2\lib\net40\Microsoft.Owin.dll + ..\packages\Microsoft.Owin.2.0.0-rc1\lib\net40\Microsoft.Owin.dll - + False - ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll + ..\packages\Microsoft.Owin.Hosting.2.0.0-rc1\lib\net40\Microsoft.Owin.Hosting.dll False diff --git a/NzbDrone.Console/packages.config b/NzbDrone.Console/packages.config index 19f3a3d8b..589175f60 100644 --- a/NzbDrone.Console/packages.config +++ b/NzbDrone.Console/packages.config @@ -2,8 +2,8 @@ - - + + diff --git a/NzbDrone.Host/NzbDrone.Host.csproj b/NzbDrone.Host/NzbDrone.Host.csproj index 2eb6bcda7..ce9da2e81 100644 --- a/NzbDrone.Host/NzbDrone.Host.csproj +++ b/NzbDrone.Host/NzbDrone.Host.csproj @@ -77,17 +77,17 @@ False ..\packages\Microsoft.AspNet.SignalR.Owin.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Owin.dll - + False - ..\packages\Microsoft.Owin.1.1.0-beta2\lib\net40\Microsoft.Owin.dll + ..\packages\Microsoft.Owin.2.0.0-rc1\lib\net40\Microsoft.Owin.dll - + False - ..\packages\Microsoft.Owin.Host.HttpListener.1.1.0-beta2\lib\net40\Microsoft.Owin.Host.HttpListener.dll + ..\packages\Microsoft.Owin.Host.HttpListener.2.0.0-rc1\lib\net40\Microsoft.Owin.Host.HttpListener.dll - + False - ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll + ..\packages\Microsoft.Owin.Hosting.2.0.0-rc1\lib\net40\Microsoft.Owin.Hosting.dll ..\packages\Nancy.0.18.0\lib\net40\Nancy.dll diff --git a/NzbDrone.Host/packages.config b/NzbDrone.Host/packages.config index 36d7e82de..99ec170a9 100644 --- a/NzbDrone.Host/packages.config +++ b/NzbDrone.Host/packages.config @@ -2,9 +2,9 @@ - - - + + + diff --git a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj index 2ffdbc7a9..bfea57f7b 100644 --- a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj +++ b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj @@ -40,19 +40,21 @@ False ..\packages\FluentValidation.4.0.0.1\lib\Net40\FluentValidation.dll - - ..\packages\Microsoft.AspNet.SignalR.Client.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Client.dll + + False + ..\packages\Microsoft.AspNet.SignalR.Client.2.0.0-rc1\lib\net40\Microsoft.AspNet.SignalR.Client.dll - - ..\packages\Microsoft.Owin.1.1.0-beta2\lib\net40\Microsoft.Owin.dll + + False + ..\packages\Microsoft.Owin.2.0.0-rc1\lib\net40\Microsoft.Owin.dll - + False - ..\packages\Microsoft.Owin.Host.HttpListener.1.1.0-beta2\lib\net40\Microsoft.Owin.Host.HttpListener.dll + ..\packages\Microsoft.Owin.Host.HttpListener.2.0.0-rc1\lib\net40\Microsoft.Owin.Host.HttpListener.dll - + False - ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll + ..\packages\Microsoft.Owin.Hosting.2.0.0-rc1\lib\net40\Microsoft.Owin.Hosting.dll False diff --git a/NzbDrone.Integration.Test/packages.config b/NzbDrone.Integration.Test/packages.config index f0ee04f81..cd41cb32b 100644 --- a/NzbDrone.Integration.Test/packages.config +++ b/NzbDrone.Integration.Test/packages.config @@ -2,11 +2,11 @@ - - - - + + + + diff --git a/NzbDrone/NzbDrone.csproj b/NzbDrone/NzbDrone.csproj index b599ed47b..4d447d32b 100644 --- a/NzbDrone/NzbDrone.csproj +++ b/NzbDrone/NzbDrone.csproj @@ -71,13 +71,13 @@ False ..\packages\Microsoft.AspNet.SignalR.Owin.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Owin.dll - + False - ..\packages\Microsoft.Owin.1.1.0-beta2\lib\net40\Microsoft.Owin.dll + ..\packages\Microsoft.Owin.2.0.0-rc1\lib\net40\Microsoft.Owin.dll - + False - ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll + ..\packages\Microsoft.Owin.Hosting.2.0.0-rc1\lib\net40\Microsoft.Owin.Hosting.dll False diff --git a/NzbDrone/packages.config b/NzbDrone/packages.config index 907d39c5a..3dfa2a2d5 100644 --- a/NzbDrone/packages.config +++ b/NzbDrone/packages.config @@ -2,8 +2,8 @@ - - + + \ No newline at end of file From 9b9e1e20eb035a3c026f2a79f3aa6fc8406199e2 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Wed, 28 Aug 2013 15:08:01 -0700 Subject: [PATCH 20/58] replaced owin's ITraceOutputFactory to one based on nlog that should work on linux. --- NzbDrone.Host/MainAppContainerBuilder.cs | 5 ++- NzbDrone.Host/NzbDrone.Host.csproj | 3 ++ NzbDrone.Host/Owin/NlogTextWriter.cs | 41 ++++++++++++++++++++ NzbDrone.Host/Owin/OwinHostController.cs | 6 ++- NzbDrone.Host/Owin/OwinServiceProvider.cs | 25 ++++++++++++ NzbDrone.Host/Owin/OwinTraceOutputFactory.cs | 14 +++++++ 6 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 NzbDrone.Host/Owin/NlogTextWriter.cs create mode 100644 NzbDrone.Host/Owin/OwinServiceProvider.cs create mode 100644 NzbDrone.Host/Owin/OwinTraceOutputFactory.cs diff --git a/NzbDrone.Host/MainAppContainerBuilder.cs b/NzbDrone.Host/MainAppContainerBuilder.cs index 51f47d415..ecebe6e70 100644 --- a/NzbDrone.Host/MainAppContainerBuilder.cs +++ b/NzbDrone.Host/MainAppContainerBuilder.cs @@ -1,4 +1,5 @@ -using Nancy.Bootstrapper; +using System; +using Nancy.Bootstrapper; using NzbDrone.Api; using NzbDrone.Api.SignalR; using NzbDrone.Common.Composition; @@ -6,6 +7,7 @@ using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Datastore; using NzbDrone.Core.Organizer; using NzbDrone.Core.RootFolders; +using NzbDrone.Host.Owin; namespace NzbDrone.Host { @@ -24,6 +26,7 @@ namespace NzbDrone.Host Container.Register(typeof(IBasicRepository), typeof(BasicRepository)); Container.Register(typeof(IBasicRepository), typeof(BasicRepository)); + Container.Register(typeof(System.IServiceProvider), typeof(OwinServiceProvider)); Container.Register(); } diff --git a/NzbDrone.Host/NzbDrone.Host.csproj b/NzbDrone.Host/NzbDrone.Host.csproj index ce9da2e81..ddb934a54 100644 --- a/NzbDrone.Host/NzbDrone.Host.csproj +++ b/NzbDrone.Host/NzbDrone.Host.csproj @@ -122,6 +122,9 @@ + + + diff --git a/NzbDrone.Host/Owin/NlogTextWriter.cs b/NzbDrone.Host/Owin/NlogTextWriter.cs new file mode 100644 index 000000000..d4cd4da7d --- /dev/null +++ b/NzbDrone.Host/Owin/NlogTextWriter.cs @@ -0,0 +1,41 @@ +using System.IO; +using System.Text; +using NLog; + +namespace NzbDrone.Host.Owin +{ + public class NlogTextWriter : TextWriter + { + private readonly Logger logger = LogManager.GetCurrentClassLogger(); + + + public override Encoding Encoding + { + get + { + return Encoding.Default; + } + } + + public override void Write(char value) + { + logger.Trace(value); + } + + public override void Write(char[] buffer) + { + logger.Trace(buffer); + } + + public override void Write(string value) + { + logger.Trace(value); + } + + public override void Write(char[] buffer, int index, int count) + { + logger.Trace(buffer); + } + + } +} \ No newline at end of file diff --git a/NzbDrone.Host/Owin/OwinHostController.cs b/NzbDrone.Host/Owin/OwinHostController.cs index 0055883b6..447ac71d0 100644 --- a/NzbDrone.Host/Owin/OwinHostController.cs +++ b/NzbDrone.Host/Owin/OwinHostController.cs @@ -14,13 +14,15 @@ namespace NzbDrone.Host.Owin { private readonly IConfigFileProvider _configFileProvider; private readonly IEnumerable _owinMiddleWares; + private readonly IServiceProvider _serviceProvider; private readonly Logger _logger; private IDisposable _host; - public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable owinMiddleWares, Logger logger) + public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable owinMiddleWares, IServiceProvider serviceProvider, Logger logger) { _configFileProvider = configFileProvider; _owinMiddleWares = owinMiddleWares; + _serviceProvider = serviceProvider; _logger = logger; } @@ -37,7 +39,7 @@ namespace NzbDrone.Host.Owin _logger.Info("starting server on {0}", url); - _host = WebApp.Start(options, BuildApp); + _host = WebApp.Start(_serviceProvider, options, BuildApp); } private void BuildApp(IAppBuilder appBuilder) diff --git a/NzbDrone.Host/Owin/OwinServiceProvider.cs b/NzbDrone.Host/Owin/OwinServiceProvider.cs new file mode 100644 index 000000000..e13c76191 --- /dev/null +++ b/NzbDrone.Host/Owin/OwinServiceProvider.cs @@ -0,0 +1,25 @@ +using System; +using Microsoft.Owin.Hosting.Services; +using Microsoft.Owin.Hosting.Tracing; + +namespace NzbDrone.Host.Owin +{ + public class OwinServiceProvider : IServiceProvider + { + private readonly IServiceProvider _defaultProvider; + + public OwinServiceProvider() + { + _defaultProvider = ServicesFactory.Create(); + } + public object GetService(Type serviceType) + { + if (serviceType == typeof (ITraceOutputFactory)) + { + return new OwinTraceOutputFactory(); + } + + return _defaultProvider.GetService(serviceType); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Host/Owin/OwinTraceOutputFactory.cs b/NzbDrone.Host/Owin/OwinTraceOutputFactory.cs new file mode 100644 index 000000000..9a0f8997d --- /dev/null +++ b/NzbDrone.Host/Owin/OwinTraceOutputFactory.cs @@ -0,0 +1,14 @@ +using System.IO; +using Microsoft.Owin.Hosting.Tracing; + +namespace NzbDrone.Host.Owin +{ + public class OwinTraceOutputFactory : ITraceOutputFactory + { + + public TextWriter Create(string outputFile) + { + return new NlogTextWriter(); + } + } +} \ No newline at end of file From 6c7e12da5bd0736ffb291b65376b26f4e41623c3 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Wed, 28 Aug 2013 15:25:12 -0700 Subject: [PATCH 21/58] replaced owin's ITraceOutputFactory to one based on nlog that should work on linux. --- NzbDrone.Host/MainAppContainerBuilder.cs | 1 - NzbDrone.Host/Owin/OwinHostController.cs | 6 ++---- NzbDrone.Host/Owin/OwinServiceProvider.cs | 21 ++++++--------------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/NzbDrone.Host/MainAppContainerBuilder.cs b/NzbDrone.Host/MainAppContainerBuilder.cs index ecebe6e70..e12fc9153 100644 --- a/NzbDrone.Host/MainAppContainerBuilder.cs +++ b/NzbDrone.Host/MainAppContainerBuilder.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Host Container.Register(typeof(IBasicRepository), typeof(BasicRepository)); Container.Register(typeof(IBasicRepository), typeof(BasicRepository)); - Container.Register(typeof(System.IServiceProvider), typeof(OwinServiceProvider)); Container.Register(); } diff --git a/NzbDrone.Host/Owin/OwinHostController.cs b/NzbDrone.Host/Owin/OwinHostController.cs index 447ac71d0..a571d5530 100644 --- a/NzbDrone.Host/Owin/OwinHostController.cs +++ b/NzbDrone.Host/Owin/OwinHostController.cs @@ -14,15 +14,13 @@ namespace NzbDrone.Host.Owin { private readonly IConfigFileProvider _configFileProvider; private readonly IEnumerable _owinMiddleWares; - private readonly IServiceProvider _serviceProvider; private readonly Logger _logger; private IDisposable _host; - public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable owinMiddleWares, IServiceProvider serviceProvider, Logger logger) + public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable owinMiddleWares, Logger logger) { _configFileProvider = configFileProvider; _owinMiddleWares = owinMiddleWares; - _serviceProvider = serviceProvider; _logger = logger; } @@ -39,7 +37,7 @@ namespace NzbDrone.Host.Owin _logger.Info("starting server on {0}", url); - _host = WebApp.Start(_serviceProvider, options, BuildApp); + _host = WebApp.Start(OwinServiceProviderFactory.Create(), options, BuildApp); } private void BuildApp(IAppBuilder appBuilder) diff --git a/NzbDrone.Host/Owin/OwinServiceProvider.cs b/NzbDrone.Host/Owin/OwinServiceProvider.cs index e13c76191..cffea738f 100644 --- a/NzbDrone.Host/Owin/OwinServiceProvider.cs +++ b/NzbDrone.Host/Owin/OwinServiceProvider.cs @@ -1,25 +1,16 @@ -using System; -using Microsoft.Owin.Hosting.Services; +using Microsoft.Owin.Hosting.Services; using Microsoft.Owin.Hosting.Tracing; namespace NzbDrone.Host.Owin { - public class OwinServiceProvider : IServiceProvider + public static class OwinServiceProviderFactory { - private readonly IServiceProvider _defaultProvider; - - public OwinServiceProvider() - { - _defaultProvider = ServicesFactory.Create(); - } - public object GetService(Type serviceType) + public static ServiceProvider Create() { - if (serviceType == typeof (ITraceOutputFactory)) - { - return new OwinTraceOutputFactory(); - } + var provider = (ServiceProvider)ServicesFactory.Create(); + provider.Add(typeof(ITraceOutputFactory), typeof(OwinTraceOutputFactory)); - return _defaultProvider.GetService(serviceType); + return provider; } } } \ No newline at end of file From 64ab411ba30a623ea58183d7a1619cd891a4a644 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Wed, 28 Aug 2013 16:14:31 -0700 Subject: [PATCH 22/58] added logging to integration test runner for status call. --- NzbDrone.Integration.Test/NzbDroneRunner.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/NzbDrone.Integration.Test/NzbDroneRunner.cs b/NzbDrone.Integration.Test/NzbDroneRunner.cs index 988c47278..cde91b605 100644 --- a/NzbDrone.Integration.Test/NzbDroneRunner.cs +++ b/NzbDrone.Integration.Test/NzbDroneRunner.cs @@ -53,11 +53,16 @@ namespace NzbDrone.Integration.Test Assert.Fail("Process has exited"); } - if (_restClient.Get(new RestRequest("system/status")).ResponseStatus == ResponseStatus.Completed) + + var statusCall = _restClient.Get(new RestRequest("system/status")); + + if (statusCall.ResponseStatus == ResponseStatus.Completed) { return; } + Console.WriteLine("Waiting for NzbDrone to start. Response Status : {0} [{1}] {2}", statusCall.ResponseStatus, statusCall.StatusDescription, statusCall.ErrorException); + Thread.Sleep(500); } } From 1f90d546d4405910eaae34d3868cfee367d30715 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 28 Aug 2013 08:15:49 -0700 Subject: [PATCH 23/58] Fixed some help icons that were pointing at old names --- UI/Settings/DownloadClient/BlackholeViewTemplate.html | 2 +- UI/Settings/DownloadClient/LayoutTemplate.html | 2 +- UI/Settings/DownloadClient/NzbgetViewTemplate.html | 4 ++-- UI/Settings/DownloadClient/PneumaticViewTemplate.html | 2 +- UI/Settings/DownloadClient/SabViewTemplate.html | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/UI/Settings/DownloadClient/BlackholeViewTemplate.html b/UI/Settings/DownloadClient/BlackholeViewTemplate.html index 05d9e78ce..e41520b2f 100644 --- a/UI/Settings/DownloadClient/BlackholeViewTemplate.html +++ b/UI/Settings/DownloadClient/BlackholeViewTemplate.html @@ -6,7 +6,7 @@
- +
diff --git a/UI/Settings/DownloadClient/LayoutTemplate.html b/UI/Settings/DownloadClient/LayoutTemplate.html index 9d66916f5..54c0c81f6 100644 --- a/UI/Settings/DownloadClient/LayoutTemplate.html +++ b/UI/Settings/DownloadClient/LayoutTemplate.html @@ -19,7 +19,7 @@
- +
diff --git a/UI/Settings/DownloadClient/NzbgetViewTemplate.html b/UI/Settings/DownloadClient/NzbgetViewTemplate.html index cc29f4a3a..cae6ec715 100644 --- a/UI/Settings/DownloadClient/NzbgetViewTemplate.html +++ b/UI/Settings/DownloadClient/NzbgetViewTemplate.html @@ -61,7 +61,7 @@ - + @@ -79,7 +79,7 @@ - + diff --git a/UI/Settings/DownloadClient/PneumaticViewTemplate.html b/UI/Settings/DownloadClient/PneumaticViewTemplate.html index 791b212ba..8fc612fc3 100644 --- a/UI/Settings/DownloadClient/PneumaticViewTemplate.html +++ b/UI/Settings/DownloadClient/PneumaticViewTemplate.html @@ -6,7 +6,7 @@
- +
diff --git a/UI/Settings/DownloadClient/SabViewTemplate.html b/UI/Settings/DownloadClient/SabViewTemplate.html index 8bdd39afd..25ae6e74a 100644 --- a/UI/Settings/DownloadClient/SabViewTemplate.html +++ b/UI/Settings/DownloadClient/SabViewTemplate.html @@ -70,11 +70,11 @@ - + - + @@ -92,7 +92,7 @@ - + From 9e5353aaccf65f45b5f97729b309da39ed592dbe Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 28 Aug 2013 18:43:45 -0700 Subject: [PATCH 24/58] Cleanup orphaned seasons when deleting episodes --- NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 1 + .../HandleEpisodeInfoDeletedEventFixture.cs | 93 ++++++++++++++++++ NzbDrone.Core/NzbDrone.Core.csproj | 1 + .../Tv/Events/EpisodeInfoDeletedEvent.cs | 16 +++ NzbDrone.Core/Tv/RefreshEpisodeService.cs | 14 ++- NzbDrone.Core/Tv/SeasonService.cs | Bin 8572 -> 9871 bytes 6 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 NzbDrone.Core.Test/TvTests/SeasonServiceTests/HandleEpisodeInfoDeletedEventFixture.cs create mode 100644 NzbDrone.Core/Tv/Events/EpisodeInfoDeletedEvent.cs diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index b3e34350c..0d3bd3634 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -186,6 +186,7 @@ + diff --git a/NzbDrone.Core.Test/TvTests/SeasonServiceTests/HandleEpisodeInfoDeletedEventFixture.cs b/NzbDrone.Core.Test/TvTests/SeasonServiceTests/HandleEpisodeInfoDeletedEventFixture.cs new file mode 100644 index 000000000..d31c2b679 --- /dev/null +++ b/NzbDrone.Core.Test/TvTests/SeasonServiceTests/HandleEpisodeInfoDeletedEventFixture.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FizzWare.NBuilder; +using Moq; +using NUnit.Framework; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; +using NzbDrone.Core.Tv.Events; + +namespace NzbDrone.Core.Test.TvTests.SeasonServiceTests +{ + [TestFixture] + public class HandleEpisodeInfoDeletedEventFixture : CoreTest + { + private List _seasons; + private List _episodes; + + [SetUp] + public void Setup() + { + _seasons = Builder + .CreateListOfSize(1) + .All() + .With(s => s.SeriesId = 1) + .Build() + .ToList(); + + _episodes = Builder + .CreateListOfSize(1) + .All() + .With(e => e.SeasonNumber = _seasons.First().SeasonNumber) + .With(s => s.SeriesId = _seasons.First().SeasonNumber) + .Build() + .ToList(); + + Mocker.GetMock() + .Setup(s => s.GetSeasonBySeries(It.IsAny())) + .Returns(_seasons); + + Mocker.GetMock() + .Setup(s => s.GetEpisodesBySeason(It.IsAny(), _seasons.First().SeasonNumber)) + .Returns(_episodes); + } + + private void GivenAbandonedSeason() + { + Mocker.GetMock() + .Setup(s => s.GetEpisodesBySeason(It.IsAny(), _seasons.First().SeasonNumber)) + .Returns(new List()); + } + + [Test] + public void should_not_delete_when_season_is_still_valid() + { + Subject.Handle(new EpisodeInfoDeletedEvent(_episodes)); + + Mocker.GetMock() + .Verify(v => v.Delete(It.IsAny()), Times.Never()); + } + + [Test] + public void should_delete_season_if_no_episodes_exist_in_that_season() + { + GivenAbandonedSeason(); + + Subject.Handle(new EpisodeInfoDeletedEvent(_episodes)); + + Mocker.GetMock() + .Verify(v => v.Delete(It.IsAny()), Times.Once()); + } + + [Test] + public void should_only_delete_a_season_once() + { + _episodes = Builder + .CreateListOfSize(5) + .All() + .With(e => e.SeasonNumber = _seasons.First().SeasonNumber) + .With(s => s.SeriesId = _seasons.First().SeasonNumber) + .Build() + .ToList(); + + GivenAbandonedSeason(); + + Subject.Handle(new EpisodeInfoDeletedEvent(_episodes)); + + Mocker.GetMock() + .Verify(v => v.Delete(It.IsAny()), Times.Once()); + } + } +} diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index a774cc3fd..9ed55a6ff 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -350,6 +350,7 @@ + diff --git a/NzbDrone.Core/Tv/Events/EpisodeInfoDeletedEvent.cs b/NzbDrone.Core/Tv/Events/EpisodeInfoDeletedEvent.cs new file mode 100644 index 000000000..864445e58 --- /dev/null +++ b/NzbDrone.Core/Tv/Events/EpisodeInfoDeletedEvent.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using NzbDrone.Common.Messaging; + +namespace NzbDrone.Core.Tv.Events +{ + public class EpisodeInfoDeletedEvent : IEvent + { + public ReadOnlyCollection Episodes { get; private set; } + + public EpisodeInfoDeletedEvent(IList episodes) + { + Episodes = new ReadOnlyCollection(episodes); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Tv/RefreshEpisodeService.cs b/NzbDrone.Core/Tv/RefreshEpisodeService.cs index 14140ba84..c62d8a5d2 100644 --- a/NzbDrone.Core/Tv/RefreshEpisodeService.cs +++ b/NzbDrone.Core/Tv/RefreshEpisodeService.cs @@ -34,7 +34,7 @@ namespace NzbDrone.Core.Tv var successCount = 0; var failCount = 0; - var existinEpisodes = _episodeService.GetEpisodeBySeries(series.Id); + var existingEpisodes = _episodeService.GetEpisodeBySeries(series.Id); var seasons = _seasonService.GetSeasonsBySeries(series.Id); var updateList = new List(); @@ -44,11 +44,11 @@ namespace NzbDrone.Core.Tv { try { - var episodeToUpdate = existinEpisodes.SingleOrDefault(e => e.SeasonNumber == episode.SeasonNumber && e.EpisodeNumber == episode.EpisodeNumber); + var episodeToUpdate = existingEpisodes.SingleOrDefault(e => e.SeasonNumber == episode.SeasonNumber && e.EpisodeNumber == episode.EpisodeNumber); if (episodeToUpdate != null) { - existinEpisodes.Remove(episodeToUpdate); + existingEpisodes.Remove(episodeToUpdate); updateList.Add(episodeToUpdate); } else @@ -82,11 +82,10 @@ namespace NzbDrone.Core.Tv AdjustMultiEpisodeAirTime(series, allEpisodes); - _episodeService.DeleteMany(existinEpisodes); + _episodeService.DeleteMany(existingEpisodes); _episodeService.UpdateMany(updateList); _episodeService.InsertMany(newList); - if (newList.Any()) { _messageAggregator.PublishEvent(new EpisodeInfoAddedEvent(newList, series)); @@ -97,6 +96,11 @@ namespace NzbDrone.Core.Tv _messageAggregator.PublishEvent(new EpisodeInfoUpdatedEvent(updateList)); } + if (existingEpisodes.Any()) + { + _messageAggregator.PublishEvent(new EpisodeInfoDeletedEvent(updateList)); + } + if (failCount != 0) { _logger.Info("Finished episode refresh for series: {0}. Successful: {1} - Failed: {2} ", diff --git a/NzbDrone.Core/Tv/SeasonService.cs b/NzbDrone.Core/Tv/SeasonService.cs index 8cb3d0c75795638537f01c86fdb483b545701f5e..6355796a47cb4e1da5460d78e1594785dad261cc 100644 GIT binary patch delta 586 zcmZ`$O-tNR6ooWuVm@A;bY^Om_O+YNSQ${)V^JJR7uLa9xGbr;Qy;_^O)>!mS8hZE zh4UlamBLWyZ|Gm>raPB*;ie$1$;?#5wr};g=iGD7z4vfcls1P6miGo3stLuC zk~hKZUt0Z)wfd6UtJZ4p%<}E>*JDA1py4o*Cyf93s& z$+4jfT=Nl3i($kn!?p~3=TGt5v2pBN;L;k!l~d7+i-Wl{?!B|Ua_0+9?}{I>8zzy! Ao&W#< delta 98 zcmeD8{o}MDjcGC~v+(3eOk!aA3X{ZUPv*^Blk0fcCfA6GPwp3ezWEPt9@FFkCYH&$ h!s1}MQ9uh!uNF`T)0YI4!1Nb^La0XW%|ha}`~Y6UASM6+ From 5dc3a3223dce293595805259d9fc8d4d5aa38c7b Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 11:34:53 -0700 Subject: [PATCH 25/58] Revert "updated Owin to 2.0 RC1" This reverts commit b75aad1268f3d6ebca4222bde09ffede283c7a3a. --- NzbDrone.Console/NzbDrone.Console.csproj | 8 ++++---- NzbDrone.Console/packages.config | 4 ++-- NzbDrone.Host/NzbDrone.Host.csproj | 12 ++++++------ NzbDrone.Host/packages.config | 6 +++--- .../NzbDrone.Integration.Test.csproj | 18 ++++++++---------- NzbDrone.Integration.Test/packages.config | 8 ++++---- NzbDrone/NzbDrone.csproj | 8 ++++---- NzbDrone/packages.config | 4 ++-- 8 files changed, 33 insertions(+), 35 deletions(-) diff --git a/NzbDrone.Console/NzbDrone.Console.csproj b/NzbDrone.Console/NzbDrone.Console.csproj index ced345799..cec173fe1 100644 --- a/NzbDrone.Console/NzbDrone.Console.csproj +++ b/NzbDrone.Console/NzbDrone.Console.csproj @@ -71,13 +71,13 @@ False ..\packages\Microsoft.AspNet.SignalR.Owin.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Owin.dll
- + False - ..\packages\Microsoft.Owin.2.0.0-rc1\lib\net40\Microsoft.Owin.dll + ..\packages\Microsoft.Owin.1.1.0-beta2\lib\net40\Microsoft.Owin.dll - + False - ..\packages\Microsoft.Owin.Hosting.2.0.0-rc1\lib\net40\Microsoft.Owin.Hosting.dll + ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll False diff --git a/NzbDrone.Console/packages.config b/NzbDrone.Console/packages.config index 589175f60..19f3a3d8b 100644 --- a/NzbDrone.Console/packages.config +++ b/NzbDrone.Console/packages.config @@ -2,8 +2,8 @@ - - + + diff --git a/NzbDrone.Host/NzbDrone.Host.csproj b/NzbDrone.Host/NzbDrone.Host.csproj index ddb934a54..c625626ea 100644 --- a/NzbDrone.Host/NzbDrone.Host.csproj +++ b/NzbDrone.Host/NzbDrone.Host.csproj @@ -77,17 +77,17 @@ False ..\packages\Microsoft.AspNet.SignalR.Owin.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Owin.dll - + False - ..\packages\Microsoft.Owin.2.0.0-rc1\lib\net40\Microsoft.Owin.dll + ..\packages\Microsoft.Owin.1.1.0-beta2\lib\net40\Microsoft.Owin.dll - + False - ..\packages\Microsoft.Owin.Host.HttpListener.2.0.0-rc1\lib\net40\Microsoft.Owin.Host.HttpListener.dll + ..\packages\Microsoft.Owin.Host.HttpListener.1.1.0-beta2\lib\net40\Microsoft.Owin.Host.HttpListener.dll - + False - ..\packages\Microsoft.Owin.Hosting.2.0.0-rc1\lib\net40\Microsoft.Owin.Hosting.dll + ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll ..\packages\Nancy.0.18.0\lib\net40\Nancy.dll diff --git a/NzbDrone.Host/packages.config b/NzbDrone.Host/packages.config index 99ec170a9..36d7e82de 100644 --- a/NzbDrone.Host/packages.config +++ b/NzbDrone.Host/packages.config @@ -2,9 +2,9 @@ - - - + + + diff --git a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj index bfea57f7b..2ffdbc7a9 100644 --- a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj +++ b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj @@ -40,21 +40,19 @@ False ..\packages\FluentValidation.4.0.0.1\lib\Net40\FluentValidation.dll - - False - ..\packages\Microsoft.AspNet.SignalR.Client.2.0.0-rc1\lib\net40\Microsoft.AspNet.SignalR.Client.dll + + ..\packages\Microsoft.AspNet.SignalR.Client.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Client.dll - - False - ..\packages\Microsoft.Owin.2.0.0-rc1\lib\net40\Microsoft.Owin.dll + + ..\packages\Microsoft.Owin.1.1.0-beta2\lib\net40\Microsoft.Owin.dll - + False - ..\packages\Microsoft.Owin.Host.HttpListener.2.0.0-rc1\lib\net40\Microsoft.Owin.Host.HttpListener.dll + ..\packages\Microsoft.Owin.Host.HttpListener.1.1.0-beta2\lib\net40\Microsoft.Owin.Host.HttpListener.dll - + False - ..\packages\Microsoft.Owin.Hosting.2.0.0-rc1\lib\net40\Microsoft.Owin.Hosting.dll + ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll False diff --git a/NzbDrone.Integration.Test/packages.config b/NzbDrone.Integration.Test/packages.config index cd41cb32b..f0ee04f81 100644 --- a/NzbDrone.Integration.Test/packages.config +++ b/NzbDrone.Integration.Test/packages.config @@ -2,11 +2,11 @@ + + + + - - - - diff --git a/NzbDrone/NzbDrone.csproj b/NzbDrone/NzbDrone.csproj index 4d447d32b..b599ed47b 100644 --- a/NzbDrone/NzbDrone.csproj +++ b/NzbDrone/NzbDrone.csproj @@ -71,13 +71,13 @@ False ..\packages\Microsoft.AspNet.SignalR.Owin.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Owin.dll - + False - ..\packages\Microsoft.Owin.2.0.0-rc1\lib\net40\Microsoft.Owin.dll + ..\packages\Microsoft.Owin.1.1.0-beta2\lib\net40\Microsoft.Owin.dll - + False - ..\packages\Microsoft.Owin.Hosting.2.0.0-rc1\lib\net40\Microsoft.Owin.Hosting.dll + ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll False diff --git a/NzbDrone/packages.config b/NzbDrone/packages.config index 3dfa2a2d5..907d39c5a 100644 --- a/NzbDrone/packages.config +++ b/NzbDrone/packages.config @@ -2,8 +2,8 @@ - - + + \ No newline at end of file From ef32431682e1ae965010345c9a2d4c1a314dd363 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 18:26:03 -0700 Subject: [PATCH 26/58] GetActualCasing can partially fix the path for non-existing paths. --- NzbDrone.Common.Test/PathExtensionFixture.cs | 21 ++++++++++---------- NzbDrone.Common/PathExtensions.cs | 14 ++++++++----- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/NzbDrone.Common.Test/PathExtensionFixture.cs b/NzbDrone.Common.Test/PathExtensionFixture.cs index 739344727..907d13d4c 100644 --- a/NzbDrone.Common.Test/PathExtensionFixture.cs +++ b/NzbDrone.Common.Test/PathExtensionFixture.cs @@ -102,30 +102,31 @@ namespace NzbDrone.Common.Test } [Test] - public void get_actual_casing_for_none_existing_file_should_throw() + public void get_actual_casing_for_none_existing_file_return_partially_fixed_result() { WindowsOnly(); - Assert.Throws(() => "C:\\InValidFolder\\invalidfile.exe".GetActualCasing()); + "C:\\WINDOWS\\invalidfile.exe".GetActualCasing().Should().Be("C:\\Windows\\invalidfile.exe"); } + [Test] - public void get_actual_casing_should_return_actual_casing_for_local_file_in_windows() + public void get_actual_casing_for_none_existing_folder_return_partially_fixed_result() { WindowsOnly(); - var path = Process.GetCurrentProcess().MainModule.FileName; - path.ToUpper().GetActualCasing().Should().Be(path); - path.ToLower().GetActualCasing().Should().Be(path); + "C:\\WINDOWS\\SYSTEM32\\FAKEFOLDER\\invalidfile.exe".GetActualCasing().Should().Be("C:\\Windows\\System32\\FAKEFOLDER\\invalidfile.exe"); } [Test] - public void get_actual_casing_should_return_origibal_value_in_linux() + public void get_actual_casing_should_return_actual_casing_for_local_file_in_windows() { - LinuxOnly(); + WindowsOnly(); var path = Process.GetCurrentProcess().MainModule.FileName; - path.GetActualCasing().Should().Be(path); - path.GetActualCasing().Should().Be(path); + path.ToUpper().GetActualCasing().Should().Be(path); + path.ToLower().GetActualCasing().Should().Be(path); } + + [Test] public void get_actual_casing_should_return_actual_casing_for_local_dir_in_windows() { diff --git a/NzbDrone.Common/PathExtensions.cs b/NzbDrone.Common/PathExtensions.cs index 15e3b8a08..b5e899eba 100644 --- a/NzbDrone.Common/PathExtensions.cs +++ b/NzbDrone.Common/PathExtensions.cs @@ -63,23 +63,27 @@ namespace NzbDrone.Common public static string GetActualCasing(this string path) { - var attributes = File.GetAttributes(path); - if (OsInfo.IsLinux || path.StartsWith("\\")) { return path; } - if ((attributes & FileAttributes.Directory) == FileAttributes.Directory) + if (Directory.Exists(path) && (File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory) { return GetProperCapitalization(new DirectoryInfo(path)); } var fileInfo = new FileInfo(path); + var dirInfo = fileInfo.Directory; + + var fileName = fileInfo.Name; + if (dirInfo != null && fileInfo.Exists) + { + fileName = dirInfo.GetFiles(fileInfo.Name)[0].Name; + } - DirectoryInfo dirInfo = fileInfo.Directory; - return Path.Combine(GetProperCapitalization(dirInfo), dirInfo.GetFiles(fileInfo.Name)[0].Name); + return Path.Combine(GetProperCapitalization(dirInfo), fileName); } public static string GetAppDataPath(this IAppFolderInfo appFolderInfo) From a22cbfee2fc5526f95f557ddbdbe59e7919fcd34 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 18:32:25 -0700 Subject: [PATCH 27/58] handle empty rss response from indexers. --- NzbDrone.Core/Indexers/BasicRssParser.cs | 46 ++++++++++--------- NzbDrone.Core/Indexers/IndexerFetchService.cs | 12 ++++- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/NzbDrone.Core/Indexers/BasicRssParser.cs b/NzbDrone.Core/Indexers/BasicRssParser.cs index d29889248..17963956c 100644 --- a/NzbDrone.Core/Indexers/BasicRssParser.cs +++ b/NzbDrone.Core/Indexers/BasicRssParser.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Text.RegularExpressions; +using System.Xml; using System.Xml.Linq; using NLog; using NzbDrone.Core.Parser.Model; @@ -12,7 +13,7 @@ namespace NzbDrone.Core.Indexers { public interface IParseFeed { - IEnumerable Process(Stream source, string url); + IEnumerable Process(string xml, string url); } public class BasicRssParser : IParseFeed @@ -24,34 +25,37 @@ namespace NzbDrone.Core.Indexers _logger = LogManager.GetCurrentClassLogger(); } - public IEnumerable Process(Stream source, string url) + public IEnumerable Process(string xml, string url) { - var document = XDocument.Load(source); - var items = document.Descendants("item"); + using (var xmlTextReader = new XmlTextReader(new StringReader(xml)) { DtdProcessing = DtdProcessing.Ignore }) + { + var document = XDocument.Load(xmlTextReader); + var items = document.Descendants("item"); - var result = new List(); + var result = new List(); - foreach (var item in items) - { - try + foreach (var item in items) { - var reportInfo = ParseFeedItem(item); - if (reportInfo != null) + try { - reportInfo.NzbUrl = GetNzbUrl(item); - reportInfo.NzbInfoUrl = GetNzbInfoUrl(item); - - result.Add(reportInfo); + var reportInfo = ParseFeedItem(item); + if (reportInfo != null) + { + reportInfo.NzbUrl = GetNzbUrl(item); + reportInfo.NzbInfoUrl = GetNzbInfoUrl(item); + + result.Add(reportInfo); + } + } + catch (Exception itemEx) + { + itemEx.Data.Add("Item", item.Title()); + _logger.ErrorException("An error occurred while processing feed item from " + url, itemEx); } } - catch (Exception itemEx) - { - itemEx.Data.Add("Item", item.Title()); - _logger.ErrorException("An error occurred while processing feed item from " + url, itemEx); - } - } - return result; + return result; + } } diff --git a/NzbDrone.Core/Indexers/IndexerFetchService.cs b/NzbDrone.Core/Indexers/IndexerFetchService.cs index 6c46032b6..63a2c5e6b 100644 --- a/NzbDrone.Core/Indexers/IndexerFetchService.cs +++ b/NzbDrone.Core/Indexers/IndexerFetchService.cs @@ -106,8 +106,16 @@ namespace NzbDrone.Core.Indexers try { _logger.Trace("Downloading Feed " + url); - var stream = _httpProvider.DownloadStream(url); - result.AddRange(indexer.Parser.Process(stream, url)); + var xml = _httpProvider.DownloadString(url); + if (!string.IsNullOrWhiteSpace(xml)) + { + result.AddRange(indexer.Parser.Process(xml, url)); + } + else + { + _logger.Warn("{0} returned empty response.", url); + } + } catch (WebException webException) { From 47e29abc2767a200d373e049a4aa6d305624c701 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 18:38:43 -0700 Subject: [PATCH 28/58] don't log indexer errors as exceptions. --- NzbDrone.Core/Indexers/IndexerFetchService.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/NzbDrone.Core/Indexers/IndexerFetchService.cs b/NzbDrone.Core/Indexers/IndexerFetchService.cs index 63a2c5e6b..2e585f862 100644 --- a/NzbDrone.Core/Indexers/IndexerFetchService.cs +++ b/NzbDrone.Core/Indexers/IndexerFetchService.cs @@ -119,14 +119,13 @@ namespace NzbDrone.Core.Indexers } catch (WebException webException) { - if (webException.Message.Contains("503") || webException.Message.Contains("timed out")) + if (webException.Message.Contains("502") || webException.Message.Contains("503") || webException.Message.Contains("timed out")) { _logger.Warn("{0} server is currently unavailable. {1} {2}", indexer.Name, url, webException.Message); } else { - webException.Data.Add("FeedUrl", url); - _logger.WarnException("An error occurred while processing feed. " + url, webException); + _logger.Warn("{0} {1} {2}", indexer.Name, url, webException.Message); } } catch (Exception feedEx) From 76c7d75c31cc914d097d44289c135c504e2bffca Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 18:55:42 -0700 Subject: [PATCH 29/58] added some test for free space. --- .../DiskProviderTests/FreeSpaceFixture.cs | 40 +++++++++++++++++++ .../DiskProviderTests/IsParentFixture.cs | 24 +++++------ .../NzbDrone.Common.Test.csproj | 1 + 3 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 NzbDrone.Common.Test/DiskProviderTests/FreeSpaceFixture.cs diff --git a/NzbDrone.Common.Test/DiskProviderTests/FreeSpaceFixture.cs b/NzbDrone.Common.Test/DiskProviderTests/FreeSpaceFixture.cs new file mode 100644 index 000000000..8359ad481 --- /dev/null +++ b/NzbDrone.Common.Test/DiskProviderTests/FreeSpaceFixture.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Test.Common; + +namespace NzbDrone.Common.Test.DiskProviderTests +{ + [TestFixture] + public class IsParentFixture : TestBase + { + private string _parent = @"C:\Test".AsOsAgnostic(); + + [Test] + public void should_return_false_when_not_a_child() + { + var path = @"C:\Another Folder".AsOsAgnostic(); + + Subject.IsParent(_parent, path).Should().BeFalse(); + } + + [Test] + public void should_return_true_when_folder_is_parent_of_another_folder() + { + var path = @"C:\Test\TV".AsOsAgnostic(); + + Subject.IsParent(_parent, path).Should().BeTrue(); + } + + [Test] + public void should_return_true_when_folder_is_parent_of_a_file() + { + var path = @"C:\Test\30.Rock.S01E01.Pilot.avi".AsOsAgnostic(); + + Subject.IsParent(_parent, path).Should().BeTrue(); + } + } +} diff --git a/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs b/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs index 8359ad481..a17595a6e 100644 --- a/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs +++ b/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using FluentAssertions; @@ -9,32 +10,31 @@ using NzbDrone.Test.Common; namespace NzbDrone.Common.Test.DiskProviderTests { [TestFixture] - public class IsParentFixture : TestBase + public class FreeSpaceFixture : TestBase { - private string _parent = @"C:\Test".AsOsAgnostic(); - [Test] - public void should_return_false_when_not_a_child() + public void should_get_free_space_for_folder() { - var path = @"C:\Another Folder".AsOsAgnostic(); + var path = @"C:\".AsOsAgnostic(); - Subject.IsParent(_parent, path).Should().BeFalse(); + Subject.GetAvilableSpace(path).Should().NotBe(0); } [Test] - public void should_return_true_when_folder_is_parent_of_another_folder() + public void should_get_free_space_for_folder_that_doesnt_exist() { - var path = @"C:\Test\TV".AsOsAgnostic(); + var path = @"C:\".AsOsAgnostic(); - Subject.IsParent(_parent, path).Should().BeTrue(); + Subject.GetAvilableSpace(Path.Combine(path, "invalidFolder")).Should().NotBe(0); } + [Test] - public void should_return_true_when_folder_is_parent_of_a_file() + public void should_get_free_space_for_drive_that_doesnt_exist() { - var path = @"C:\Test\30.Rock.S01E01.Pilot.avi".AsOsAgnostic(); + WindowsOnly(); - Subject.IsParent(_parent, path).Should().BeTrue(); + Subject.GetAvilableSpace("J:\\").Should().NotBe(0); } } } diff --git a/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj b/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj index 1dd3ccd78..15bb183ee 100644 --- a/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj +++ b/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj @@ -62,6 +62,7 @@ + From 84857f286a20124f76edfb5966d58484ccfbc911 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 19:00:40 -0700 Subject: [PATCH 30/58] handle exceptions when getting header for covers fail. --- NzbDrone.Core/MediaCover/MediaCoverService.cs | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/NzbDrone.Core/MediaCover/MediaCoverService.cs b/NzbDrone.Core/MediaCover/MediaCoverService.cs index 99f10e4e7..b14a6bcb3 100644 --- a/NzbDrone.Core/MediaCover/MediaCoverService.cs +++ b/NzbDrone.Core/MediaCover/MediaCoverService.cs @@ -44,30 +44,31 @@ namespace NzbDrone.Core.MediaCover foreach (var cover in series.Images) { var fileName = GetCoverPath(series.Id, cover.CoverType); - if (!_coverExistsSpecification.AlreadyExists(cover.Url, fileName)) + try { - DownloadCover(series, cover); + if (!_coverExistsSpecification.AlreadyExists(cover.Url, fileName)) + { + DownloadCover(series, cover); + } + } + catch (WebException e) + { + _logger.Warn(string.Format("Couldn't download media cover for {0}. {1}", series, e.Message); + } + catch (Exception e) + { + _logger.ErrorException("Couldn't download media cover for " + series, e); } } } private void DownloadCover(Series series, MediaCover cover) { - try - { - var fileName = GetCoverPath(series.Id, cover.CoverType); + var fileName = GetCoverPath(series.Id, cover.CoverType); + + _logger.Info("Downloading {0} for {1} {2}", cover.CoverType, series, cover.Url); + _httpProvider.DownloadFile(cover.Url, fileName); - _logger.Info("Downloading {0} for {1} {2}", cover.CoverType, series, cover.Url); - _httpProvider.DownloadFile(cover.Url, fileName); - } - catch (WebException e) - { - _logger.Warn("Couldn't download media cover for " + series); - } - catch (Exception e) - { - _logger.ErrorException("Couldn't download media cover for " + series, e); - } } public void HandleAsync(SeriesDeletedEvent message) From 25e6473537f9cc45c42b678d9f9dc7dba2961647 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 19:05:33 -0700 Subject: [PATCH 31/58] fixed broken build. --- NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs | 2 +- NzbDrone.Core/MediaCover/MediaCoverService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs b/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs index a17595a6e..bc52f482b 100644 --- a/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs +++ b/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs @@ -34,7 +34,7 @@ namespace NzbDrone.Common.Test.DiskProviderTests { WindowsOnly(); - Subject.GetAvilableSpace("J:\\").Should().NotBe(0); + Assert.Throws(() => Subject.GetAvilableSpace("J:\\").Should().NotBe(0)); } } } diff --git a/NzbDrone.Core/MediaCover/MediaCoverService.cs b/NzbDrone.Core/MediaCover/MediaCoverService.cs index b14a6bcb3..e3d247bfa 100644 --- a/NzbDrone.Core/MediaCover/MediaCoverService.cs +++ b/NzbDrone.Core/MediaCover/MediaCoverService.cs @@ -53,7 +53,7 @@ namespace NzbDrone.Core.MediaCover } catch (WebException e) { - _logger.Warn(string.Format("Couldn't download media cover for {0}. {1}", series, e.Message); + _logger.Warn(string.Format("Couldn't download media cover for {0}. {1}", series, e.Message)); } catch (Exception e) { From 3e65c393fdceb487dcb8ee397fe58dbf8fc3f34c Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 19:10:43 -0700 Subject: [PATCH 32/58] fixed broken test --- NzbDrone.Common/PathExtensions.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/NzbDrone.Common/PathExtensions.cs b/NzbDrone.Common/PathExtensions.cs index b5e899eba..374d2372a 100644 --- a/NzbDrone.Common/PathExtensions.cs +++ b/NzbDrone.Common/PathExtensions.cs @@ -58,7 +58,15 @@ namespace NzbDrone.Common //Drive letter return dirInfo.Name.ToUpper(); } - return Path.Combine(GetProperCapitalization(parentDirInfo), parentDirInfo.GetDirectories(dirInfo.Name)[0].Name); + + var folderName = dirInfo.Name; + + if (dirInfo.Exists) + { + folderName = parentDirInfo.GetDirectories(dirInfo.Name)[0].Name; + } + + return Path.Combine(GetProperCapitalization(parentDirInfo), folderName); } public static string GetActualCasing(this string path) From 87ac2b3b763ce89f2f439b46795da0a996b8930c Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 19:27:23 -0700 Subject: [PATCH 33/58] fixed Dtd issues on Linux. --- NzbDrone.Common/Services.cs | 3 --- .../IndexerTests/IntegrationTests/IndexerIntegrationTests.cs | 4 ++-- .../DataAugmentation/DailySeries/DailySeriesDataProxy.cs | 1 - NzbDrone.Core/Indexers/BasicRssParser.cs | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/NzbDrone.Common/Services.cs b/NzbDrone.Common/Services.cs index bfa537901..0824c4735 100644 --- a/NzbDrone.Common/Services.cs +++ b/NzbDrone.Common/Services.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace NzbDrone.Common { diff --git a/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs b/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs index d052503a9..813c1a45f 100644 --- a/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs +++ b/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs @@ -44,17 +44,17 @@ namespace NzbDrone.Core.Test.IndexerTests.IntegrationTests [Test] - [Explicit("needs newznab api key")] public void nzbsorg_rss() { var indexer = new Newznab(); indexer.Settings = new NewznabSettings { - ApiKey = "", + ApiKey = "64d61d3cfd4b75e51d01cbc7c6a78275", Url = "http://nzbs.org" }; indexer.InstanceDefinition = new IndexerDefinition(); + indexer.InstanceDefinition.Name = "nzbs.org"; var result = Subject.FetchRss(indexer); diff --git a/NzbDrone.Core/DataAugmentation/DailySeries/DailySeriesDataProxy.cs b/NzbDrone.Core/DataAugmentation/DailySeries/DailySeriesDataProxy.cs index 239afecc8..f59ff9ee9 100644 --- a/NzbDrone.Core/DataAugmentation/DailySeries/DailySeriesDataProxy.cs +++ b/NzbDrone.Core/DataAugmentation/DailySeries/DailySeriesDataProxy.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using NLog; using NzbDrone.Common; using NzbDrone.Common.Serializer; -using NzbDrone.Core.Configuration; namespace NzbDrone.Core.DataAugmentation.DailySeries { diff --git a/NzbDrone.Core/Indexers/BasicRssParser.cs b/NzbDrone.Core/Indexers/BasicRssParser.cs index 17963956c..84c61f296 100644 --- a/NzbDrone.Core/Indexers/BasicRssParser.cs +++ b/NzbDrone.Core/Indexers/BasicRssParser.cs @@ -27,7 +27,7 @@ namespace NzbDrone.Core.Indexers public IEnumerable Process(string xml, string url) { - using (var xmlTextReader = new XmlTextReader(new StringReader(xml)) { DtdProcessing = DtdProcessing.Ignore }) + using (var xmlTextReader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings { ProhibitDtd = false, IgnoreComments = true })) { var document = XDocument.Load(xmlTextReader); var items = document.Descendants("item"); From b8bd2bffbf133f10e54b2de200f317be0a9af55a Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 22:20:41 -0700 Subject: [PATCH 34/58] db stores logs for 7 days instead of 15. --- NzbDrone.Core/Instrumentation/LogRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NzbDrone.Core/Instrumentation/LogRepository.cs b/NzbDrone.Core/Instrumentation/LogRepository.cs index 5fe755580..0a00aa27b 100644 --- a/NzbDrone.Core/Instrumentation/LogRepository.cs +++ b/NzbDrone.Core/Instrumentation/LogRepository.cs @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Instrumentation public void Trim() { - var trimDate = DateTime.UtcNow.AddDays(-15).Date; + var trimDate = DateTime.UtcNow.AddDays(-7).Date; Delete(c => c.Time <= trimDate); } } From e256271c5c321cded971867ceb1e467ef43f93f7 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 23:38:55 -0700 Subject: [PATCH 35/58] store scene name in history --- .../016_updated_imported_history_item.cs | 14 ++++++++++++++ NzbDrone.Core/History/HistoryService.cs | 15 ++++++++------- .../EpisodeImport/ImportApprovedEpisodes.cs | 6 ++++-- .../MediaFiles/Events/EpisodeImportedEvent.cs | 9 ++++++--- NzbDrone.Core/NzbDrone.Core.csproj | 1 + .../Details/HistoryDetailsViewTemplate.html | 12 ++++++------ 6 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 NzbDrone.Core/Datastore/Migration/016_updated_imported_history_item.cs diff --git a/NzbDrone.Core/Datastore/Migration/016_updated_imported_history_item.cs b/NzbDrone.Core/Datastore/Migration/016_updated_imported_history_item.cs new file mode 100644 index 000000000..7a2c50e71 --- /dev/null +++ b/NzbDrone.Core/Datastore/Migration/016_updated_imported_history_item.cs @@ -0,0 +1,14 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(16)] + public class updated_imported_history_item : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Execute.Sql(@"UPDATE HISTORY SET Data = replace( Data, '""Path""', '""ImportedPath""' ) WHERE EventType=3"); + } + } +} diff --git a/NzbDrone.Core/History/HistoryService.cs b/NzbDrone.Core/History/HistoryService.cs index 40f637fcf..349d81c08 100644 --- a/NzbDrone.Core/History/HistoryService.cs +++ b/NzbDrone.Core/History/HistoryService.cs @@ -62,7 +62,7 @@ namespace NzbDrone.Core.History { var history = new History { - EventType = HistoryEventType.Grabbed, + EventType = HistoryEventType.Grabbed, Date = DateTime.UtcNow, Quality = message.Episode.ParsedEpisodeInfo.Quality, SourceTitle = message.Episode.Report.Title, @@ -81,20 +81,21 @@ namespace NzbDrone.Core.History public void Handle(EpisodeImportedEvent message) { - foreach (var episode in message.EpisodeFile.Episodes.Value) + foreach (var episode in message.DroppedEpisode.Episodes) { var history = new History { EventType = HistoryEventType.DownloadFolderImported, Date = DateTime.UtcNow, - Quality = message.EpisodeFile.Quality, - SourceTitle = message.EpisodeFile.Path, - SeriesId = message.EpisodeFile.SeriesId, + Quality = message.DroppedEpisode.Quality, + SourceTitle = message.ImportedEpisode.SceneName, + SeriesId = message.ImportedEpisode.SeriesId, EpisodeId = episode.Id }; - history.Data.Add("Path", message.EpisodeFile.Path); - history.Data.Add("Filename", Path.GetFileNameWithoutExtension(message.EpisodeFile.Path)); + history.Data.Add("FileId", message.ImportedEpisode.Id.ToString()); + history.Data.Add("DroppedPath", message.DroppedEpisode.Path); + history.Data.Add("ImportedPath", message.ImportedEpisode.Path); _historyRepository.Insert(history); } diff --git a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs index 0757b1495..539bb8ccd 100644 --- a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs +++ b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs @@ -65,12 +65,14 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport episodeFile.SceneName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath()); episodeFile.Episodes = localEpisode.Episodes; + if (newDownload) { episodeFile = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode); - _messageAggregator.PublishEvent(new EpisodeImportedEvent(episodeFile)); + _messageAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile)); } - + + _mediaFileService.Add(episodeFile); imported.Add(importDecision); } diff --git a/NzbDrone.Core/MediaFiles/Events/EpisodeImportedEvent.cs b/NzbDrone.Core/MediaFiles/Events/EpisodeImportedEvent.cs index 9c8e59cdc..2f166b069 100644 --- a/NzbDrone.Core/MediaFiles/Events/EpisodeImportedEvent.cs +++ b/NzbDrone.Core/MediaFiles/Events/EpisodeImportedEvent.cs @@ -1,14 +1,17 @@ using NzbDrone.Common.Messaging; +using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.MediaFiles.Events { public class EpisodeImportedEvent : IEvent { - public EpisodeFile EpisodeFile { get; private set; } + public LocalEpisode DroppedEpisode { get; private set; } + public EpisodeFile ImportedEpisode { get; private set; } - public EpisodeImportedEvent(EpisodeFile episodeFile) + public EpisodeImportedEvent(LocalEpisode droppedEpisode, EpisodeFile importedEpisode) { - EpisodeFile = episodeFile; + DroppedEpisode = droppedEpisode; + ImportedEpisode = importedEpisode; } } } \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 9ed55a6ff..26f5df9b8 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -158,6 +158,7 @@ + diff --git a/UI/History/Details/HistoryDetailsViewTemplate.html b/UI/History/Details/HistoryDetailsViewTemplate.html index 832573e9e..5d15ca7b4 100644 --- a/UI/History/Details/HistoryDetailsViewTemplate.html +++ b/UI/History/Details/HistoryDetailsViewTemplate.html @@ -35,14 +35,14 @@ {{#if data}} {{#with data}}
- {{#if filename}} -
Filename
-
{{filename}}
+ {{#if droppedPath}} +
Source:
+
{{droppedPath}}
{{/if}} - {{#if path}} -
Path
-
{{path}}
+ {{#if importedPath}} +
Imported To:
+
{{importedPath}}
{{/if}}
{{/with}} From 954a79639fc5cf15b758a0e3ec4d7298a7c55e15 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 23:39:41 -0700 Subject: [PATCH 36/58] moveepisode is less side-effecty! --- .../ImportApprovedEpisodesFixture.cs | 3 +-- .../RenameEpisodeFileServiceFixture.cs | 3 +-- NzbDrone.Core/History/HistoryService.cs | 3 ++- .../MediaFiles/EpisodeFileMovingService.cs | 27 +++++++------------ .../EpisodeImport/ImportApprovedEpisodes.cs | 6 ++--- .../MediaFiles/UpgradeMediaFileService.cs | 4 +-- 6 files changed, 19 insertions(+), 27 deletions(-) diff --git a/NzbDrone.Core.Test/MediaFileTests/ImportApprovedEpisodesFixture.cs b/NzbDrone.Core.Test/MediaFileTests/ImportApprovedEpisodesFixture.cs index 9e34a5882..a7d13ff0c 100644 --- a/NzbDrone.Core.Test/MediaFileTests/ImportApprovedEpisodesFixture.cs +++ b/NzbDrone.Core.Test/MediaFileTests/ImportApprovedEpisodesFixture.cs @@ -53,8 +53,7 @@ namespace NzbDrone.Core.Test.MediaFileTests } Mocker.GetMock() - .Setup(s => s.UpgradeEpisodeFile(It.IsAny(), It.IsAny())) - .Returns(new EpisodeFile()); + .Setup(s => s.UpgradeEpisodeFile(It.IsAny(), It.IsAny())); } [Test] diff --git a/NzbDrone.Core.Test/MediaFileTests/RenameEpisodeFileServiceFixture.cs b/NzbDrone.Core.Test/MediaFileTests/RenameEpisodeFileServiceFixture.cs index dbdf35b56..80b4dc855 100644 --- a/NzbDrone.Core.Test/MediaFileTests/RenameEpisodeFileServiceFixture.cs +++ b/NzbDrone.Core.Test/MediaFileTests/RenameEpisodeFileServiceFixture.cs @@ -60,8 +60,7 @@ namespace NzbDrone.Core.Test.MediaFileTests private void GivenMovedFiles() { Mocker.GetMock() - .Setup(s => s.MoveEpisodeFile(It.IsAny(), _series)) - .Returns(_episodeFiles.First()); + .Setup(s => s.MoveEpisodeFile(It.IsAny(), _series)); } [Test] diff --git a/NzbDrone.Core/History/HistoryService.cs b/NzbDrone.Core/History/HistoryService.cs index 349d81c08..c0752eb2a 100644 --- a/NzbDrone.Core/History/HistoryService.cs +++ b/NzbDrone.Core/History/HistoryService.cs @@ -93,7 +93,8 @@ namespace NzbDrone.Core.History EpisodeId = episode.Id }; - history.Data.Add("FileId", message.ImportedEpisode.Id.ToString()); + //Won't have a value since we publish this event before saving to DB. + //history.Data.Add("FileId", message.ImportedEpisode.Id.ToString()); history.Data.Add("DroppedPath", message.DroppedEpisode.Path); history.Data.Add("ImportedPath", message.ImportedEpisode.Path); diff --git a/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs b/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs index e46bf3b26..e7a03d22a 100644 --- a/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs +++ b/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs @@ -13,8 +13,8 @@ namespace NzbDrone.Core.MediaFiles { public interface IMoveEpisodeFiles { - EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, Series series); - EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode); + string MoveEpisodeFile(EpisodeFile episodeFile, Series series); + string MoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode); } public class MoveEpisodeFiles : IMoveEpisodeFiles @@ -38,27 +38,24 @@ namespace NzbDrone.Core.MediaFiles _logger = logger; } - public EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, Series series) + public string MoveEpisodeFile(EpisodeFile episodeFile, Series series) { var episodes = _episodeService.GetEpisodesByFileId(episodeFile.Id); var newFileName = _buildFileNames.BuildFilename(episodes, series, episodeFile); - var destinationFilename = _buildFileNames.BuildFilePath(series, episodes.First().SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path)); + var filePath = _buildFileNames.BuildFilePath(series, episodes.First().SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path)); - return MoveFile(episodeFile, destinationFilename); + return filePath; } - public EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode) + public string MoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode) { var newFileName = _buildFileNames.BuildFilename(localEpisode.Episodes, localEpisode.Series, episodeFile); - var destinationFilename = _buildFileNames.BuildFilePath(localEpisode.Series, localEpisode.SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path)); - episodeFile = MoveFile(episodeFile, destinationFilename); - - _messageAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode)); - - return episodeFile; + var filePath = _buildFileNames.BuildFilePath(localEpisode.Series, localEpisode.SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path)); + MoveFile(episodeFile, filePath); + return filePath; } - private EpisodeFile MoveFile(EpisodeFile episodeFile, string destinationFilename) + private void MoveFile(EpisodeFile episodeFile, string destinationFilename) { if (!_diskProvider.FileExists(episodeFile.Path)) { @@ -85,10 +82,6 @@ namespace NzbDrone.Core.MediaFiles _logger.Debug("Unable to apply folder permissions to: ", destinationFilename); _logger.TraceException(ex.Message, ex); } - - episodeFile.Path = destinationFilename; - - return episodeFile; } } } \ No newline at end of file diff --git a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs index 539bb8ccd..087f29e68 100644 --- a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs +++ b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs @@ -13,7 +13,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport { List Import(List decisions, bool newDownloads = false); } - + public class ImportApprovedEpisodes : IImportApprovedEpisodes { private readonly IUpgradeMediaFiles _episodeFileUpgrader; @@ -68,10 +68,10 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport if (newDownload) { - episodeFile = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode); + episodeFile.Path = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode); _messageAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile)); + _messageAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode)); } - _mediaFileService.Add(episodeFile); imported.Add(importDecision); diff --git a/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs b/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs index c272e9197..75ee6869e 100644 --- a/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs +++ b/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs @@ -7,7 +7,7 @@ namespace NzbDrone.Core.MediaFiles { public interface IUpgradeMediaFiles { - EpisodeFile UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode); + string UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode); } public class UpgradeMediaFileService : IUpgradeMediaFiles @@ -31,7 +31,7 @@ namespace NzbDrone.Core.MediaFiles _logger = logger; } - public EpisodeFile UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode) + public string UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode) { var existingFiles = localEpisode.Episodes .Where(e => e.EpisodeFileId > 0) From c25b92955f0fd68ba66d6b235db8823488eab172 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 23:41:49 -0700 Subject: [PATCH 37/58] moveepisode is less side-effecty! --- NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs b/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs index f6737a9ef..7912039e7 100644 --- a/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs +++ b/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs @@ -34,14 +34,12 @@ namespace NzbDrone.Core.MediaFiles { var renamed = new List(); - foreach (var file in episodeFiles) + foreach (var episodeFile in episodeFiles) { try { - var episodeFile = file; - _logger.Trace("Renaming episode file: {0}", episodeFile); - episodeFile = _episodeFileMover.MoveEpisodeFile(episodeFile, series); + episodeFile.Path = _episodeFileMover.MoveEpisodeFile(episodeFile, series); _mediaFileService.Update(episodeFile); renamed.Add(episodeFile); @@ -54,7 +52,7 @@ namespace NzbDrone.Core.MediaFiles } catch (Exception ex) { - _logger.ErrorException("Failed to rename file: " + file.Path, ex); + _logger.ErrorException("Failed to rename file: " + episodeFile.Path, ex); } } From dd835d55033c7cdf5c4e279cb56635631b4b84b9 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 29 Aug 2013 23:50:43 -0700 Subject: [PATCH 38/58] clear existing scene name since it wasn't storing the correct string --- .../Datastore/Migration/017_reset_scene_names.cs | 15 +++++++++++++++ .../EpisodeImport/ImportApprovedEpisodes.cs | 2 +- NzbDrone.Core/NzbDrone.Core.csproj | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 NzbDrone.Core/Datastore/Migration/017_reset_scene_names.cs diff --git a/NzbDrone.Core/Datastore/Migration/017_reset_scene_names.cs b/NzbDrone.Core/Datastore/Migration/017_reset_scene_names.cs new file mode 100644 index 000000000..e2e3a21d6 --- /dev/null +++ b/NzbDrone.Core/Datastore/Migration/017_reset_scene_names.cs @@ -0,0 +1,15 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(17)] + public class reset_scene_names : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + //we were storing new file name as scene name. + Execute.Sql(@"UPDATE EpisodeFiles SET SceneName = NULL where SceneName != NULL"); + } + } +} diff --git a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs index 087f29e68..733b8580d 100644 --- a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs +++ b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs @@ -62,12 +62,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport episodeFile.Size = _diskProvider.GetFileSize(localEpisode.Path); episodeFile.Quality = localEpisode.Quality; episodeFile.SeasonNumber = localEpisode.SeasonNumber; - episodeFile.SceneName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath()); episodeFile.Episodes = localEpisode.Episodes; if (newDownload) { + episodeFile.SceneName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath()); episodeFile.Path = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode); _messageAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile)); _messageAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode)); diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 26f5df9b8..82fd0aa60 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -159,6 +159,7 @@ + From 7a19b6a2b3af7ca988a5111773b870641db0fe1b Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Fri, 30 Aug 2013 15:55:01 -0700 Subject: [PATCH 39/58] Host process cleanup. --- NzbDrone.Console/ConsoleApp.cs | 5 ++- .../AccessControl/FirewallAdapter.cs | 38 ++----------------- NzbDrone.Host/AccessControl/UrlAclAdapter.cs | 16 ++++++-- NzbDrone.Host/ApplicationServer.cs | 13 +------ NzbDrone.Host/Owin/IHostController.cs | 1 - NzbDrone.Host/Owin/OwinHostController.cs | 29 ++++++++------ NzbDrone/NzbDrone.csproj | 4 ++ NzbDrone/WindowsApp.cs | 4 ++ NzbDrone/packages.config | 1 + 9 files changed, 46 insertions(+), 65 deletions(-) diff --git a/NzbDrone.Console/ConsoleApp.cs b/NzbDrone.Console/ConsoleApp.cs index 586027a54..726139f8a 100644 --- a/NzbDrone.Console/ConsoleApp.cs +++ b/NzbDrone.Console/ConsoleApp.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using NLog; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Host; @@ -7,6 +8,8 @@ namespace NzbDrone.Console { public static class ConsoleApp { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + public static void Main(string[] args) { try @@ -18,7 +21,7 @@ namespace NzbDrone.Console } catch (Exception e) { - System.Console.WriteLine(e.ToString()); + Logger.FatalException(e.Message, e); System.Console.ReadLine(); } diff --git a/NzbDrone.Host/AccessControl/FirewallAdapter.cs b/NzbDrone.Host/AccessControl/FirewallAdapter.cs index 96fb87679..72d194446 100644 --- a/NzbDrone.Host/AccessControl/FirewallAdapter.cs +++ b/NzbDrone.Host/AccessControl/FirewallAdapter.cs @@ -1,6 +1,7 @@ using System; using NetFwTypeLib; using NLog; +using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Configuration; namespace NzbDrone.Host.AccessControl @@ -31,9 +32,6 @@ namespace NzbDrone.Host.AccessControl return; } - CloseFirewallPort(); - - //Open the new port OpenFirewallPort(_configFileProvider.Port); } } @@ -91,38 +89,10 @@ namespace NzbDrone.Host.AccessControl } } - private void CloseFirewallPort() - { - try - { - var netFwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr", false); - var mgr = (INetFwMgr)Activator.CreateInstance(netFwMgrType); - var ports = mgr.LocalPolicy.CurrentProfile.GloballyOpenPorts; - - var portNumber = 8989; - - foreach (INetFwOpenPort p in ports) - { - if (p.Name == "NzbDrone") - { - portNumber = p.Port; - break; - } - } - - if (portNumber != _configFileProvider.Port) - { - ports.Remove(portNumber, NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP); - } - } - catch (Exception ex) - { - _logger.WarnException("Failed to close port in firewall for NzbDrone", ex); - } - } - private bool IsFirewallEnabled() { + if (OsInfo.IsLinux) return false; + try { var netFwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr", false); @@ -135,7 +105,5 @@ namespace NzbDrone.Host.AccessControl return false; } } - - } } diff --git a/NzbDrone.Host/AccessControl/UrlAclAdapter.cs b/NzbDrone.Host/AccessControl/UrlAclAdapter.cs index c7e1480d6..e536fffbd 100644 --- a/NzbDrone.Host/AccessControl/UrlAclAdapter.cs +++ b/NzbDrone.Host/AccessControl/UrlAclAdapter.cs @@ -9,6 +9,7 @@ namespace NzbDrone.Host.AccessControl public interface IUrlAclAdapter { void RefreshRegistration(); + string UrlAcl { get; } } public class UrlAclAdapter : IUrlAclAdapter @@ -24,18 +25,25 @@ namespace NzbDrone.Host.AccessControl _logger = logger; } + public string UrlAcl + { + get + { + return "http://*:" + _configFileProvider.Port + "/"; + } + } + public void RefreshRegistration() { if (OsInfo.Version.Major < 6) return; - RegisterUrl(_configFileProvider.Port); + RegisterUrl(); } - - private void RegisterUrl(int portNumber) + private void RegisterUrl() { - var arguments = String.Format("http add urlacl http://*:{0}/ sddl=D:(A;;GX;;;S-1-1-0)", portNumber); + var arguments = String.Format("http add urlacl {0} sddl=D:(A;;GX;;;S-1-1-0)", UrlAcl); RunNetsh(arguments); } diff --git a/NzbDrone.Host/ApplicationServer.cs b/NzbDrone.Host/ApplicationServer.cs index b1abc00c5..d6e1e3625 100644 --- a/NzbDrone.Host/ApplicationServer.cs +++ b/NzbDrone.Host/ApplicationServer.cs @@ -4,7 +4,6 @@ using NLog; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Configuration; -using NzbDrone.Host.AccessControl; using NzbDrone.Host.Owin; namespace NzbDrone.Host @@ -23,13 +22,10 @@ namespace NzbDrone.Host private readonly IProcessProvider _processProvider; private readonly PriorityMonitor _priorityMonitor; private readonly IStartupArguments _startupArguments; - private readonly IFirewallAdapter _firewallAdapter; - private readonly IUrlAclAdapter _urlAclAdapter; private readonly Logger _logger; public NzbDroneServiceFactory(IConfigFileProvider configFileProvider, IHostController hostController, IRuntimeInfo runtimeInfo, - IProcessProvider processProvider, PriorityMonitor priorityMonitor, IStartupArguments startupArguments, - IFirewallAdapter firewallAdapter, IUrlAclAdapter urlAclAdapter, Logger logger) + IProcessProvider processProvider, PriorityMonitor priorityMonitor, IStartupArguments startupArguments, Logger logger) { _configFileProvider = configFileProvider; _hostController = hostController; @@ -37,8 +33,6 @@ namespace NzbDrone.Host _processProvider = processProvider; _priorityMonitor = priorityMonitor; _startupArguments = startupArguments; - _firewallAdapter = firewallAdapter; - _urlAclAdapter = urlAclAdapter; _logger = logger; } @@ -49,11 +43,6 @@ namespace NzbDrone.Host public void Start() { - if (OsInfo.IsWindows && _runtimeInfo.IsAdmin) - { - _urlAclAdapter.RefreshRegistration(); - _firewallAdapter.MakeAccessible(); - } _hostController.StartServer(); if (!_startupArguments.Flags.Contains(StartupArguments.NO_BROWSER) && diff --git a/NzbDrone.Host/Owin/IHostController.cs b/NzbDrone.Host/Owin/IHostController.cs index 9df77feb4..026bff89e 100644 --- a/NzbDrone.Host/Owin/IHostController.cs +++ b/NzbDrone.Host/Owin/IHostController.cs @@ -4,7 +4,6 @@ { string AppUrl { get; } void StartServer(); - void RestartServer(); void StopServer(); } } \ No newline at end of file diff --git a/NzbDrone.Host/Owin/OwinHostController.cs b/NzbDrone.Host/Owin/OwinHostController.cs index a571d5530..9968b22bb 100644 --- a/NzbDrone.Host/Owin/OwinHostController.cs +++ b/NzbDrone.Host/Owin/OwinHostController.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Owin.Hosting; using NLog; +using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Security; using NzbDrone.Core.Configuration; +using NzbDrone.Host.AccessControl; using NzbDrone.Host.Owin.MiddleWare; using Owin; @@ -14,13 +16,20 @@ namespace NzbDrone.Host.Owin { private readonly IConfigFileProvider _configFileProvider; private readonly IEnumerable _owinMiddleWares; + private readonly IRuntimeInfo _runtimeInfo; + private readonly IUrlAclAdapter _urlAclAdapter; + private readonly IFirewallAdapter _firewallAdapter; private readonly Logger _logger; private IDisposable _host; - public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable owinMiddleWares, Logger logger) + public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable owinMiddleWares, + IRuntimeInfo runtimeInfo, IUrlAclAdapter urlAclAdapter, IFirewallAdapter firewallAdapter, Logger logger) { _configFileProvider = configFileProvider; _owinMiddleWares = owinMiddleWares; + _runtimeInfo = runtimeInfo; + _urlAclAdapter = urlAclAdapter; + _firewallAdapter = firewallAdapter; _logger = logger; } @@ -28,14 +37,18 @@ namespace NzbDrone.Host.Owin { IgnoreCertErrorPolicy.Register(); - var url = "http://*:" + _configFileProvider.Port; + if (OsInfo.IsWindows && _runtimeInfo.IsAdmin) + { + _urlAclAdapter.RefreshRegistration(); + _firewallAdapter.MakeAccessible(); + } - var options = new StartOptions(url) + var options = new StartOptions(_urlAclAdapter.UrlAcl) { ServerFactory = "Microsoft.Owin.Host.HttpListener" }; - _logger.Info("starting server on {0}", url); + _logger.Info("starting server on {0}", _urlAclAdapter.UrlAcl); _host = WebApp.Start(OwinServiceProviderFactory.Create(), options, BuildApp); } @@ -56,14 +69,6 @@ namespace NzbDrone.Host.Owin get { return string.Format("http://localhost:{0}", _configFileProvider.Port); } } - public void RestartServer() - { - _logger.Warn("Attempting to restart server."); - - StopServer(); - StartServer(); - } - public void StopServer() { if (_host == null) return; diff --git a/NzbDrone/NzbDrone.csproj b/NzbDrone/NzbDrone.csproj index b599ed47b..5d45930cd 100644 --- a/NzbDrone/NzbDrone.csproj +++ b/NzbDrone/NzbDrone.csproj @@ -83,6 +83,10 @@ False ..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll
+ + False + ..\packages\NLog.2.0.1.2\lib\net40\NLog.dll + False ..\packages\Owin.1.0\lib\net40\Owin.dll diff --git a/NzbDrone/WindowsApp.cs b/NzbDrone/WindowsApp.cs index 0ded14d61..e144b82cc 100644 --- a/NzbDrone/WindowsApp.cs +++ b/NzbDrone/WindowsApp.cs @@ -1,5 +1,6 @@ using System; using System.Windows.Forms; +using NLog; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Host; using NzbDrone.SysTray; @@ -8,6 +9,8 @@ namespace NzbDrone { public static class WindowsApp { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + public static void Main(string[] args) { try @@ -21,6 +24,7 @@ namespace NzbDrone } catch (Exception e) { + Logger.FatalException(e.Message, e); var message = string.Format("{0}: {1}", e.GetType().Name, e.Message); MessageBox.Show(text: message, buttons: MessageBoxButtons.OK, icon: MessageBoxIcon.Error, caption: "Epic Fail!"); } diff --git a/NzbDrone/packages.config b/NzbDrone/packages.config index 907d39c5a..19f3a3d8b 100644 --- a/NzbDrone/packages.config +++ b/NzbDrone/packages.config @@ -5,5 +5,6 @@ + \ No newline at end of file From 298d6fe3bf3d457c398b61b2682b789ed73313f6 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Fri, 30 Aug 2013 19:45:44 -0700 Subject: [PATCH 40/58] fixed app startup --- NzbDrone.Console/ConsoleApp.cs | 3 --- NzbDrone/WindowsApp.cs | 2 -- 2 files changed, 5 deletions(-) diff --git a/NzbDrone.Console/ConsoleApp.cs b/NzbDrone.Console/ConsoleApp.cs index 726139f8a..3119cc811 100644 --- a/NzbDrone.Console/ConsoleApp.cs +++ b/NzbDrone.Console/ConsoleApp.cs @@ -8,8 +8,6 @@ namespace NzbDrone.Console { public static class ConsoleApp { - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - public static void Main(string[] args) { try @@ -21,7 +19,6 @@ namespace NzbDrone.Console } catch (Exception e) { - Logger.FatalException(e.Message, e); System.Console.ReadLine(); } diff --git a/NzbDrone/WindowsApp.cs b/NzbDrone/WindowsApp.cs index e144b82cc..4d4dc9d69 100644 --- a/NzbDrone/WindowsApp.cs +++ b/NzbDrone/WindowsApp.cs @@ -9,7 +9,6 @@ namespace NzbDrone { public static class WindowsApp { - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); public static void Main(string[] args) { @@ -24,7 +23,6 @@ namespace NzbDrone } catch (Exception e) { - Logger.FatalException(e.Message, e); var message = string.Format("{0}: {1}", e.GetType().Name, e.Message); MessageBox.Show(text: message, buttons: MessageBoxButtons.OK, icon: MessageBoxIcon.Error, caption: "Epic Fail!"); } From 4ffcf6b8c6a678c29102e0b652f288786e25b426 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Fri, 30 Aug 2013 23:10:08 -0700 Subject: [PATCH 41/58] updated deb control file. --- debian/control | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/debian/control b/debian/control index ed77723ae..32d1ac549 100644 --- a/debian/control +++ b/debian/control @@ -1,12 +1,11 @@ -Source: nzbdrone +Package: nzbdrone Section: web Priority: optional -Maintainer: NzbDrone Depends: libmono-cil-dev (>= 2.10.1) +Architecture: all +Maintainer: NzbDrone +Source: nzbdrone Homepage: http://www.nzbdrone.com Vcs-Git: git@github.com:NzbDrone/NzbDrone.git Vcs-Browser: https://github.com/NzbDrone/NzbDrone - -Package: nzbdrone -Architecture: all Description: NZBDrone is a PVR for newsgroup users From a4d92f0a31f0e7bdd411bafddc7aa1fe9e09dcfb Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 30 Aug 2013 23:25:31 -0700 Subject: [PATCH 42/58] Removed tooltip for quality profile name --- UI/Settings/Quality/Profile/EditQualityProfileTemplate.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/UI/Settings/Quality/Profile/EditQualityProfileTemplate.html b/UI/Settings/Quality/Profile/EditQualityProfileTemplate.html index 021a494d7..f45c97dda 100644 --- a/UI/Settings/Quality/Profile/EditQualityProfileTemplate.html +++ b/UI/Settings/Quality/Profile/EditQualityProfileTemplate.html @@ -12,9 +12,6 @@
- - -
From 8a71621de7f165261ddbfe4067d43bc0ffa3a0ca Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Fri, 30 Aug 2013 23:26:33 -0700 Subject: [PATCH 43/58] Update control --- debian/control | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/debian/control b/debian/control index 32d1ac549..d6e75940e 100644 --- a/debian/control +++ b/debian/control @@ -1,11 +1,13 @@ -Package: nzbdrone Section: web Priority: optional -Depends: libmono-cil-dev (>= 2.10.1) -Architecture: all Maintainer: NzbDrone Source: nzbdrone Homepage: http://www.nzbdrone.com Vcs-Git: git@github.com:NzbDrone/NzbDrone.git Vcs-Browser: https://github.com/NzbDrone/NzbDrone + + +Package: nzbdrone +Architecture: all +Depends: libmono-cil-dev (>= 2.10.1) Description: NZBDrone is a PVR for newsgroup users From bf9946b6538e1c3a81edda8f9473160623183d84 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Fri, 30 Aug 2013 23:26:51 -0700 Subject: [PATCH 44/58] Update control --- debian/control | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/control b/debian/control index d6e75940e..e7f6a7b11 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,6 @@ Homepage: http://www.nzbdrone.com Vcs-Git: git@github.com:NzbDrone/NzbDrone.git Vcs-Browser: https://github.com/NzbDrone/NzbDrone - Package: nzbdrone Architecture: all Depends: libmono-cil-dev (>= 2.10.1) From 4465d50a317694d7224ccafb454701f2629294f8 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sat, 31 Aug 2013 13:31:58 -0700 Subject: [PATCH 45/58] added path validation to add series/ recent folders. --- NzbDrone.Api/NzbDrone.Api.csproj | 1 + NzbDrone.Api/RootFolders/RootFolderModule.cs | 3 + NzbDrone.Api/Series/SeriesModule.cs | 6 +- NzbDrone.Api/Validation/PathValidator.cs | 18 ++++++ .../Validation/RuleBuilderExtensions.cs | 9 ++- .../EnsureThat/EnsureStringExtensions.cs | 30 ++-------- NzbDrone.Common/PathExtensions.cs | 27 +++++++++ .../Validation/RuleBuilderExtensions.cs | 1 + NzbDrone.Integration.Test/IntegrationTest.cs | 7 ++- .../RootFolderIntegrationTest.cs | 12 ++++ .../SeriesIntegrationTest.cs | 6 -- UI/AddSeries/RootFolders/Collection.js | 2 +- UI/AddSeries/RootFolders/Layout.js | 11 +++- UI/AddSeries/RootFolders/LayoutTemplate.html | 9 ++- UI/AddSeries/RootFolders/Model.js | 1 + UI/AddSeries/SearchResultView.js | 3 +- UI/Content/theme.less | 11 ++-- UI/Mixins/AsValidatedView.js | 60 +++++++++---------- UI/jQuery/jquery.validation.js | 7 ++- 19 files changed, 141 insertions(+), 83 deletions(-) create mode 100644 NzbDrone.Api/Validation/PathValidator.cs diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj index 5210ef0a6..d0a03bd17 100644 --- a/NzbDrone.Api/NzbDrone.Api.csproj +++ b/NzbDrone.Api/NzbDrone.Api.csproj @@ -164,6 +164,7 @@ + diff --git a/NzbDrone.Api/RootFolders/RootFolderModule.cs b/NzbDrone.Api/RootFolders/RootFolderModule.cs index 5c13a736c..7bcc4aa52 100644 --- a/NzbDrone.Api/RootFolders/RootFolderModule.cs +++ b/NzbDrone.Api/RootFolders/RootFolderModule.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using NzbDrone.Core.RootFolders; using NzbDrone.Api.Mapping; +using NzbDrone.Api.Validation; namespace NzbDrone.Api.RootFolders { @@ -17,6 +18,8 @@ namespace NzbDrone.Api.RootFolders GetResourceById = GetRootFolder; CreateResource = CreateRootFolder; DeleteResource = DeleteFolder; + + SharedValidator.RuleFor(c=>c.Path).IsValidPath(); } private RootFolderResource GetRootFolder(int id) diff --git a/NzbDrone.Api/Series/SeriesModule.cs b/NzbDrone.Api/Series/SeriesModule.cs index 57caeb7a6..fe7b820a6 100644 --- a/NzbDrone.Api/Series/SeriesModule.cs +++ b/NzbDrone.Api/Series/SeriesModule.cs @@ -31,10 +31,10 @@ namespace NzbDrone.Api.Series SharedValidator.RuleFor(s => s.QualityProfileId).ValidId(); - PutValidator.RuleFor(s => s.Path).NotEmpty(); + PutValidator.RuleFor(s => s.Path).IsValidPath(); - PostValidator.RuleFor(s => s.Path).NotEmpty().When(s => String.IsNullOrEmpty(s.RootFolderPath)); - PostValidator.RuleFor(s => s.RootFolderPath).NotEmpty().When(s => String.IsNullOrEmpty(s.Path)); + PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => String.IsNullOrEmpty(s.RootFolderPath)); + PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => String.IsNullOrEmpty(s.Path)); PostValidator.RuleFor(s => s.Title).NotEmpty(); } diff --git a/NzbDrone.Api/Validation/PathValidator.cs b/NzbDrone.Api/Validation/PathValidator.cs new file mode 100644 index 000000000..bc055a98c --- /dev/null +++ b/NzbDrone.Api/Validation/PathValidator.cs @@ -0,0 +1,18 @@ +using FluentValidation.Validators; +using NzbDrone.Common; + +namespace NzbDrone.Api.Validation +{ + public class PathValidator : PropertyValidator + { + public PathValidator() + : base("Invalid Path") + { + } + + protected override bool IsValid(PropertyValidatorContext context) + { + return context.PropertyValue.ToString().IsPathValid(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Api/Validation/RuleBuilderExtensions.cs b/NzbDrone.Api/Validation/RuleBuilderExtensions.cs index 23dc34c77..b142f5a56 100644 --- a/NzbDrone.Api/Validation/RuleBuilderExtensions.cs +++ b/NzbDrone.Api/Validation/RuleBuilderExtensions.cs @@ -1,4 +1,6 @@ -using System.Text.RegularExpressions; +using System; +using System.Linq.Expressions; +using System.Text.RegularExpressions; using FluentValidation; using FluentValidation.Validators; @@ -20,5 +22,10 @@ namespace NzbDrone.Api.Validation { return ruleBuilder.SetValidator(new RegularExpressionValidator("^http(s)?://", RegexOptions.IgnoreCase)).WithMessage("must start with http:// or https://"); } + + public static IRuleBuilderOptions IsValidPath(this IRuleBuilder ruleBuilder) + { + return ruleBuilder.SetValidator(new PathValidator()); + } } } \ No newline at end of file diff --git a/NzbDrone.Common/EnsureThat/EnsureStringExtensions.cs b/NzbDrone.Common/EnsureThat/EnsureStringExtensions.cs index 9a0275894..0cd595464 100644 --- a/NzbDrone.Common/EnsureThat/EnsureStringExtensions.cs +++ b/NzbDrone.Common/EnsureThat/EnsureStringExtensions.cs @@ -95,8 +95,7 @@ namespace NzbDrone.Common.EnsureThat return param; } - private static readonly Regex windowsInvalidPathRegex = new Regex(@"[/*<>""|]", RegexOptions.Compiled); - private static readonly Regex windowsPathRegex = new Regex(@"^[a-zA-Z]:\\", RegexOptions.Compiled); + [DebuggerStepThrough] public static Param IsValidPath(this Param param) @@ -104,31 +103,14 @@ namespace NzbDrone.Common.EnsureThat if (string.IsNullOrWhiteSpace(param.Value)) throw ExceptionFactory.CreateForParamValidation(param.Name, ExceptionMessages.EnsureExtensions_IsNotNullOrWhiteSpace); + if (param.Value.IsPathValid()) return param; + if (OsInfo.IsLinux) { - if (!param.Value.StartsWith(Path.DirectorySeparatorChar.ToString())) - { - throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid *nix path. paths must start with /", param.Value)); - } - } - else - { - if (windowsInvalidPathRegex.IsMatch(param.Value)) - { - throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid Windows path. It contains invalid characters", param.Value)); - } - - //Network path - if (param.Value.StartsWith(Path.DirectorySeparatorChar.ToString())) return param; - - if (!windowsPathRegex.IsMatch(param.Value)) - { - throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid Windows path. paths must be a full path eg. C:\\Windows", param.Value)); - } + throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid *nix path. paths must start with /", param.Value)); } - - - return param; + + throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid Windows path. paths must be a full path eg. C:\\Windows", param.Value)); } } } diff --git a/NzbDrone.Common/PathExtensions.cs b/NzbDrone.Common/PathExtensions.cs index 374d2372a..2cdd5dd44 100644 --- a/NzbDrone.Common/PathExtensions.cs +++ b/NzbDrone.Common/PathExtensions.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text.RegularExpressions; using NzbDrone.Common.EnsureThat; using NzbDrone.Common.EnvironmentInfo; @@ -45,6 +46,32 @@ namespace NzbDrone.Common return String.Equals(firstPath.CleanFilePath(), secondPath.CleanFilePath(), StringComparison.InvariantCultureIgnoreCase); } + private static readonly Regex WindowsInvalidPathRegex = new Regex(@"[/*<>""|]", RegexOptions.Compiled); + private static readonly Regex WindowsPathRegex = new Regex(@"^[a-zA-Z]:\\", RegexOptions.Compiled); + + public static bool IsPathValid(this string path) + { + if (OsInfo.IsLinux && !path.StartsWith(Path.DirectorySeparatorChar.ToString())) + { + return false; + } + if (WindowsInvalidPathRegex.IsMatch(path)) + { + return false; + } + + //Network path + if (path.StartsWith(Path.DirectorySeparatorChar.ToString())) return true; + + if (!WindowsPathRegex.IsMatch(path)) + { + return false; + } + + return true; + } + + public static bool ContainsInvalidPathChars(this string text) { return text.IndexOfAny(Path.GetInvalidPathChars()) >= 0; diff --git a/NzbDrone.Core/Validation/RuleBuilderExtensions.cs b/NzbDrone.Core/Validation/RuleBuilderExtensions.cs index 6401fb475..da8609e84 100644 --- a/NzbDrone.Core/Validation/RuleBuilderExtensions.cs +++ b/NzbDrone.Core/Validation/RuleBuilderExtensions.cs @@ -23,6 +23,7 @@ namespace NzbDrone.Core.Validation public static IRuleBuilderOptions ValidRootUrl(this IRuleBuilder ruleBuilder) { + ruleBuilder.SetValidator(new NotEmptyValidator(null)); return ruleBuilder.SetValidator(new RegularExpressionValidator("^http(?:s)?://[a-z0-9-.]+", RegexOptions.IgnoreCase)).WithMessage("must be valid URL that"); } } diff --git a/NzbDrone.Integration.Test/IntegrationTest.cs b/NzbDrone.Integration.Test/IntegrationTest.cs index 3ef126a98..c0bb4b5fd 100644 --- a/NzbDrone.Integration.Test/IntegrationTest.cs +++ b/NzbDrone.Integration.Test/IntegrationTest.cs @@ -1,4 +1,5 @@ -using NLog; +using System.Runtime.CompilerServices; +using NLog; using NLog.Config; using NLog.Targets; using NUnit.Framework; @@ -39,7 +40,7 @@ namespace NzbDrone.Integration.Test LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, consoleTarget)); } - [SetUp] + [TestFixtureSetUp] public void SmokeTestSetup() { _runner = new NzbDroneRunner(); @@ -63,7 +64,7 @@ namespace NzbDrone.Integration.Test NamingConfig = new ClientBase(RestClient, "config/naming"); } - [TearDown] + [TestFixtureTearDown] public void SmokeTestTearDown() { _runner.KillAll(); diff --git a/NzbDrone.Integration.Test/RootFolderIntegrationTest.cs b/NzbDrone.Integration.Test/RootFolderIntegrationTest.cs index cd1b29cf0..8a888fffa 100644 --- a/NzbDrone.Integration.Test/RootFolderIntegrationTest.cs +++ b/NzbDrone.Integration.Test/RootFolderIntegrationTest.cs @@ -58,5 +58,17 @@ namespace NzbDrone.Integration.Test RootFolders.All().Should().BeEmpty(); } + + [Test] + public void invalid_path_should_return_bad_request() + { + var rootFolder = new RootFolderResource + { + Path = "invalid_path" + }; + + var postResponse = RootFolders.InvalidPost(rootFolder); + postResponse.Should().NotBeEmpty(); + } } } \ No newline at end of file diff --git a/NzbDrone.Integration.Test/SeriesIntegrationTest.cs b/NzbDrone.Integration.Test/SeriesIntegrationTest.cs index 85ef89050..c03940490 100644 --- a/NzbDrone.Integration.Test/SeriesIntegrationTest.cs +++ b/NzbDrone.Integration.Test/SeriesIntegrationTest.cs @@ -9,12 +9,6 @@ namespace NzbDrone.Integration.Test [TestFixture] public class SeriesIntegrationTest : IntegrationTest { - [Test] - public void should_have_no_series_on_start_application() - { - Series.All().Should().BeEmpty(); - } - [Test] public void series_lookup_on_trakt() { diff --git a/UI/AddSeries/RootFolders/Collection.js b/UI/AddSeries/RootFolders/Collection.js index 8f20ac92a..74b9b4555 100644 --- a/UI/AddSeries/RootFolders/Collection.js +++ b/UI/AddSeries/RootFolders/Collection.js @@ -1,4 +1,4 @@ -'use strict'; +'use strict'; define( [ 'backbone', diff --git a/UI/AddSeries/RootFolders/Layout.js b/UI/AddSeries/RootFolders/Layout.js index 89388b2c2..3a75c0f9f 100644 --- a/UI/AddSeries/RootFolders/Layout.js +++ b/UI/AddSeries/RootFolders/Layout.js @@ -7,10 +7,11 @@ define( 'AddSeries/RootFolders/Collection', 'AddSeries/RootFolders/Model', 'Shared/LoadingView', + 'Mixins/AsValidatedView', 'Mixins/AutoComplete' - ], function (Marionette, RootFolderCollectionView, RootFolderCollection, RootFolderModel, LoadingView) { + ], function (Marionette, RootFolderCollectionView, RootFolderCollection, RootFolderModel, LoadingView, AsValidatedView) { - return Marionette.Layout.extend({ + var layout = Marionette.Layout.extend({ template: 'AddSeries/RootFolders/LayoutTemplate', ui: { @@ -55,12 +56,16 @@ define( Path: this.ui.pathInput.val() }); - RootFolderCollection.add(newDir); + this.bindToModelValidation(newDir); newDir.save().done(function () { + RootFolderCollection.add(newDir); self.trigger('folderSelected', {model: newDir}); }); } }); + + return AsValidatedView.apply(layout); + }); diff --git a/UI/AddSeries/RootFolders/LayoutTemplate.html b/UI/AddSeries/RootFolders/LayoutTemplate.html index 2a5d5f350..a62ef128d 100644 --- a/UI/AddSeries/RootFolders/LayoutTemplate.html +++ b/UI/AddSeries/RootFolders/LayoutTemplate.html @@ -3,10 +3,13 @@

Select Folder