pull/2789/head
Mark McDowall 7 years ago committed by Taloth Saldono
parent 211f3769e1
commit 7297c1b8e4

@ -1,8 +1,8 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Core.Annotations;
using NzbDrone.Test.Common;
using Sonarr.Http.ClientSchema;
namespace NzbDrone.Api.Test.ClientSchemaTests
{

@ -90,6 +90,10 @@
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
<Name>NzbDrone.Test.Common</Name>
</ProjectReference>
<ProjectReference Include="..\Sonarr.Http\Sonarr.Http.csproj">
<Project>{5370BFF7-1BD7-46BC-AF06-7D9EA5CDA1D6}</Project>
<Name>Sonarr.Http</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="..\NzbDrone.Test.Common\App.config">

@ -1,9 +1,10 @@
using NzbDrone.Core.Blacklisting;
using NzbDrone.Core.Datastore;
using Sonarr.Http;
namespace NzbDrone.Api.Blacklist
{
public class BlacklistModule : NzbDroneRestModule<BlacklistResource>
public class BlacklistModule : SonarrRestModule<BlacklistResource>
{
private readonly IBlacklistService _blacklistService;

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series;
using NzbDrone.Core.Indexers;

@ -1,4 +0,0 @@
namespace NzbDrone.Api.ClientSchema
{
}

@ -1,7 +0,0 @@
namespace NzbDrone.Api.ClientSchema
{
public static class SchemaDeserializer
{
}
}

@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.Validation;
using Sonarr.Http.Extensions;
using NzbDrone.Common;
using NzbDrone.Common.TPL;
using NzbDrone.Core.Datastore.Events;
@ -10,11 +9,14 @@ using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ProgressMessaging;
using NzbDrone.SignalR;
using Sonarr.Http;
using Sonarr.Http.Mapping;
using Sonarr.Http.Validation;
namespace NzbDrone.Api.Commands
{
public class CommandModule : NzbDroneRestModuleWithSignalR<CommandResource, CommandModel>, IHandle<CommandUpdatedEvent>
public class CommandModule : SonarrRestModuleWithSignalR<CommandResource, CommandModel>, IHandle<CommandUpdatedEvent>
{
private readonly IManageCommandQueue _commandQueueManager;
private readonly IServiceFactory _serviceFactory;

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Api.Commands

@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Api.Config

@ -8,10 +8,11 @@ using NzbDrone.Core.Configuration;
using NzbDrone.Core.Update;
using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths;
using Sonarr.Http;
namespace NzbDrone.Api.Config
{
public class HostConfigModule : NzbDroneRestModule<HostConfigResource>
public class HostConfigModule : SonarrRestModule<HostConfigResource>
{
private readonly IConfigFileProvider _configFileProvider;
private readonly IConfigService _configService;

@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Authentication;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Update;

@ -1,6 +1,6 @@
using FluentValidation;
using NzbDrone.Api.Validation;
using NzbDrone.Core.Configuration;
using Sonarr.Http.Validation;
namespace NzbDrone.Api.Config
{

@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Api.Config

@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles;

@ -6,11 +6,13 @@ using Nancy.Responses;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Organizer;
using Nancy.ModelBinding;
using NzbDrone.Api.Extensions;
using Sonarr.Http.Extensions;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Config
{
public class NamingConfigModule : NzbDroneRestModule<NamingConfigResource>
public class NamingConfigModule : SonarrRestModule<NamingConfigResource>
{
private readonly INamingConfigService _namingConfigService;
private readonly IFilenameSampleService _filenameSampleService;

@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Organizer;
namespace NzbDrone.Api.Config

@ -1,11 +1,12 @@
using System.Linq;
using System.Reflection;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Configuration;
using Sonarr.Http;
namespace NzbDrone.Api.Config
{
public abstract class NzbDroneConfigModule<TResource> : NzbDroneRestModule<TResource> where TResource : RestResource, new()
public abstract class NzbDroneConfigModule<TResource> : SonarrRestModule<TResource> where TResource : RestResource, new()
{
private readonly IConfigService _configService;

@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Api.Config

@ -1,9 +1,10 @@
using System.Collections.Generic;
using NzbDrone.Core.DiskSpace;
using Sonarr.Http;
namespace NzbDrone.Api.DiskSpace
{
public class DiskSpaceModule :NzbDroneRestModule<DiskSpaceResource>
public class DiskSpaceModule :SonarrRestModule<DiskSpaceResource>
{
private readonly IDiskSpaceService _diskSpaceService;

@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
namespace NzbDrone.Api.DiskSpace
{

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Sonarr.Http.REST;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
@ -11,7 +12,7 @@ using HttpStatusCode = System.Net.HttpStatusCode;
namespace NzbDrone.Api.EpisodeFiles
{
public class EpisodeFileModule : NzbDroneRestModuleWithSignalR<EpisodeFileResource, EpisodeFile>,
public class EpisodeFileModule : SonarrRestModuleWithSignalR<EpisodeFileResource, EpisodeFile>,
IHandle<EpisodeFileAddedEvent>
{
private readonly IMediaFileService _mediaFileService;

@ -1,6 +1,8 @@
using System;
using System.IO;
using NzbDrone.Api.REST;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.MediaFiles;
using Sonarr.Http.REST;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Api.EpisodeFiles
@ -23,7 +25,7 @@ namespace NzbDrone.Api.EpisodeFiles
public static class EpisodeFileResourceMapper
{
private static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model)
private static EpisodeFileResource ToResource(this EpisodeFile model)
{
if (model == null) return null;
@ -44,7 +46,7 @@ namespace NzbDrone.Api.EpisodeFiles
};
}
public static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model, Core.Tv.Series series, Core.DecisionEngine.IQualityUpgradableSpecification qualityUpgradableSpecification)
public static EpisodeFileResource ToResource(this EpisodeFile model, Core.Tv.Series series, IQualityUpgradableSpecification qualityUpgradableSpecification)
{
if (model == null) return null;
@ -60,7 +62,7 @@ namespace NzbDrone.Api.EpisodeFiles
DateAdded = model.DateAdded,
SceneName = model.SceneName,
Quality = model.Quality,
QualityCutoffNotMet = qualityUpgradableSpecification.CutoffNotMet(series.Profile.Value, model.Quality),
QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(series.Profile.Value, model.Quality),
MediaInfo = model.MediaInfo.ToResource(model.SceneName),
OriginalFilePath = model.OriginalFilePath
};

@ -1,5 +1,5 @@
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaFiles.MediaInfo;
using Sonarr.Http.REST;
namespace NzbDrone.Api.EpisodeFiles
{

@ -1,5 +1,5 @@
using System.Collections.Generic;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Tv;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.SignalR;

@ -1,7 +1,7 @@
using System.Collections.Generic;
using NzbDrone.Common.Extensions;
using NzbDrone.Api.EpisodeFiles;
using NzbDrone.Api.Series;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
@ -9,10 +9,11 @@ using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv;
using NzbDrone.SignalR;
using Sonarr.Http;
namespace NzbDrone.Api.Episodes
{
public abstract class EpisodeModuleWithSignalR : NzbDroneRestModuleWithSignalR<EpisodeResource, Episode>,
public abstract class EpisodeModuleWithSignalR : SonarrRestModuleWithSignalR<EpisodeResource, Episode>,
IHandle<EpisodeGrabbedEvent>,
IHandle<EpisodeImportedEvent>
{

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using NzbDrone.Api.EpisodeFiles;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Api.Series;
using NzbDrone.Core.Tv;

@ -1,10 +1,11 @@
using System.Collections.Generic;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.MediaFiles;
using Sonarr.Http;
namespace NzbDrone.Api.Episodes
{
public class RenameEpisodeModule : NzbDroneRestModule<RenameEpisodeResource>
public class RenameEpisodeModule : SonarrRestModule<RenameEpisodeResource>
{
private readonly IRenameEpisodeFileService _renameEpisodeFileService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
namespace NzbDrone.Api.Episodes
{

@ -1,8 +1,8 @@
using System;
using System;
using System.IO;
using System.Linq;
using Nancy;
using NzbDrone.Api.Extensions;
using Sonarr.Http.Extensions;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles;
@ -31,15 +31,10 @@ namespace NzbDrone.Api.FileSystem
private Response GetContents()
{
var pathQuery = Request.Query.path;
var includeFilesQuery = Request.Query.includeFiles;
bool includeFiles = false;
var includeFiles = Request.GetBooleanQueryParameter("includeFiles");
var allowFoldersWithoutTrailingSlashes = Request.GetBooleanQueryParameter("allowFoldersWithoutTrailingSlashes");
if (includeFilesQuery.HasValue)
{
includeFiles = Convert.ToBoolean(includeFilesQuery.Value);
}
return _fileSystemLookupService.LookupContents((string)pathQuery.Value, includeFiles).AsResponse();
return _fileSystemLookupService.LookupContents((string)pathQuery.Value, includeFiles, allowFoldersWithoutTrailingSlashes).AsResponse();
}
private Response GetEntityType()
@ -73,4 +68,4 @@ namespace NzbDrone.Api.FileSystem
}).AsResponse();
}
}
}
}

@ -1,121 +0,0 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using Nancy;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Analytics;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Api.Frontend.Mappers
{
public class IndexHtmlMapper : StaticResourceMapperBase
{
private readonly IDiskProvider _diskProvider;
private readonly IConfigFileProvider _configFileProvider;
private readonly IAnalyticsService _analyticsService;
private readonly Func<ICacheBreakerProvider> _cacheBreakProviderFactory;
private readonly string _indexPath;
private static readonly Regex ReplaceRegex = new Regex(@"(?:(?<attribute>href|src)=\"")(?<path>.*?(?<extension>css|js|png|ico|ics|svg))(?:\"")(?:\s(?<nohash>data-no-hash))?", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static string API_KEY;
private static string URL_BASE;
private string _generatedContent
;
public IndexHtmlMapper(IAppFolderInfo appFolderInfo,
IDiskProvider diskProvider,
IConfigFileProvider configFileProvider,
IAnalyticsService analyticsService,
Func<ICacheBreakerProvider> cacheBreakProviderFactory,
Logger logger)
: base(diskProvider, logger)
{
_diskProvider = diskProvider;
_configFileProvider = configFileProvider;
_analyticsService = analyticsService;
_cacheBreakProviderFactory = cacheBreakProviderFactory;
_indexPath = Path.Combine(appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, "index.html");
API_KEY = configFileProvider.ApiKey;
URL_BASE = configFileProvider.UrlBase;
}
public override string Map(string resourceUrl)
{
return _indexPath;
}
public override bool CanHandle(string resourceUrl)
{
resourceUrl = resourceUrl.ToLowerInvariant();
return !resourceUrl.StartsWith("/content") &&
!resourceUrl.StartsWith("/mediacover") &&
!resourceUrl.Contains(".") &&
!resourceUrl.StartsWith("/login");
}
public override Response GetResponse(string resourceUrl)
{
var response = base.GetResponse(resourceUrl);
response.Headers["X-UA-Compatible"] = "IE=edge";
return response;
}
protected override Stream GetContentStream(string filePath)
{
var text = GetIndexText();
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(text);
writer.Flush();
stream.Position = 0;
return stream;
}
private string GetIndexText()
{
if (RuntimeInfo.IsProduction && _generatedContent != null)
{
return _generatedContent;
}
var text = _diskProvider.ReadAllText(_indexPath);
var cacheBreakProvider = _cacheBreakProviderFactory();
text = ReplaceRegex.Replace(text, match =>
{
string url;
if (match.Groups["nohash"].Success)
{
url = match.Groups["path"].Value;
}
else
{
url = cacheBreakProvider.AddCacheBreakerToPath(match.Groups["path"].Value);
}
return string.Format("{0}=\"{1}{2}\"", match.Groups["attribute"].Value, URL_BASE, url);
});
text = text.Replace("API_ROOT", URL_BASE + "/api");
text = text.Replace("API_KEY", API_KEY);
text = text.Replace("APP_VERSION", BuildInfo.Version.ToString());
text = text.Replace("APP_BRANCH", _configFileProvider.Branch.ToLower());
text = text.Replace("APP_ANALYTICS", _analyticsService.IsEnabled.ToString().ToLowerInvariant());
text = text.Replace("URL_BASE", URL_BASE);
text = text.Replace("PRODUCTION", RuntimeInfo.IsProduction.ToString().ToLowerInvariant());
_generatedContent = text;
return _generatedContent;
}
}
}

@ -1,90 +0,0 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using Nancy;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Api.Frontend.Mappers
{
public class LoginHtmlMapper : StaticResourceMapperBase
{
private readonly IDiskProvider _diskProvider;
private readonly IConfigFileProvider _configFileProvider;
private readonly Func<ICacheBreakerProvider> _cacheBreakProviderFactory;
private readonly string _indexPath;
private static readonly Regex ReplaceRegex = new Regex("(?<=(?:href|src|data-main)=\").*?(?=\")", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static string URL_BASE;
private string _generatedContent;
public LoginHtmlMapper(IAppFolderInfo appFolderInfo,
IDiskProvider diskProvider,
IConfigFileProvider configFileProvider,
Func<ICacheBreakerProvider> cacheBreakProviderFactory,
Logger logger)
: base(diskProvider, logger)
{
_diskProvider = diskProvider;
_configFileProvider = configFileProvider;
_cacheBreakProviderFactory = cacheBreakProviderFactory;
_indexPath = Path.Combine(appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, "login.html");
URL_BASE = configFileProvider.UrlBase;
}
public override string Map(string resourceUrl)
{
return _indexPath;
}
public override bool CanHandle(string resourceUrl)
{
return resourceUrl.StartsWith("/login");
}
public override Response GetResponse(string resourceUrl)
{
var response = base.GetResponse(resourceUrl);
response.Headers["X-UA-Compatible"] = "IE=edge";
return response;
}
protected override Stream GetContentStream(string filePath)
{
var text = GetLoginText();
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(text);
writer.Flush();
stream.Position = 0;
return stream;
}
private string GetLoginText()
{
if (RuntimeInfo.IsProduction && _generatedContent != null)
{
return _generatedContent;
}
var text = _diskProvider.ReadAllText(_indexPath);
var cacheBreakProvider = _cacheBreakProviderFactory();
text = ReplaceRegex.Replace(text, match =>
{
var url = cacheBreakProvider.AddCacheBreakerToPath(match.Value);
return URL_BASE + url;
});
_generatedContent = text;
return _generatedContent;
}
}
}

@ -3,10 +3,11 @@ using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.HealthCheck;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.SignalR;
using Sonarr.Http;
namespace NzbDrone.Api.Health
{
public class HealthModule : NzbDroneRestModuleWithSignalR<HealthResource, HealthCheck>,
public class HealthModule : SonarrRestModuleWithSignalR<HealthResource, HealthCheck>,
IHandle<HealthCheckCompleteEvent>
{
private readonly IHealthCheckService _healthCheckService;

@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Common.Http;
using NzbDrone.Core.HealthCheck;
using Sonarr.Http.REST;
namespace NzbDrone.Api.Health
{

@ -3,17 +3,18 @@ using System.Collections.Generic;
using System.Linq;
using Nancy;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.REST;
using Sonarr.Http.Extensions;
using NzbDrone.Api.Series;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.History;
using Sonarr.Http;
using Sonarr.Http.REST;
namespace NzbDrone.Api.History
{
public class HistoryModule : NzbDroneRestModule<HistoryResource>
public class HistoryModule : SonarrRestModule<HistoryResource>
{
private readonly IHistoryService _historyService;
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
@ -50,19 +51,19 @@ namespace NzbDrone.Api.History
private PagingResource<HistoryResource> GetHistory(PagingResource<HistoryResource> pagingResource)
{
var episodeId = Request.Query.EpisodeId;
var pagingSpec = pagingResource.MapToPagingSpec<HistoryResource, Core.History.History>("date", SortDirection.Descending);
var filter = pagingResource.Filters.FirstOrDefault();
if (pagingResource.FilterKey == "eventType")
if (filter != null && filter.Key == "eventType")
{
var filterValue = (HistoryEventType)Convert.ToInt32(pagingResource.FilterValue);
pagingSpec.FilterExpression = v => v.EventType == filterValue;
var filterValue = (HistoryEventType)Convert.ToInt32(filter.Value);
pagingSpec.FilterExpressions.Add(v => v.EventType == filterValue);
}
if (episodeId.HasValue)
{
int i = (int)episodeId;
pagingSpec.FilterExpression = h => h.EpisodeId == i;
pagingSpec.FilterExpressions.Add(h => h.EpisodeId == i);
}
return ApplyToPage(_historyService.Paged, pagingSpec, MapToResource);

@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Api.Series;
using NzbDrone.Core.History;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Api.History
{
public class HistoryResource : RestResource

@ -10,7 +10,7 @@ using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser.Model;
using Nancy.ModelBinding;
using NzbDrone.Api.Extensions;
using Sonarr.Http.Extensions;
using NzbDrone.Common.Cache;
using HttpStatusCode = System.Net.HttpStatusCode;

@ -1,9 +1,10 @@
using System.Collections.Generic;
using NzbDrone.Core.DecisionEngine;
using Sonarr.Http;
namespace NzbDrone.Api.Indexers
{
public abstract class ReleaseModuleBase : NzbDroneRestModule<ReleaseResource>
public abstract class ReleaseModuleBase : SonarrRestModule<ReleaseResource>
{
protected virtual List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision> decisions)
{

@ -11,6 +11,8 @@ using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser.Model;
using Sonarr.Http.Extensions;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Indexers
{

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Indexers;

@ -5,10 +5,11 @@ using NzbDrone.Common.Disk;
using Nancy;
using Nancy.Responses;
using NzbDrone.Core.Configuration;
using Sonarr.Http;
namespace NzbDrone.Api.Logs
{
public abstract class LogFileModuleBase : NzbDroneRestModule<LogFileResource>
public abstract class LogFileModuleBase : SonarrRestModule<LogFileResource>
{
protected const string LOGFILE_ROUTE = @"/(?<filename>[-.a-zA-Z0-9]+?\.txt)";

@ -1,5 +1,5 @@
using System;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
namespace NzbDrone.Api.Logs
{

@ -1,8 +1,10 @@
using NzbDrone.Core.Instrumentation;
using System.Linq;
using NzbDrone.Core.Instrumentation;
using Sonarr.Http;
namespace NzbDrone.Api.Logs
{
public class LogModule : NzbDroneRestModule<LogResource>
public class LogModule : SonarrRestModule<LogResource>
{
private readonly ILogService _logService;
@ -21,27 +23,29 @@ namespace NzbDrone.Api.Logs
pageSpec.SortKey = "id";
}
if (pagingResource.FilterKey == "level")
var filter = pagingResource.Filters.FirstOrDefault();
if (filter != null && filter.Key == "level")
{
switch (pagingResource.FilterValue)
switch (filter.Value)
{
case "Fatal":
pageSpec.FilterExpression = h => h.Level == "Fatal";
pageSpec.FilterExpressions.Add(h => h.Level == "Fatal");
break;
case "Error":
pageSpec.FilterExpression = h => h.Level == "Fatal" || h.Level == "Error";
pageSpec.FilterExpressions.Add(h => h.Level == "Fatal" || h.Level == "Error");
break;
case "Warn":
pageSpec.FilterExpression = h => h.Level == "Fatal" || h.Level == "Error" || h.Level == "Warn";
pageSpec.FilterExpressions.Add(h => h.Level == "Fatal" || h.Level == "Error" || h.Level == "Warn");
break;
case "Info":
pageSpec.FilterExpression = h => h.Level == "Fatal" || h.Level == "Error" || h.Level == "Warn" || h.Level == "Info";
pageSpec.FilterExpressions.Add(h => h.Level == "Fatal" || h.Level == "Error" || h.Level == "Warn" || h.Level == "Info");
break;
case "Debug":
pageSpec.FilterExpression = h => h.Level == "Fatal" || h.Level == "Error" || h.Level == "Warn" || h.Level == "Info" || h.Level == "Debug";
pageSpec.FilterExpressions.Add(h => h.Level == "Fatal" || h.Level == "Error" || h.Level == "Warn" || h.Level == "Info" || h.Level == "Debug");
break;
case "Trace":
pageSpec.FilterExpression = h => h.Level == "Fatal" || h.Level == "Error" || h.Level == "Warn" || h.Level == "Info" || h.Level == "Debug" || h.Level == "Trace";
pageSpec.FilterExpressions.Add(h => h.Level == "Fatal" || h.Level == "Error" || h.Level == "Warn" || h.Level == "Info" || h.Level == "Debug" || h.Level == "Trace");
break;
}
}
@ -49,4 +53,4 @@ namespace NzbDrone.Api.Logs
return ApplyToPage(_logService.Paged, pageSpec, LogResourceMapper.ToResource);
}
}
}
}

@ -1,5 +1,5 @@
using System;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
namespace NzbDrone.Api.Logs
{

@ -1,11 +1,13 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.MediaFiles.EpisodeImport.Manual;
using NzbDrone.Core.Qualities;
using Sonarr.Http;
using Sonarr.Http.Extensions;
namespace NzbDrone.Api.ManualImport
{
public class ManualImportModule : NzbDroneRestModule<ManualImportResource>
public class ManualImportModule : SonarrRestModule<ManualImportResource>
{
private readonly IManualImportService _manualImportService;
@ -24,8 +26,9 @@ namespace NzbDrone.Api.ManualImport
var downloadIdQuery = Request.Query.downloadId;
var downloadId = (string)downloadIdQuery.Value;
var filterExistingFiles = Request.GetBooleanQueryParameter("filterExistingFiles", true);
return _manualImportService.GetMediaFiles(folder, downloadId).ToResource().Select(AddQualityWeight).ToList();
return _manualImportService.GetMediaFiles(folder, downloadId, filterExistingFiles).ToResource().Select(AddQualityWeight).ToList();
}
private ManualImportResource AddQualityWeight(ManualImportResource item)
@ -40,4 +43,4 @@ namespace NzbDrone.Api.ManualImport
return item;
}
}
}
}

@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Api.Series;
using NzbDrone.Common.Crypto;
using NzbDrone.Core.DecisionEngine;

@ -78,7 +78,6 @@
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data.SQLite, Version=1.0.84.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -88,43 +87,31 @@
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml" />
<Reference Include="Omu.ValueInjecter">
<HintPath>..\packages\ValueInjecter.2.3.3\lib\net35\Omu.ValueInjecter.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Authentication\AuthenticationService.cs" />
<Compile Include="Authentication\EnableAuthInNancy.cs" />
<Compile Include="Authentication\AuthenticationModule.cs" />
<Compile Include="Authentication\LoginResource.cs" />
<Compile Include="Authentication\NzbDroneUser.cs" />
<Compile Include="Blacklist\BlacklistModule.cs" />
<Compile Include="Blacklist\BlacklistResource.cs" />
<Compile Include="Calendar\CalendarFeedModule.cs" />
<Compile Include="Calendar\CalendarModule.cs" />
<Compile Include="ClientSchema\Field.cs" />
<Compile Include="ClientSchema\FieldDefinitionAttribute.cs" />
<Compile Include="ClientSchema\FieldMapping.cs" />
<Compile Include="ClientSchema\SchemaBuilder.cs" />
<Compile Include="ClientSchema\SchemaDeserializer.cs" />
<Compile Include="ClientSchema\SelectOption.cs" />
<Compile Include="Commands\CommandModule.cs" />
<Compile Include="Commands\CommandResource.cs" />
<Compile Include="EpisodeFiles\MediaInfoResource.cs" />
<Compile Include="Extensions\AccessControlHeaders.cs" />
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
<Compile Include="Extensions\Pipelines\UrlBasePipeline.cs" />
<Compile Include="Extensions\Pipelines\RequestLoggingPipeline.cs" />
<Compile Include="Frontend\Mappers\LoginHtmlMapper.cs" />
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
<Compile Include="Indexers\ReleaseModuleBase.cs" />
<Compile Include="Indexers\ReleasePushModule.cs" />
<Compile Include="NzbDroneFeedModule.cs" />
<Compile Include="Parse\ParseModule.cs" />
<Compile Include="Parse\ParseResource.cs" />
<Compile Include="ManualImport\ManualImportModule.cs" />
<Compile Include="ManualImport\ManualImportResource.cs" />
<Compile Include="Profiles\Delay\DelayProfileModule.cs" />
<Compile Include="Profiles\Delay\DelayProfileResource.cs" />
<Compile Include="ProviderModuleBase.cs" />
<Compile Include="Queue\QueueActionModule.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingModule.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingResource.cs" />
@ -154,31 +141,6 @@
<Compile Include="Episodes\EpisodeResource.cs" />
<Compile Include="Episodes\RenameEpisodeModule.cs" />
<Compile Include="Episodes\RenameEpisodeResource.cs" />
<Compile Include="ErrorManagement\ApiException.cs" />
<Compile Include="ErrorManagement\ErrorHandler.cs" />
<Compile Include="ErrorManagement\ErrorModel.cs" />
<Compile Include="ErrorManagement\NzbDroneErrorPipeline.cs" />
<Compile Include="Exceptions\InvalidApiKeyException.cs" />
<Compile Include="Extensions\NancyJsonSerializer.cs" />
<Compile Include="Extensions\Pipelines\CacheHeaderPipeline.cs" />
<Compile Include="Extensions\Pipelines\GZipPipeline.cs" />
<Compile Include="Extensions\Pipelines\IfModifiedPipeline.cs" />
<Compile Include="Extensions\Pipelines\IRegisterNancyPipeline.cs" />
<Compile Include="Extensions\Pipelines\NzbDroneVersionPipeline.cs" />
<Compile Include="Extensions\ReqResExtensions.cs" />
<Compile Include="Extensions\RequestExtensions.cs" />
<Compile Include="Frontend\CacheableSpecification.cs" />
<Compile Include="Frontend\Mappers\BackupFileMapper.cs" />
<Compile Include="Frontend\Mappers\CacheBreakerProvider.cs" />
<Compile Include="Frontend\Mappers\FaviconMapper.cs" />
<Compile Include="Frontend\Mappers\IMapHttpRequestsToDisk.cs" />
<Compile Include="Frontend\Mappers\IndexHtmlMapper.cs" />
<Compile Include="Frontend\Mappers\LogFileMapper.cs" />
<Compile Include="Frontend\Mappers\MediaCoverMapper.cs" />
<Compile Include="Frontend\Mappers\StaticResourceMapper.cs" />
<Compile Include="Frontend\Mappers\StaticResourceMapperBase.cs" />
<Compile Include="Frontend\Mappers\UpdateLogFileMapper.cs" />
<Compile Include="Frontend\StaticResourceModule.cs" />
<Compile Include="Health\HealthModule.cs" />
<Compile Include="Health\HealthResource.cs" />
<Compile Include="History\HistoryModule.cs" />
@ -196,14 +158,9 @@
<Compile Include="MediaCovers\MediaCoverModule.cs" />
<Compile Include="Metadata\MetadataModule.cs" />
<Compile Include="Metadata\MetadataResource.cs" />
<Compile Include="NancyBootstrapper.cs" />
<Compile Include="Notifications\NotificationModule.cs" />
<Compile Include="Notifications\NotificationResource.cs" />
<Compile Include="NzbDroneApiModule.cs" />
<Compile Include="NzbDroneFeedModule.cs" />
<Compile Include="NzbDroneRestModule.cs" />
<Compile Include="NzbDroneRestModuleWithSignalR.cs" />
<Compile Include="PagingResource.cs" />
<Compile Include="Profiles\Languages\LanguageModule.cs" />
<Compile Include="Profiles\Languages\LanguageResource.cs" />
<Compile Include="Profiles\LegacyProfileModule.cs" />
@ -212,21 +169,13 @@
<Compile Include="Profiles\ProfileSchemaModule.cs" />
<Compile Include="Profiles\ProfileValidation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProviderModuleBase.cs" />
<Compile Include="ProviderResource.cs" />
<Compile Include="Qualities\QualityDefinitionModule.cs" />
<Compile Include="Qualities\QualityDefinitionResource.cs" />
<Compile Include="Queue\QueueModule.cs" />
<Compile Include="Queue\QueueResource.cs" />
<Compile Include="ResourceChangeMessage.cs" />
<Compile Include="Restrictions\RestrictionModule.cs" />
<Compile Include="Restrictions\RestrictionResource.cs" />
<Compile Include="REST\NotFoundException.cs" />
<Compile Include="REST\BadRequestException.cs" />
<Compile Include="REST\MethodNotAllowedException.cs" />
<Compile Include="REST\ResourceValidator.cs" />
<Compile Include="REST\RestModule.cs" />
<Compile Include="REST\RestResource.cs" />
<Compile Include="RootFolders\RootFolderModule.cs" />
<Compile Include="RootFolders\RootFolderResource.cs" />
<Compile Include="SeasonPass\SeasonPassResource.cs" />
@ -245,12 +194,8 @@
<Compile Include="System\SystemModule.cs" />
<Compile Include="Tags\TagModule.cs" />
<Compile Include="Tags\TagResource.cs" />
<Compile Include="TinyIoCNancyBootstrapper.cs" />
<Compile Include="Update\UpdateModule.cs" />
<Compile Include="Update\UpdateResource.cs" />
<Compile Include="Validation\RssSyncIntervalValidator.cs" />
<Compile Include="Validation\EmptyCollectionValidator.cs" />
<Compile Include="Validation\RuleBuilderExtensions.cs" />
<Compile Include="Wanted\CutoffModule.cs" />
<Compile Include="Wanted\LegacyMissingModule.cs" />
<Compile Include="Wanted\MissingModule.cs" />
@ -278,6 +223,10 @@
<Project>{7C2CC69F-5CA0-4E5C-85CB-983F9F6C3B36}</Project>
<Name>NzbDrone.SignalR</Name>
</ProjectReference>
<ProjectReference Include="..\Sonarr.Http\Sonarr.Http.csproj">
<Project>{5370BFF7-1BD7-46BC-AF06-7D9EA5CDA1D6}</Project>
<Name>Sonarr.Http</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

@ -1,66 +0,0 @@
using NzbDrone.Api.REST;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.SignalR;
namespace NzbDrone.Api
{
public abstract class NzbDroneRestModuleWithSignalR<TResource, TModel> : NzbDroneRestModule<TResource>, IHandle<ModelEvent<TModel>>
where TResource : RestResource, new()
where TModel : ModelBase, new()
{
private readonly IBroadcastSignalRMessage _signalRBroadcaster;
protected NzbDroneRestModuleWithSignalR(IBroadcastSignalRMessage signalRBroadcaster)
{
_signalRBroadcaster = signalRBroadcaster;
}
protected NzbDroneRestModuleWithSignalR(IBroadcastSignalRMessage signalRBroadcaster, string resource)
: base(resource)
{
_signalRBroadcaster = signalRBroadcaster;
}
public void Handle(ModelEvent<TModel> message)
{
if (message.Action == ModelAction.Deleted || message.Action == ModelAction.Sync)
{
BroadcastResourceChange(message.Action);
}
BroadcastResourceChange(message.Action, message.Model.Id);
}
protected void BroadcastResourceChange(ModelAction action, int id)
{
var resource = GetResourceById(id);
BroadcastResourceChange(action, resource);
}
protected void BroadcastResourceChange(ModelAction action, TResource resource)
{
var signalRMessage = new SignalRMessage
{
Name = Resource,
Body = new ResourceChangeMessage<TResource>(resource, action)
};
_signalRBroadcaster.BroadcastMessage(signalRMessage);
}
protected void BroadcastResourceChange(ModelAction action)
{
var signalRMessage = new SignalRMessage
{
Name = Resource,
Body = new ResourceChangeMessage<TResource>(action)
};
_signalRBroadcaster.BroadcastMessage(signalRMessage);
}
}
}

@ -2,10 +2,11 @@
using NzbDrone.Api.Series;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Parser;
using Sonarr.Http;
namespace NzbDrone.Api.Parse
{
public class ParseModule : NzbDroneRestModule<ParseResource>
public class ParseModule : SonarrRestModule<ParseResource>
{
private readonly IParsingService _parsingService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Api.Series;
using NzbDrone.Core.Parser.Model;

@ -1,13 +1,14 @@
using System.Collections.Generic;
using FluentValidation;
using FluentValidation.Results;
using NzbDrone.Api.REST;
using NzbDrone.Api.Validation;
using Sonarr.Http.REST;
using NzbDrone.Core.Profiles.Delay;
using Sonarr.Http;
using Sonarr.Http.Validation;
namespace NzbDrone.Api.Profiles.Delay
{
public class DelayProfileModule : NzbDroneRestModule<DelayProfileResource>
public class DelayProfileModule : SonarrRestModule<DelayProfileResource>
{
private readonly IDelayProfileService _delayProfileService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Profiles.Delay;

@ -2,10 +2,11 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Parser;
using Sonarr.Http;
namespace NzbDrone.Api.Profiles.Languages
{
public class LanguageModule : NzbDroneRestModule<LanguageResource>
public class LanguageModule : SonarrRestModule<LanguageResource>
{
public LanguageModule()
{

@ -1,5 +1,5 @@
using Newtonsoft.Json;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
namespace NzbDrone.Api.Profiles.Languages
{

@ -2,10 +2,12 @@
using FluentValidation;
using NzbDrone.Core.Profiles;
using NzbDrone.Core.Validation;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Profiles
{
public class ProfileModule : NzbDroneRestModule<ProfileResource>
public class ProfileModule : SonarrRestModule<ProfileResource>
{
private readonly IProfileService _profileService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Profiles;
using NzbDrone.Core.Qualities;

@ -3,10 +3,12 @@ using System.Linq;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Profiles;
using NzbDrone.Core.Qualities;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Profiles
{
public class ProfileSchemaModule : NzbDroneRestModule<ProfileResource>
public class ProfileSchemaModule : SonarrRestModule<ProfileResource>
{
private readonly IQualityDefinitionService _qualityDefinitionService;

@ -3,16 +3,18 @@ using System.Linq;
using FluentValidation;
using FluentValidation.Results;
using Nancy;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Api.Extensions;
using Sonarr.Http.Extensions;
using NzbDrone.Common.Reflection;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using Newtonsoft.Json;
using Sonarr.Http;
using Sonarr.Http.ClientSchema;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api
{
public abstract class ProviderModuleBase<TProviderResource, TProvider, TProviderDefinition> : NzbDroneRestModule<TProviderResource>
public abstract class ProviderModuleBase<TProviderResource, TProvider, TProviderDefinition> : SonarrRestModule<TProviderResource>
where TProviderDefinition : ProviderDefinition, new()
where TProvider : IProvider
where TProviderResource : ProviderResource, new()

@ -1,7 +1,7 @@
using System.Collections.Generic;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.ThingiProvider;
using Sonarr.Http.ClientSchema;
namespace NzbDrone.Api
{

@ -1,9 +1,11 @@
using System.Collections.Generic;
using NzbDrone.Core.Qualities;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Qualities
{
public class QualityDefinitionModule : NzbDroneRestModule<QualityDefinitionResource>
public class QualityDefinitionModule : SonarrRestModule<QualityDefinitionResource>
{
private readonly IQualityDefinitionService _qualityDefinitionService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using Sonarr.Http.REST;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Api.Qualities

@ -1,16 +1,17 @@
using System;
using Nancy;
using Nancy.Responses;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.REST;
using Sonarr.Http.Extensions;
using Sonarr.Http.REST;
using NzbDrone.Core.Download;
using NzbDrone.Core.Download.Pending;
using NzbDrone.Core.Download.TrackedDownloads;
using NzbDrone.Core.Queue;
using Sonarr.Http;
namespace NzbDrone.Api.Queue
{
public class QueueActionModule : NzbDroneRestModule<QueueResource>
public class QueueActionModule : SonarrRestModule<QueueResource>
{
private readonly IQueueService _queueService;
private readonly ITrackedDownloadService _trackedDownloadService;

@ -5,10 +5,11 @@ using NzbDrone.Core.Download.Pending;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Queue;
using NzbDrone.SignalR;
using Sonarr.Http;
namespace NzbDrone.Api.Queue
{
public class QueueModule : NzbDroneRestModuleWithSignalR<QueueResource, Core.Queue.Queue>,
public class QueueModule : SonarrRestModuleWithSignalR<QueueResource, Core.Queue.Queue>,
IHandle<QueueUpdatedEvent>, IHandle<PendingReleasesUpdatedEvent>
{
private readonly IQueueService _queueService;

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series;
using NzbDrone.Api.Episodes;

@ -2,10 +2,11 @@
using FluentValidation;
using NzbDrone.Core.RemotePathMappings;
using NzbDrone.Core.Validation.Paths;
using Sonarr.Http;
namespace NzbDrone.Api.RemotePathMappings
{
public class RemotePathMappingModule : NzbDroneRestModule<RemotePathMappingResource>
public class RemotePathMappingModule : SonarrRestModule<RemotePathMappingResource>
{
private readonly IRemotePathMappingService _remotePathMappingService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using Sonarr.Http.REST;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.RemotePathMappings;
namespace NzbDrone.Api.RemotePathMappings

@ -2,10 +2,12 @@
using FluentValidation.Results;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Restrictions;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Restrictions
{
public class RestrictionModule : NzbDroneRestModule<RestrictionResource>
public class RestrictionModule : SonarrRestModule<RestrictionResource>
{
private readonly IRestrictionService _restrictionService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Restrictions;
namespace NzbDrone.Api.Restrictions

@ -3,10 +3,12 @@ using FluentValidation;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Validation.Paths;
using NzbDrone.SignalR;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.RootFolders
{
public class RootFolderModule : NzbDroneRestModuleWithSignalR<RootFolderResource, RootFolder>
public class RootFolderModule : SonarrRestModuleWithSignalR<RootFolderResource, RootFolder>
{
private readonly IRootFolderService _rootFolderService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using Sonarr.Http.REST;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.RootFolders;
namespace NzbDrone.Api.RootFolders

@ -1,5 +1,5 @@
using Nancy;
using NzbDrone.Api.Extensions;
using Sonarr.Http.Extensions;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.SeasonPass

@ -1,8 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using Nancy;
using NzbDrone.Api.Extensions;
using Sonarr.Http.Extensions;
using NzbDrone.Core.Tv;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Series
{
@ -23,7 +24,7 @@ namespace NzbDrone.Api.Series
var series = resources.Select(seriesResource => seriesResource.ToModel(_seriesService.GetSeries(seriesResource.Id))).ToList();
return _seriesService.UpdateSeries(series)
return _seriesService.UpdateSeries(series, true)
.ToResource(false)
.AsResponse(HttpStatusCode.Accepted);
}

@ -1,13 +1,15 @@
using System.Collections.Generic;
using Nancy;
using NzbDrone.Api.Extensions;
using Sonarr.Http.Extensions;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource;
using System.Linq;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Series
{
public class SeriesLookupModule : NzbDroneRestModule<SeriesResource>
public class SeriesLookupModule : SonarrRestModule<SeriesResource>
{
private readonly ISearchForNewSeries _searchProxy;

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using NzbDrone.Api.Extensions;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.MediaCover;
@ -16,10 +15,12 @@ using NzbDrone.Core.Validation.Paths;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.Validation;
using NzbDrone.SignalR;
using Sonarr.Http;
using Sonarr.Http.Extensions;
namespace NzbDrone.Api.Series
{
public class SeriesModule : NzbDroneRestModuleWithSignalR<SeriesResource, Core.Tv.Series>,
public class SeriesModule : SonarrRestModuleWithSignalR<SeriesResource, Core.Tv.Series>,
IHandle<EpisodeImportedEvent>,
IHandle<EpisodeFileDeletedEvent>,
IHandle<SeriesUpdatedEvent>,
@ -64,7 +65,7 @@ namespace NzbDrone.Api.Series
UpdateResource = UpdateSeries;
DeleteResource = DeleteSeries;
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
SharedValidator.RuleFor(s => s.ProfileId).ValidId();
SharedValidator.RuleFor(s => s.Path)
.Cascade(CascadeMode.StopOnFirstFailure)
@ -207,7 +208,12 @@ namespace NzbDrone.Api.Series
if (mappings == null) return;
resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource
{
Title = v.Title,
SeasonNumber = v.SeasonNumber,
SceneSeasonNumber = v.SceneSeasonNumber
}).ToList();
}
public void Handle(EpisodeImportedEvent message)

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
@ -76,8 +76,6 @@ namespace NzbDrone.Api.Series
public AddSeriesOptions AddOptions { get; set; }
public Ratings Ratings { get; set; }
//TODO: Add series statistics as a property of the series (instead of individual properties)
//Used to support legacy consumers
public int QualityProfileId
{

@ -2,10 +2,11 @@
using System.IO;
using System.Linq;
using NzbDrone.Core.Backup;
using Sonarr.Http;
namespace NzbDrone.Api.System.Backup
{
public class BackupModule : NzbDroneRestModule<BackupResource>
public class BackupModule : SonarrRestModule<BackupResource>
{
private readonly IBackupService _backupService;

@ -1,5 +1,5 @@
using System;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Backup;
namespace NzbDrone.Api.System.Backup

@ -1,6 +1,6 @@
using Nancy;
using Nancy.Routing;
using NzbDrone.Api.Extensions;
using Sonarr.Http.Extensions;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;

@ -5,10 +5,11 @@ using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.SignalR;
using Sonarr.Http;
namespace NzbDrone.Api.System.Tasks
{
public class TaskModule : NzbDroneRestModuleWithSignalR<TaskResource, ScheduledTask>, IHandle<CommandExecutedEvent>
public class TaskModule : SonarrRestModuleWithSignalR<TaskResource, ScheduledTask>, IHandle<CommandExecutedEvent>
{
private readonly ITaskManager _taskManager;

@ -1,5 +1,5 @@
using System;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
namespace NzbDrone.Api.System.Tasks
{

@ -3,10 +3,12 @@ using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tags;
using NzbDrone.SignalR;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Tags
{
public class TagModule : NzbDroneRestModuleWithSignalR<TagResource, Tag>, IHandle<TagsUpdatedEvent>
public class TagModule : SonarrRestModuleWithSignalR<TagResource, Tag>, IHandle<TagsUpdatedEvent>
{
private readonly ITagService _tagService;

@ -1,6 +1,6 @@
using System.Collections.Generic;
using Sonarr.Http.REST;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.Tags;
namespace NzbDrone.Api.Tags

@ -2,10 +2,12 @@
using System.Linq;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Update;
using Sonarr.Http;
using Sonarr.Http.Mapping;
namespace NzbDrone.Api.Update
{
public class UpdateModule : NzbDroneRestModule<UpdateResource>
public class UpdateModule : SonarrRestModule<UpdateResource>
{
private readonly IRecentUpdateProvider _recentUpdateProvider;

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using NzbDrone.Api.REST;
using Sonarr.Http.REST;
using NzbDrone.Core.Update;
namespace NzbDrone.Api.Update

@ -1,8 +1,10 @@
using NzbDrone.Api.Episodes;
using System.Linq;
using NzbDrone.Api.Episodes;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv;
using NzbDrone.SignalR;
using Sonarr.Http;
namespace NzbDrone.Api.Wanted
{
@ -24,14 +26,15 @@ namespace NzbDrone.Api.Wanted
private PagingResource<EpisodeResource> GetCutoffUnmetEpisodes(PagingResource<EpisodeResource> pagingResource)
{
var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>("airDateUtc", SortDirection.Descending);
var filter = pagingResource.Filters.FirstOrDefault(f => f.Key == "monitored");
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
if (filter != null && filter.Value == "false")
{
pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false;
pagingSpec.FilterExpressions.Add(v => v.Monitored == false || v.Series.Monitored == false);
}
else
{
pagingSpec.FilterExpression = v => v.Monitored == true && v.Series.Monitored == true;
pagingSpec.FilterExpressions.Add(v => v.Monitored == true && v.Series.Monitored == true);
}
var resource = ApplyToPage(_episodeCutoffService.EpisodesWhereCutoffUnmet, pagingSpec, v => MapToResource(v, true, true));

@ -1,8 +1,10 @@
using NzbDrone.Api.Episodes;
using System.Linq;
using NzbDrone.Api.Episodes;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv;
using NzbDrone.SignalR;
using Sonarr.Http;
namespace NzbDrone.Api.Wanted
{
@ -20,14 +22,15 @@ namespace NzbDrone.Api.Wanted
private PagingResource<EpisodeResource> GetMissingEpisodes(PagingResource<EpisodeResource> pagingResource)
{
var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>("airDateUtc", SortDirection.Descending);
var monitoredFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "monitored");
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
if (monitoredFilter != null && monitoredFilter.Value == "false")
{
pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false;
pagingSpec.FilterExpressions.Add(v => v.Monitored == false || v.Series.Monitored == false);
}
else
{
pagingSpec.FilterExpression = v => v.Monitored == true && v.Series.Monitored == true;
pagingSpec.FilterExpressions.Add(v => v.Monitored == true && v.Series.Monitored == true);
}
var resource = ApplyToPage(_episodeService.EpisodesWithoutFiles, pagingSpec, v => MapToResource(v, true, false));

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FluentAssertions;
@ -49,7 +49,7 @@ namespace NzbDrone.Common.Test.DiskTests
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
.Returns(_folders);
Subject.LookupContents(root, false).Directories.Should().NotContain(Path.Combine(root, RECYCLING_BIN));
Subject.LookupContents(root, false, false).Directories.Should().NotContain(Path.Combine(root, RECYCLING_BIN));
}
[Test]
@ -62,7 +62,7 @@ namespace NzbDrone.Common.Test.DiskTests
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
.Returns(_folders);
Subject.LookupContents(root, false).Directories.Should().NotContain(Path.Combine(root, SYSTEM_VOLUME_INFORMATION));
Subject.LookupContents(root, false, false).Directories.Should().NotContain(Path.Combine(root, SYSTEM_VOLUME_INFORMATION));
}
[Test]
@ -75,7 +75,7 @@ namespace NzbDrone.Common.Test.DiskTests
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
.Returns(_folders);
var result = Subject.LookupContents(root, false);
var result = Subject.LookupContents(root, false, false);
result.Directories.Should().HaveCount(_folders.Count - 3);

@ -1,4 +1,4 @@
using FluentAssertions;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
@ -10,7 +10,7 @@ namespace NzbDrone.Common.Test.EnvironmentInfo
[Test]
public void should_return_version()
{
BuildInfo.Version.Major.Should().BeOneOf(2, 10);
BuildInfo.Version.Major.Should().BeOneOf(3, 10);
}
[Test]
@ -20,4 +20,4 @@ namespace NzbDrone.Common.Test.EnvironmentInfo
BuildInfo.Branch.Should().NotBeNullOrWhiteSpace();
}
}
}
}

@ -1,8 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
@ -10,13 +9,13 @@ namespace NzbDrone.Common.Disk
{
public interface IFileSystemLookupService
{
FileSystemResult LookupContents(string query, bool includeFiles);
FileSystemResult LookupContents(string query, bool includeFiles, bool allowFoldersWithoutTrailingSlashes);
}
public class FileSystemLookupService : IFileSystemLookupService
{
private readonly IDiskProvider _diskProvider;
private readonly Logger _logger;
private readonly IRuntimeInfo _runtimeInfo;
private readonly HashSet<string> _setToRemove = new HashSet<string>
{
@ -48,20 +47,19 @@ namespace NzbDrone.Common.Disk
"@eadir"
};
public FileSystemLookupService(IDiskProvider diskProvider, Logger logger)
public FileSystemLookupService(IDiskProvider diskProvider, IRuntimeInfo runtimeInfo)
{
_diskProvider = diskProvider;
_logger = logger;
_runtimeInfo = runtimeInfo;
}
public FileSystemResult LookupContents(string query, bool includeFiles)
public FileSystemResult LookupContents(string query, bool includeFiles, bool allowFoldersWithoutTrailingSlashes)
{
var result = new FileSystemResult();
if (query.IsNullOrWhiteSpace())
{
if (OsInfo.IsWindows)
{
var result = new FileSystemResult();
result.Directories = GetDrives();
return result;
@ -70,67 +68,94 @@ namespace NzbDrone.Common.Disk
query = "/";
}
if (
allowFoldersWithoutTrailingSlashes &&
query.IsPathValid() &&
_diskProvider.FolderExists(query))
{
return GetResult(query, includeFiles);
}
var lastSeparatorIndex = query.LastIndexOf(Path.DirectorySeparatorChar);
var path = query.Substring(0, lastSeparatorIndex + 1);
if (lastSeparatorIndex != -1)
{
try
{
result.Parent = GetParent(path);
result.Directories = GetDirectories(path);
if (includeFiles)
{
result.Files = GetFiles(path);
}
}
catch (DirectoryNotFoundException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
catch (ArgumentException)
{
return new FileSystemResult();
}
catch (IOException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
catch (UnauthorizedAccessException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
return GetResult(path, includeFiles);
}
return result;
return new FileSystemResult();
}
private List<FileSystemModel> GetDrives()
{
return _diskProvider.GetMounts()
.Where(d =>
{
// Fow Windows Services, exclude mapped network drives.
if (_runtimeInfo.IsWindowsService)
{
return d.DriveType != DriveType.Network;
}
return true;
})
.Select(d => new FileSystemModel
{
Type = FileSystemEntityType.Drive,
Name = d.VolumeName,
Path = d.RootDirectory,
LastModified = null
})
{
Type = FileSystemEntityType.Drive,
Name = GetVolumeName(d),
Path = d.RootDirectory,
LastModified = null
})
.ToList();
}
private FileSystemResult GetResult(string path, bool includeFiles)
{
var result = new FileSystemResult();
try
{
result.Parent = GetParent(path);
result.Directories = GetDirectories(path);
if (includeFiles)
{
result.Files = GetFiles(path);
}
}
catch (DirectoryNotFoundException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
catch (ArgumentException)
{
return new FileSystemResult();
}
catch (IOException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
catch (UnauthorizedAccessException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
return result;
}
private List<FileSystemModel> GetDirectories(string path)
{
var directories = _diskProvider.GetDirectoryInfos(path)
.OrderBy(d => d.Name)
.Select(d => new FileSystemModel
{
Name = d.Name,
Path = GetDirectoryPath(d.FullName.GetActualCasing()),
LastModified = d.LastWriteTimeUtc,
Type = FileSystemEntityType.Folder
})
{
Name = d.Name,
Path = GetDirectoryPath(d.FullName.GetActualCasing()),
LastModified = d.LastWriteTimeUtc,
Type = FileSystemEntityType.Folder
})
.ToList();
directories.RemoveAll(d => _setToRemove.Contains(d.Name.ToLowerInvariant()));
@ -143,18 +168,28 @@ namespace NzbDrone.Common.Disk
return _diskProvider.GetFileInfos(path)
.OrderBy(d => d.Name)
.Select(d => new FileSystemModel
{
Name = d.Name,
Path = d.FullName.GetActualCasing(),
LastModified = d.LastWriteTimeUtc,
Extension = d.Extension,
Size = d.Length,
Type = FileSystemEntityType.File
})
{
Name = d.Name,
Path = d.FullName.GetActualCasing(),
LastModified = d.LastWriteTimeUtc,
Extension = d.Extension,
Size = d.Length,
Type = FileSystemEntityType.File
})
.ToList();
}
private string GetDirectoryPath(string path)
private static string GetVolumeName(IMount mountInfo)
{
if (mountInfo.VolumeLabel.IsNullOrWhiteSpace())
{
return mountInfo.Name;
}
return $"{mountInfo.Name} ({mountInfo.VolumeLabel})";
}
private static string GetDirectoryPath(string path)
{
if (path.Last() != Path.DirectorySeparatorChar)
{
@ -164,7 +199,7 @@ namespace NzbDrone.Common.Disk
return path;
}
private string GetParent(string path)
private static string GetParent(string path)
{
var di = new DirectoryInfo(path);

@ -1,12 +1,17 @@
using System;
namespace NzbDrone.Common.EnvironmentInfo
{
public interface IRuntimeInfo
{
DateTime StartTime { get; }
bool IsUserInteractive { get; }
bool IsAdmin { get; }
bool IsWindowsService { get; }
bool IsWindowsTray { get; }
bool IsExiting { get; set; }
bool IsTray { get; }
RuntimeMode Mode { get; }
bool RestartPending { get; set; }
string ExecutingApplication { get; }
}

@ -12,6 +12,7 @@ namespace NzbDrone.Common.EnvironmentInfo
public class RuntimeInfo : IRuntimeInfo
{
private readonly Logger _logger;
private readonly DateTime _startTime = DateTime.UtcNow;
public RuntimeInfo(IServiceProvider serviceProvider, Logger logger)
{
@ -37,6 +38,14 @@ namespace NzbDrone.Common.EnvironmentInfo
IsProduction = InternalIsProduction();
}
public DateTime StartTime
{
get
{
return _startTime;
}
}
public static bool IsUserInteractive => Environment.UserInteractive;
bool IRuntimeInfo.IsUserInteractive => IsUserInteractive;
@ -61,6 +70,37 @@ namespace NzbDrone.Common.EnvironmentInfo
public bool IsWindowsService { get; private set; }
public bool IsExiting { get; set; }
public bool IsTray
{
get
{
if (OsInfo.IsWindows)
{
return IsUserInteractive && Process.GetCurrentProcess().ProcessName.Equals(ProcessProvider.NZB_DRONE_PROCESS_NAME, StringComparison.InvariantCultureIgnoreCase);
}
return false;
}
}
public RuntimeMode Mode
{
get
{
if (IsWindowsService)
{
return RuntimeMode.Service;
}
if (IsTray)
{
return RuntimeMode.Tray;
}
return RuntimeMode.Console;
}
}
public bool RestartPending { get; set; }
public string ExecutingApplication { get; }

@ -0,0 +1,9 @@
namespace NzbDrone.Common.EnvironmentInfo
{
public enum RuntimeMode
{
Console,
Service,
Tray
}
}

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace NzbDrone.Common.Extensions
{
@ -108,5 +109,13 @@ namespace NzbDrone.Common.Extensions
{
return source.Select(predicate).ToList();
}
// public static IOrderedEnumerable<TEntity> OrderBy<TEntity>(this IEnumerable<TEntity> source, string propertyName, bool descending)
// {
// var property = typeof(TEntity).GetProperty(propertyName);
// Func<TEntity, Object> orderByFunc = x => property.GetValue(x, null);
//
// return descending ? source.OrderByDescending(orderByFunc) : source.OrderBy(orderByFunc);
// }
}
}

@ -97,6 +97,7 @@
<Compile Include="EnvironmentInfo\OsVersionModel.cs" />
<Compile Include="Disk\DestinationAlreadyExistsException.cs" />
<Compile Include="Exceptions\SonarrStartupException.cs" />
<Compile Include="EnvironmentInfo\RuntimeMode.cs" />
<Compile Include="Extensions\DictionaryExtensions.cs" />
<Compile Include="Disk\OsPath.cs" />
<Compile Include="Disk\DiskProviderBase.cs" />

@ -10,11 +10,17 @@ namespace NzbDrone.Common.Serializer
public static class Json
{
private static readonly JsonSerializer Serializer;
private static readonly JsonSerializerSettings SerializerSetting;
private static readonly JsonSerializerSettings SerializerSettings;
static Json()
{
SerializerSetting = new JsonSerializerSettings
SerializerSettings = GetSerializerSettings();
Serializer = JsonSerializer.Create(SerializerSettings);
}
public static JsonSerializerSettings GetSerializerSettings()
{
var serializerSettings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
NullValueHandling = NullValueHandling.Ignore,
@ -23,14 +29,11 @@ namespace NzbDrone.Common.Serializer
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
serializerSettings.Converters.Add(new StringEnumConverter { CamelCaseText = true });
serializerSettings.Converters.Add(new VersionConverter());
serializerSettings.Converters.Add(new HttpUriConverter());
SerializerSetting.Converters.Add(new StringEnumConverter { CamelCaseText = true });
//SerializerSetting.Converters.Add(new IntConverter());
SerializerSetting.Converters.Add(new VersionConverter());
SerializerSetting.Converters.Add(new HttpUriConverter());
Serializer = JsonSerializer.Create(SerializerSetting);
return serializerSettings;
}
public static T Deserialize<T>(string json) where T : new()
@ -113,7 +116,7 @@ namespace NzbDrone.Common.Serializer
public static string ToJson(this object obj)
{
return JsonConvert.SerializeObject(obj, SerializerSetting);
return JsonConvert.SerializeObject(obj, SerializerSettings);
}
public static void Serialize<TModel>(TModel model, TextWriter outputStream)

@ -1,3 +1,4 @@
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Extensions;

@ -1,4 +1,5 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Moq;

@ -8,6 +8,7 @@ using NzbDrone.Common.Disk;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.EpisodeImport;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common;
@ -39,6 +40,10 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.GetParentFolder(It.IsAny<string>()))
.Returns((string path) => Directory.GetParent(path).FullName);
Mocker.GetMock<IRootFolderService>()
.Setup(s => s.GetBestRootFolderPath(It.IsAny<string>()))
.Returns(_rootFolder);
}
private void GivenRootFolder(params string[] subfolders)

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localEpisode));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedEpisodes>()
@ -124,7 +124,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
Mocker.GetMock<IMakeImportDecision>()
.Verify(c => c.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), It.IsAny<ParsedEpisodeInfo>(), It.IsAny<bool>()),
.Verify(c => c.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), It.IsAny<ParsedEpisodeInfo>(), It.IsAny<bool>(), true),
Times.Never());
VerifyNoImport();
@ -175,7 +175,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localEpisode));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedEpisodes>()
@ -201,7 +201,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localEpisode));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedEpisodes>()
@ -271,7 +271,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localEpisode));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedEpisodes>()
@ -380,7 +380,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localEpisode));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>(), null, true, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedEpisodes>()

@ -102,7 +102,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
GivenAugmentationSuccess();
GivenSpecifications(_pass1, _pass2, _pass3, _fail1, _fail2, _fail3);
Subject.GetImportDecisions(_videoFiles, _series, downloadClientItem, null, false);
Subject.GetImportDecisions(_videoFiles, _series, downloadClientItem, null, false, true);
_fail1.Verify(c => c.IsSatisfiedBy(It.IsAny<LocalEpisode>(), downloadClientItem), Times.Once());
_fail2.Verify(c => c.IsSatisfiedBy(It.IsAny<LocalEpisode>(), downloadClientItem), Times.Once());

@ -317,5 +317,16 @@ namespace NzbDrone.Core.Test.MediaFiles
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(c => c.OriginalFilePath == $"{name}\\subfolder\\{name}.mkv".AsOsAgnostic())));
}
public void should_delete_existing_metadata_files_with_the_same_path()
{
Mocker.GetMock<IMediaFileService>()
.Setup(s => s.GetFilesWithRelativePath(It.IsAny<int>(), It.IsAny<string>()))
.Returns(Builder<EpisodeFile>.CreateListOfSize(1).BuildList());
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, false);
Mocker.GetMock<IMediaFileService>()
.Verify(v => v.Delete(It.IsAny<EpisodeFile>(), DeleteMediaFileReason.ManualOverride), Times.Once());
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save