mirror of
https://github.com/Sonarr/Sonarr.git
synced 2026-04-18 21:35:27 -04:00
Compare commits
1 Commits
v2.0.0.4323
..
stats
| Author | SHA1 | Date | |
|---|---|---|---|
| a19776553e |
@@ -1,25 +0,0 @@
|
|||||||
# This file is for unifying the coding style for different editors and IDEs
|
|
||||||
# editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*.{cs,html,js,hbs}]
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.less]
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
# They have troubles with TABS. Use 2 spaces
|
|
||||||
[{package.json,.travis.yml}]
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Provide a description of the feature request or bug, the more details the better.
|
|
||||||
Please use https://forums.sonarr.tv/ for support or other questions. (When in doubt, use the forums)
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#### Database Migration
|
|
||||||
YES | NO
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
A few sentences describing the overall goals of the pull request's commits.
|
|
||||||
|
|
||||||
#### Todos
|
|
||||||
- [ ] Tests
|
|
||||||
- [ ] Documentation
|
|
||||||
|
|
||||||
|
|
||||||
#### Issues Fixed or Closed by this PR
|
|
||||||
|
|
||||||
*
|
|
||||||
@@ -128,4 +128,3 @@ output/*
|
|||||||
._*
|
._*
|
||||||
|
|
||||||
_start
|
_start
|
||||||
_temp_*/**/*
|
|
||||||
|
|||||||
+2
-4
@@ -1,6 +1,6 @@
|
|||||||
# How to Contribute #
|
# How to Contribute #
|
||||||
|
|
||||||
We're always looking for people to help make Sonarr even better, there are a number of ways to contribute.
|
We're always looking for people to help make Sonarr even better, there are a number of ways to contribute. To get started, <a href="http://www.clahub.com/agreements/NzbDrone/NzbDrone">sign the Contributor License Agreement</a>.
|
||||||
|
|
||||||
## Documentation ##
|
## Documentation ##
|
||||||
Setup guides, FAQ, the more information we have on the wiki the better.
|
Setup guides, FAQ, the more information we have on the wiki the better.
|
||||||
@@ -18,9 +18,7 @@ Setup guides, FAQ, the more information we have on the wiki the better.
|
|||||||
1. Fork Sonarr
|
1. Fork Sonarr
|
||||||
2. Clone (develop branch) *you may need pull in submodules separately if you client doesn't clone them automatically (CurlSharp)*
|
2. Clone (develop branch) *you may need pull in submodules separately if you client doesn't clone them automatically (CurlSharp)*
|
||||||
3. Run `npm install`
|
3. Run `npm install`
|
||||||
4. Run `npm start` - Used to compile the UI components and copy them.
|
4. Run `gulp watch` - Used to compile the UI components and copy them (leave this window open)
|
||||||
Leave this window open.
|
|
||||||
If you have gulp globally installed you can use `gulp watch` instead
|
|
||||||
5. Compile in Visual Studio
|
5. Compile in Visual Studio
|
||||||
|
|
||||||
### Contributing Code ###
|
### Contributing Code ###
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
msBuild='/c/Program Files (x86)/MSBuild/14.0/Bin'
|
msBuild='/c/Windows/Microsoft.NET/Framework64/v4.0.30319/'
|
||||||
outputFolder='./_output'
|
outputFolder='./_output'
|
||||||
outputFolderMono='./_output_mono'
|
outputFolderMono='./_output_mono'
|
||||||
outputFolderOsx='./_output_osx'
|
outputFolderOsx='./_output_osx'
|
||||||
@@ -102,12 +102,12 @@ Build()
|
|||||||
RunGulp()
|
RunGulp()
|
||||||
{
|
{
|
||||||
echo "##teamcity[progressStart 'npm install']"
|
echo "##teamcity[progressStart 'npm install']"
|
||||||
npm-cache install npm || CheckExitCode npm install
|
CheckExitCode npm install
|
||||||
echo "##teamcity[progressFinish 'npm install']"
|
echo "##teamcity[progressFinish 'npm install']"
|
||||||
|
|
||||||
echo "##teamcity[progressStart 'Running gulp']"
|
echo "##teamcity[progressStart 'Running Gulp']"
|
||||||
CheckExitCode npm run build
|
CheckExitCode gulp build
|
||||||
echo "##teamcity[progressFinish 'Running gulp']"
|
echo "##teamcity[progressFinish 'Running Gulp']"
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateMdbs()
|
CreateMdbs()
|
||||||
@@ -208,9 +208,9 @@ PackageTests()
|
|||||||
find $sourceFolder -path $testSearchPattern -exec cp -r -u -T "{}" $testPackageFolder \;
|
find $sourceFolder -path $testSearchPattern -exec cp -r -u -T "{}" $testPackageFolder \;
|
||||||
|
|
||||||
if [ $runtime = "dotnet" ] ; then
|
if [ $runtime = "dotnet" ] ; then
|
||||||
$nuget install NUnit.ConsoleRunner -Version 3.2.0 -Output $testPackageFolder
|
$nuget install NUnit.Runners -Version 2.6.1 -Output $testPackageFolder
|
||||||
else
|
else
|
||||||
mono $nuget install NUnit.ConsoleRunner -Version 3.2.0 -Output $testPackageFolder
|
mono $nuget install NUnit.Runners -Version 2.6.1 -Output $testPackageFolder
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cp $outputFolder/*.dll $testPackageFolder
|
cp $outputFolder/*.dll $testPackageFolder
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
EXCLUDE="-exclude:Windows -include:IntegrationTest"
|
||||||
|
TESTDIR="."
|
||||||
|
NUNIT="$TESTDIR/NUnit.Runners.2.6.1/tools/nunit-console-x86.exe"
|
||||||
|
|
||||||
|
mono --debug --runtime=v4.0 $NUNIT $EXCLUDE -xml:NzbDrone.Api.Result.xml $TESTDIR/NzbDrone.Api.Test.dll
|
||||||
|
mono --debug --runtime=v4.0 $NUNIT $EXCLUDE -xml:NzbDrone.Core.Result.xml $TESTDIR/NzbDrone.Core.Test.dll
|
||||||
|
mono --debug --runtime=v4.0 $NUNIT $EXCLUDE -xml:NzbDrone.Integration.Result.xml $TESTDIR/NzbDrone.Integration.Test.dll
|
||||||
|
mono --debug --runtime=v4.0 $NUNIT $EXCLUDE -xml:NzbDrone.Common.Result.xml $TESTDIR/NzbDrone.Common.Test.dll
|
||||||
+6
-23
@@ -1,31 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#get the bundle's MacOS directory full path
|
#get the bundle's MacOS directory full path
|
||||||
DIR=$(cd "$(dirname "$0")"; pwd)
|
DIR=$(cd "$(dirname "$0")"; pwd)
|
||||||
|
|
||||||
#change these values to match your app
|
#change these values to match your app
|
||||||
EXE_PATH="$DIR/NzbDrone.exe"
|
EXE_PATH="$DIR/NzbDrone.exe"
|
||||||
APPNAME="Sonarr"
|
APPNAME="Sonarr"
|
||||||
|
|
||||||
#set up environment
|
#set up environment
|
||||||
if [[ -x '/opt/local/bin/mono' ]]; then
|
MONO_FRAMEWORK_PATH=/Library/Frameworks/Mono.framework/Versions/Current
|
||||||
export PATH="/opt/local/bin:$PATH"
|
export DYLD_FALLBACK_LIBRARY_PATH="$DIR:$MONO_FRAMEWORK_PATH/lib:/lib:/usr/lib"
|
||||||
fi
|
export PATH="$MONO_FRAMEWORK_PATH/bin:$PATH"
|
||||||
|
|
||||||
export DYLD_FALLBACK_LIBRARY_PATH="$DIR"
|
|
||||||
|
|
||||||
if [ -e /Library/Frameworks/Mono.framework ]; then
|
|
||||||
MONO_FRAMEWORK_PATH=/Library/Frameworks/Mono.framework/Versions/Current
|
|
||||||
export PATH="$MONO_FRAMEWORK_PATH/bin:$PATH"
|
|
||||||
export DYLD_FALLBACK_LIBRARY_PATH="$DYLD_FALLBACK_LIBRARY_PATH:$MONO_FRAMEWORK_PATH/lib"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -f '/opt/local/lib/libsqlite3.0.dylib' ]]; then
|
|
||||||
export DYLD_FALLBACK_LIBRARY_PATH="/opt/local/lib:$DYLD_FALLBACK_LIBRARY_PATH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
export DYLD_FALLBACK_LIBRARY_PATH="$DYLD_FALLBACK_LIBRARY_PATH:$HOME/lib:/usr/local/lib:/lib:/usr/lib"
|
|
||||||
|
|
||||||
#mono version check
|
#mono version check
|
||||||
REQUIRED_MAJOR=3
|
REQUIRED_MAJOR=3
|
||||||
REQUIRED_MINOR=10
|
REQUIRED_MINOR=10
|
||||||
@@ -35,9 +21,6 @@ VERSION_MSG="$APPNAME requires Mono Runtime Environment(MRE) $REQUIRED_MAJOR.$RE
|
|||||||
DOWNLOAD_URL="http://www.mono-project.com/download/#download-mac"
|
DOWNLOAD_URL="http://www.mono-project.com/download/#download-mac"
|
||||||
|
|
||||||
MONO_VERSION="$(mono --version | grep 'Mono JIT compiler version ' | cut -f5 -d\ )"
|
MONO_VERSION="$(mono --version | grep 'Mono JIT compiler version ' | cut -f5 -d\ )"
|
||||||
# if [[ -o DEBUG ]]; then osascript -e "display dialog \"MONO_VERSION: $MONO_VERSION\""; fi
|
|
||||||
|
|
||||||
|
|
||||||
MONO_VERSION_MAJOR="$(echo $MONO_VERSION | cut -f1 -d.)"
|
MONO_VERSION_MAJOR="$(echo $MONO_VERSION | cut -f1 -d.)"
|
||||||
MONO_VERSION_MINOR="$(echo $MONO_VERSION | cut -f2 -d.)"
|
MONO_VERSION_MINOR="$(echo $MONO_VERSION | cut -f2 -d.)"
|
||||||
if [ -z "$MONO_VERSION" ] \
|
if [ -z "$MONO_VERSION" ] \
|
||||||
|
|||||||
+2
-3
@@ -4,15 +4,14 @@
|
|||||||
"description": "Sonarr",
|
"description": "Sonarr",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp build",
|
"preinstall": ""
|
||||||
"start": "gulp watch"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/Sonarr/Sonarr.git"
|
"url": "git://github.com/Sonarr/Sonarr.git"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "GPL-3.0",
|
"license": "BSD",
|
||||||
"gitHead": "9ff7aa1bf7fe38c4c5bdb92f56c8ad556916ed67",
|
"gitHead": "9ff7aa1bf7fe38c4c5bdb92f56c8ad556916ed67",
|
||||||
"readmeFilename": "readme.md",
|
"readmeFilename": "readme.md",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS fee
|
|||||||
- Visual Studio 2015 [Free Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
|
- Visual Studio 2015 [Free Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
|
||||||
- [Git](http://git-scm.com/downloads)
|
- [Git](http://git-scm.com/downloads)
|
||||||
- [NodeJS](http://nodejs.org/download/)
|
- [NodeJS](http://nodejs.org/download/)
|
||||||
|
- [Gulp](http://gulpjs.com)
|
||||||
|
|
||||||
### Setup ###
|
### Setup ###
|
||||||
|
|
||||||
@@ -31,7 +32,8 @@ Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS fee
|
|||||||
- Clone the repository into your development machine. [*info*](https://help.github.com/articles/working-with-repositories)
|
- Clone the repository into your development machine. [*info*](https://help.github.com/articles/working-with-repositories)
|
||||||
- Grab the submodules `git submodule init && git submodule update`
|
- Grab the submodules `git submodule init && git submodule update`
|
||||||
- install the required Node Packages `npm install`
|
- install the required Node Packages `npm install`
|
||||||
- start gulp to monitor your dev environment for any changes that need post processing using `npm start` command.
|
- install gulp `npm install gulp -g`
|
||||||
|
- start gulp to monitor your dev environment for any changes that need post processing using `gulp watch` command.
|
||||||
|
|
||||||
*Please note gulp must be running at all times while you are working with Sonarr client source files.*
|
*Please note gulp must be running at all times while you are working with Sonarr client source files.*
|
||||||
|
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ namespace LogentriesCore
|
|||||||
WriteDebugMessages("HostName parameter is not defined - trying to get it from System.Environment.MachineName");
|
WriteDebugMessages("HostName parameter is not defined - trying to get it from System.Environment.MachineName");
|
||||||
m_HostName = "HostName=" + System.Environment.MachineName + " ";
|
m_HostName = "HostName=" + System.Environment.MachineName + " ";
|
||||||
}
|
}
|
||||||
catch (InvalidOperationException)
|
catch (InvalidOperationException ex)
|
||||||
{
|
{
|
||||||
// Cannot get host name automatically, so assume that HostName is not used
|
// Cannot get host name automatically, so assume that HostName is not used
|
||||||
// and log message is sent without it.
|
// and log message is sent without it.
|
||||||
|
|||||||
@@ -51,9 +51,8 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog">
|
||||||
<HintPath>..\packages\NLog.4.3.4\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
@@ -80,7 +79,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="fastJSON\license.txt" />
|
<None Include="fastJSON\license.txt" />
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ namespace LogentriesNLog.fastJSON
|
|||||||
SerializeNullValues = false;
|
SerializeNullValues = false;
|
||||||
UseOptimizedDatasetSchema = false;
|
UseOptimizedDatasetSchema = false;
|
||||||
UsingGlobalTypes = false;
|
UsingGlobalTypes = false;
|
||||||
UseUTCDateTime = true;
|
|
||||||
}
|
}
|
||||||
public bool UseOptimizedDatasetSchema = true;
|
public bool UseOptimizedDatasetSchema = true;
|
||||||
public bool UseFastGuid = true;
|
public bool UseFastGuid = true;
|
||||||
@@ -40,7 +39,7 @@ namespace LogentriesNLog.fastJSON
|
|||||||
return ToJSON(obj, UseSerializerExtension, UseFastGuid, UseOptimizedDatasetSchema, SerializeNullValues);
|
return ToJSON(obj, UseSerializerExtension, UseFastGuid, UseOptimizedDatasetSchema, SerializeNullValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public string ToJSON(object obj,
|
public string ToJSON(object obj,
|
||||||
bool enableSerializerExtensions,
|
bool enableSerializerExtensions,
|
||||||
bool enableFastGuid,
|
bool enableFastGuid,
|
||||||
@@ -50,13 +49,13 @@ namespace LogentriesNLog.fastJSON
|
|||||||
return new JSONSerializer(enableOptimizedDatasetSchema, enableFastGuid, enableSerializerExtensions, serializeNullValues, IndentOutput).ConvertToJSON(obj);
|
return new JSONSerializer(enableOptimizedDatasetSchema, enableFastGuid, enableSerializerExtensions, serializeNullValues, IndentOutput).ConvertToJSON(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public T ToObject<T>(string json)
|
public T ToObject<T>(string json)
|
||||||
{
|
{
|
||||||
return (T)ToObject(json, typeof(T));
|
return (T)ToObject(json, typeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public object ToObject(string json, Type type)
|
public object ToObject(string json, Type type)
|
||||||
{
|
{
|
||||||
var ht = new JsonParser(json).Decode() as Dictionary<string, object>;
|
var ht = new JsonParser(json).Decode() as Dictionary<string, object>;
|
||||||
@@ -321,7 +320,7 @@ namespace LogentriesNLog.fastJSON
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_getterscache.Add(type, getters);
|
_getterscache.Add(type, getters);
|
||||||
return getters;
|
return getters;
|
||||||
}
|
}
|
||||||
@@ -449,7 +448,7 @@ namespace LogentriesNLog.fastJSON
|
|||||||
#if !SILVERLIGHT
|
#if !SILVERLIGHT
|
||||||
else if (pi.isDictionary || pi.isHashtable)
|
else if (pi.isDictionary || pi.isHashtable)
|
||||||
oset = CreateDictionary((ArrayList)v, pi.pt, pi.GenericTypes, globaltypes);
|
oset = CreateDictionary((ArrayList)v, pi.pt, pi.GenericTypes, globaltypes);
|
||||||
#else
|
#else
|
||||||
else if (pi.isDictionary)
|
else if (pi.isDictionary)
|
||||||
oset = CreateDictionary((List<object>)v, pi.pt, pi.GenericTypes, globaltypes);
|
oset = CreateDictionary((List<object>)v, pi.pt, pi.GenericTypes, globaltypes);
|
||||||
#endif
|
#endif
|
||||||
@@ -818,4 +817,4 @@ namespace LogentriesNLog.fastJSON
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,8 +170,6 @@ namespace LogentriesNLog.fastJSON
|
|||||||
_output.Append(dt.Minute.ToString("00", NumberFormatInfo.InvariantInfo));
|
_output.Append(dt.Minute.ToString("00", NumberFormatInfo.InvariantInfo));
|
||||||
_output.Append(":");
|
_output.Append(":");
|
||||||
_output.Append(dt.Second.ToString("00", NumberFormatInfo.InvariantInfo));
|
_output.Append(dt.Second.ToString("00", NumberFormatInfo.InvariantInfo));
|
||||||
_output.Append(".");
|
|
||||||
_output.Append(dt.Millisecond.ToString("000", NumberFormatInfo.InvariantInfo));
|
|
||||||
|
|
||||||
if (JSON.Instance.UseUTCDateTime)
|
if (JSON.Instance.UseUTCDateTime)
|
||||||
_output.Append("Z");
|
_output.Append("Z");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="NLog" version="4.3.4" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
||||||
|
|||||||
@@ -774,8 +774,7 @@ namespace MonoTorrent
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ("nodes"):
|
case ("nodes"):
|
||||||
if (keypair.Value.ToString().Length != 0)
|
this.nodes = (BEncodedList)keypair.Value;
|
||||||
this.nodes = (BEncodedList)keypair.Value;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ("comment.utf-8"):
|
case ("comment.utf-8"):
|
||||||
|
|||||||
@@ -0,0 +1,168 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Marr.Data;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Api.Commands;
|
||||||
|
using NzbDrone.Api.Config;
|
||||||
|
using NzbDrone.Api.Episodes;
|
||||||
|
using NzbDrone.Api.History;
|
||||||
|
using NzbDrone.Api.Indexers;
|
||||||
|
using NzbDrone.Api.Logs;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
|
using NzbDrone.Api.Profiles;
|
||||||
|
using NzbDrone.Api.RootFolders;
|
||||||
|
using NzbDrone.Api.Series;
|
||||||
|
using NzbDrone.Core.DecisionEngine;
|
||||||
|
using NzbDrone.Core.Instrumentation;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Profiles;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.RootFolders;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.Update.Commands;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Test.MappingTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ResourceMappingFixture : TestBase
|
||||||
|
{
|
||||||
|
[TestCase(typeof(Core.Tv.Series), typeof(SeriesResource))]
|
||||||
|
[TestCase(typeof(Episode), typeof(EpisodeResource))]
|
||||||
|
[TestCase(typeof(RootFolder), typeof(RootFolderResource))]
|
||||||
|
[TestCase(typeof(NamingConfig), typeof(NamingConfigResource))]
|
||||||
|
// [TestCase(typeof(IndexerDefinition), typeof(IndexerResource))] //TODO: Ignoring because we don't have a good way to ignore properties with value injector
|
||||||
|
[TestCase(typeof(ReleaseInfo), typeof(ReleaseResource))]
|
||||||
|
[TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))]
|
||||||
|
[TestCase(typeof(DownloadDecision), typeof(ReleaseResource))]
|
||||||
|
[TestCase(typeof(Core.History.History), typeof(HistoryResource))]
|
||||||
|
[TestCase(typeof(Profile), typeof(ProfileResource))]
|
||||||
|
[TestCase(typeof(ProfileQualityItem), typeof(ProfileQualityItemResource))]
|
||||||
|
[TestCase(typeof(Log), typeof(LogResource))]
|
||||||
|
[TestCase(typeof(Command), typeof(CommandResource))]
|
||||||
|
public void matching_fields(Type modelType, Type resourceType)
|
||||||
|
{
|
||||||
|
MappingValidation.ValidateMapping(modelType, resourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_map_lazy_loaded_values_should_not_be_inject_if_not_loaded()
|
||||||
|
{
|
||||||
|
var modelWithLazy = new ModelWithLazy()
|
||||||
|
{
|
||||||
|
Guid = new TestLazyLoaded<Guid>()
|
||||||
|
};
|
||||||
|
|
||||||
|
modelWithLazy.InjectTo<ModelWithNoLazy>().Guid.Should().BeEmpty();
|
||||||
|
|
||||||
|
modelWithLazy.Guid.IsLoaded.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_map_lay_loaded_values_should_be_inject_if_loaded()
|
||||||
|
{
|
||||||
|
|
||||||
|
var guid = Guid.NewGuid();
|
||||||
|
|
||||||
|
var modelWithLazy = new ModelWithLazy()
|
||||||
|
{
|
||||||
|
Guid = new LazyLoaded<Guid>(guid)
|
||||||
|
};
|
||||||
|
|
||||||
|
modelWithLazy.InjectTo<ModelWithNoLazy>().Guid.Should().Be(guid);
|
||||||
|
|
||||||
|
modelWithLazy.Guid.IsLoaded.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_able_to_map_lists()
|
||||||
|
{
|
||||||
|
var modelList = Builder<TestModel>.CreateListOfSize(10).Build();
|
||||||
|
|
||||||
|
var resourceList = modelList.InjectTo<List<TestResource>>();
|
||||||
|
|
||||||
|
resourceList.Should().HaveSameCount(modelList);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_map_wrapped_models()
|
||||||
|
{
|
||||||
|
var modelList = Builder<TestModel>.CreateListOfSize(10).Build().ToList();
|
||||||
|
|
||||||
|
var wrapper = new TestModelWrapper
|
||||||
|
{
|
||||||
|
TestlList = modelList
|
||||||
|
};
|
||||||
|
|
||||||
|
wrapper.InjectTo<TestResourceWrapper>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_map_profile()
|
||||||
|
{
|
||||||
|
var profileResource = new ProfileResource
|
||||||
|
{
|
||||||
|
Cutoff = Quality.WEBDL1080p,
|
||||||
|
Items = new List<ProfileQualityItemResource> { new ProfileQualityItemResource { Quality = Quality.WEBDL1080p, Allowed = true } }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
profileResource.InjectTo<Profile>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_map_tracked_command()
|
||||||
|
{
|
||||||
|
var commandResource = new CommandModel { Body = new ApplicationUpdateCommand() };
|
||||||
|
commandResource.InjectTo<CommandResource>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ModelWithLazy
|
||||||
|
{
|
||||||
|
public LazyLoaded<Guid> Guid { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ModelWithNoLazy
|
||||||
|
{
|
||||||
|
public Guid Guid { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestLazyLoaded<T> : LazyLoaded<T>
|
||||||
|
{
|
||||||
|
public override void Prepare(Func<IDataMapper> dataMapperFactory, object parent)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class TestModelWrapper
|
||||||
|
{
|
||||||
|
public List<TestModel> TestlList { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestResourceWrapper
|
||||||
|
{
|
||||||
|
public List<TestResource> TestList { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestModel
|
||||||
|
{
|
||||||
|
public string Field1 { get; set; }
|
||||||
|
public string Field2 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestResource
|
||||||
|
{
|
||||||
|
public string Field1 { get; set; }
|
||||||
|
public string Field2 { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,9 +46,9 @@
|
|||||||
<HintPath>..\packages\FluentAssertions.4.2.1\lib\net40\FluentAssertions.Core.dll</HintPath>
|
<HintPath>..\packages\FluentAssertions.4.2.1\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=3.2.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NUnit.3.2.0\lib\net40\nunit.framework.dll</HintPath>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<Private>True</Private>
|
<HintPath>..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
@@ -63,9 +63,13 @@
|
|||||||
<Reference Include="Moq">
|
<Reference Include="Moq">
|
||||||
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
|
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Omu.ValueInjecter">
|
||||||
|
<HintPath>..\packages\ValueInjecter.2.3.3\lib\net35\Omu.ValueInjecter.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ClientSchemaTests\SchemaBuilderFixture.cs" />
|
<Compile Include="ClientSchemaTests\SchemaBuilderFixture.cs" />
|
||||||
|
<Compile Include="MappingTests\ResourceMappingFixture.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -107,4 +111,4 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -3,5 +3,6 @@
|
|||||||
<package id="FluentAssertions" version="4.2.1" targetFramework="net40" />
|
<package id="FluentAssertions" version="4.2.1" targetFramework="net40" />
|
||||||
<package id="Moq" version="4.0.10827" />
|
<package id="Moq" version="4.0.10827" />
|
||||||
<package id="NBuilder" version="3.0.1.1" targetFramework="net40" />
|
<package id="NBuilder" version="3.0.1.1" targetFramework="net40" />
|
||||||
<package id="NUnit" version="3.2.0" targetFramework="net40" />
|
<package id="NUnit" version="2.6.3" targetFramework="net40" />
|
||||||
|
<package id="ValueInjecter" version="2.3.3" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -27,8 +27,6 @@ namespace NzbDrone.Api.Authentication
|
|||||||
_configFileProvider = configFileProvider;
|
_configFileProvider = configFileProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order { get { return 10; } }
|
|
||||||
|
|
||||||
public void Register(IPipelines pipelines)
|
public void Register(IPipelines pipelines)
|
||||||
{
|
{
|
||||||
if (_configFileProvider.AuthenticationMethod == AuthenticationType.Forms)
|
if (_configFileProvider.AuthenticationMethod == AuthenticationType.Forms)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using NzbDrone.Core.Blacklisting;
|
||||||
using NzbDrone.Core.Blacklisting;
|
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Blacklist
|
namespace NzbDrone.Api.Blacklist
|
||||||
@@ -17,9 +16,15 @@ namespace NzbDrone.Api.Blacklist
|
|||||||
|
|
||||||
private PagingResource<BlacklistResource> GetBlacklist(PagingResource<BlacklistResource> pagingResource)
|
private PagingResource<BlacklistResource> GetBlacklist(PagingResource<BlacklistResource> pagingResource)
|
||||||
{
|
{
|
||||||
var pagingSpec = pagingResource.MapToPagingSpec<BlacklistResource, Core.Blacklisting.Blacklist>("id", SortDirection.Ascending);
|
var pagingSpec = new PagingSpec<Core.Blacklisting.Blacklist>
|
||||||
|
{
|
||||||
|
Page = pagingResource.Page,
|
||||||
|
PageSize = pagingResource.PageSize,
|
||||||
|
SortKey = pagingResource.SortKey,
|
||||||
|
SortDirection = pagingResource.SortDirection
|
||||||
|
};
|
||||||
|
|
||||||
return ApplyToPage(_blacklistService.Paged, pagingSpec, BlacklistResourceMapper.MapToResource);
|
return ApplyToPage(_blacklistService.Paged, pagingSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteBlacklist(int id)
|
private void DeleteBlacklist(int id)
|
||||||
@@ -27,4 +32,4 @@ namespace NzbDrone.Api.Blacklist
|
|||||||
_blacklistService.Delete(id);
|
_blacklistService.Delete(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,28 +20,4 @@ namespace NzbDrone.Api.Blacklist
|
|||||||
|
|
||||||
public SeriesResource Series { get; set; }
|
public SeriesResource Series { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BlacklistResourceMapper
|
|
||||||
{
|
|
||||||
public static BlacklistResource MapToResource(this Core.Blacklisting.Blacklist model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new BlacklistResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
EpisodeIds = model.EpisodeIds,
|
|
||||||
SourceTitle = model.SourceTitle,
|
|
||||||
Quality = model.Quality,
|
|
||||||
Date = model.Date,
|
|
||||||
Protocol = model.Protocol,
|
|
||||||
Indexer = model.Indexer,
|
|
||||||
Message = model.Message,
|
|
||||||
|
|
||||||
Series = model.Series.ToResource()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,12 @@ namespace NzbDrone.Api.Calendar
|
|||||||
var futureDays = 28;
|
var futureDays = 28;
|
||||||
var start = DateTime.Today.AddDays(-pastDays);
|
var start = DateTime.Today.AddDays(-pastDays);
|
||||||
var end = DateTime.Today.AddDays(futureDays);
|
var end = DateTime.Today.AddDays(futureDays);
|
||||||
var unmonitored = false;
|
|
||||||
|
|
||||||
// TODO: Remove start/end parameters in v3, they don't work well for iCal
|
// TODO: Remove start/end parameters in v3, they don't work well for iCal
|
||||||
var queryStart = Request.Query.Start;
|
var queryStart = Request.Query.Start;
|
||||||
var queryEnd = Request.Query.End;
|
var queryEnd = Request.Query.End;
|
||||||
var queryPastDays = Request.Query.PastDays;
|
var queryPastDays = Request.Query.PastDays;
|
||||||
var queryFutureDays = Request.Query.FutureDays;
|
var queryFutureDays = Request.Query.FutureDays;
|
||||||
var queryUnmonitored = Request.Query.Unmonitored;
|
|
||||||
|
|
||||||
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
|
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
|
||||||
if (queryEnd.HasValue) end = DateTime.Parse(queryEnd.Value);
|
if (queryEnd.HasValue) end = DateTime.Parse(queryEnd.Value);
|
||||||
@@ -50,12 +48,7 @@ namespace NzbDrone.Api.Calendar
|
|||||||
end = DateTime.Today.AddDays(futureDays);
|
end = DateTime.Today.AddDays(futureDays);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryUnmonitored.HasValue)
|
var episodes = _episodeService.EpisodesBetweenDates(start, end, false);
|
||||||
{
|
|
||||||
unmonitored = bool.Parse(queryUnmonitored.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
var episodes = _episodeService.EpisodesBetweenDates(start, end, unmonitored);
|
|
||||||
var icalCalendar = new iCalendar();
|
var icalCalendar = new iCalendar();
|
||||||
|
|
||||||
foreach (var episode in episodes.OrderBy(v => v.AirDateUtc.Value))
|
foreach (var episode in episodes.OrderBy(v => v.AirDateUtc.Value))
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace NzbDrone.Api.Calendar
|
|||||||
if (queryEnd.HasValue) end = DateTime.Parse(queryEnd.Value);
|
if (queryEnd.HasValue) end = DateTime.Parse(queryEnd.Value);
|
||||||
if (queryIncludeUnmonitored.HasValue) includeUnmonitored = Convert.ToBoolean(queryIncludeUnmonitored.Value);
|
if (queryIncludeUnmonitored.HasValue) includeUnmonitored = Convert.ToBoolean(queryIncludeUnmonitored.Value);
|
||||||
|
|
||||||
var resources = MapToResource(_episodeService.EpisodesBetweenDates(start, end, includeUnmonitored), true, true);
|
var resources = ToListResource(() => _episodeService.EpisodesBetweenDates(start, end, includeUnmonitored));
|
||||||
|
|
||||||
return resources.OrderBy(e => e.AirDateUtc).ToList();
|
return resources.OrderBy(e => e.AirDateUtc).ToList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using NzbDrone.Common.EnsureThat;
|
|||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Reflection;
|
using NzbDrone.Common.Reflection;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Api.ClientSchema
|
namespace NzbDrone.Api.ClientSchema
|
||||||
{
|
{
|
||||||
@@ -55,7 +56,7 @@ namespace NzbDrone.Api.ClientSchema
|
|||||||
return result.OrderBy(r => r.Order).ToList();
|
return result.OrderBy(r => r.Order).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object ReadFromSchema(List<Field> fields, Type targetType)
|
public static object ReadFormSchema(List<Field> fields, Type targetType, object defaults = null)
|
||||||
{
|
{
|
||||||
Ensure.That(targetType, () => targetType).IsNotNull();
|
Ensure.That(targetType, () => targetType).IsNotNull();
|
||||||
|
|
||||||
@@ -63,6 +64,11 @@ namespace NzbDrone.Api.ClientSchema
|
|||||||
|
|
||||||
var target = Activator.CreateInstance(targetType);
|
var target = Activator.CreateInstance(targetType);
|
||||||
|
|
||||||
|
if (defaults != null)
|
||||||
|
{
|
||||||
|
target.InjectFrom(defaults);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var propertyInfo in properties)
|
foreach (var propertyInfo in properties)
|
||||||
{
|
{
|
||||||
var fieldAttribute = propertyInfo.GetAttribute<FieldDefinitionAttribute>(false);
|
var fieldAttribute = propertyInfo.GetAttribute<FieldDefinitionAttribute>(false);
|
||||||
@@ -140,9 +146,9 @@ namespace NzbDrone.Api.ClientSchema
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T ReadFromSchema<T>(List<Field> fields)
|
public static T ReadFormSchema<T>(List<Field> fields)
|
||||||
{
|
{
|
||||||
return (T)ReadFromSchema(fields, typeof(T));
|
return (T)ReadFormSchema(fields, typeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<SelectOption> GetSelectOptions(Type selectOptions)
|
private static List<SelectOption> GetSelectOptions(Type selectOptions)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Api.Validation;
|
using NzbDrone.Api.Validation;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
@@ -35,13 +36,15 @@ namespace NzbDrone.Api.Commands
|
|||||||
|
|
||||||
private CommandResource GetCommand(int id)
|
private CommandResource GetCommand(int id)
|
||||||
{
|
{
|
||||||
return _commandQueueManager.Get(id).ToResource();
|
return _commandQueueManager.Get(id).InjectTo<CommandResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int StartCommand(CommandResource commandResource)
|
private int StartCommand(CommandResource commandResource)
|
||||||
{
|
{
|
||||||
var commandType = _serviceFactory.GetImplementations(typeof(Command))
|
var commandType =
|
||||||
.Single(c => c.Name.Replace("Command", "").Equals(commandResource.Name, StringComparison.InvariantCultureIgnoreCase));
|
_serviceFactory.GetImplementations(typeof (Command))
|
||||||
|
.Single(c => c.Name.Replace("Command", "")
|
||||||
|
.Equals(commandResource.Name, StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
|
||||||
dynamic command = Request.Body.FromJson(commandType);
|
dynamic command = Request.Body.FromJson(commandType);
|
||||||
command.Trigger = CommandTrigger.Manual;
|
command.Trigger = CommandTrigger.Manual;
|
||||||
@@ -52,14 +55,14 @@ namespace NzbDrone.Api.Commands
|
|||||||
|
|
||||||
private List<CommandResource> GetStartedCommands()
|
private List<CommandResource> GetStartedCommands()
|
||||||
{
|
{
|
||||||
return _commandQueueManager.GetStarted().ToResource();
|
return ToListResource(_commandQueueManager.GetStarted());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(CommandUpdatedEvent message)
|
public void Handle(CommandUpdatedEvent message)
|
||||||
{
|
{
|
||||||
if (message.Command.Body.SendUpdatesToClient)
|
if (message.Command.Body.SendUpdatesToClient)
|
||||||
{
|
{
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Command.ToResource());
|
BroadcastResourceChange(ModelAction.Updated, message.Command.InjectTo<CommandResource>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
@@ -11,7 +9,7 @@ namespace NzbDrone.Api.Commands
|
|||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public object Body { get; set; }
|
public Command Body { get; set; }
|
||||||
public CommandPriority Priority { get; set; }
|
public CommandPriority Priority { get; set; }
|
||||||
public CommandStatus Status { get; set; }
|
public CommandStatus Status { get; set; }
|
||||||
public DateTime Queued { get; set; }
|
public DateTime Queued { get; set; }
|
||||||
@@ -72,7 +70,7 @@ namespace NzbDrone.Api.Commands
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Body != null) return (Body as Command).SendUpdatesToClient;
|
if (Body != null) return Body.SendUpdatesToClient;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -84,7 +82,7 @@ namespace NzbDrone.Api.Commands
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Body != null) return (Body as Command).UpdateScheduledTask;
|
if (Body != null) return Body.UpdateScheduledTask;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -94,37 +92,4 @@ namespace NzbDrone.Api.Commands
|
|||||||
|
|
||||||
public DateTime? LastExecutionTime { get; set; }
|
public DateTime? LastExecutionTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CommandResourceMapper
|
|
||||||
{
|
|
||||||
public static CommandResource ToResource(this CommandModel model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new CommandResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
Name = model.Name,
|
|
||||||
Message = model.Message,
|
|
||||||
Body = model.Body,
|
|
||||||
Priority = model.Priority,
|
|
||||||
Status = model.Status,
|
|
||||||
Queued = model.QueuedAt,
|
|
||||||
Started = model.StartedAt,
|
|
||||||
Ended = model.EndedAt,
|
|
||||||
Duration = model.Duration,
|
|
||||||
Exception = model.Exception,
|
|
||||||
Trigger = model.Trigger,
|
|
||||||
|
|
||||||
CompletionMessage = model.Body.CompletionMessage,
|
|
||||||
LastExecutionTime = model.Body.LastExecutionTime
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<CommandResource> ToResource(this IEnumerable<CommandModel> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,5 @@ namespace NzbDrone.Api.Config
|
|||||||
.SetValidator(pathExistsValidator)
|
.SetValidator(pathExistsValidator)
|
||||||
.When(c => !string.IsNullOrWhiteSpace(c.DownloadedEpisodesFolder));
|
.When(c => !string.IsNullOrWhiteSpace(c.DownloadedEpisodesFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DownloadClientConfigResource ToResource(IConfigService model)
|
|
||||||
{
|
|
||||||
return DownloadClientConfigResourceMapper.ToResource(model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
@@ -16,23 +15,4 @@ namespace NzbDrone.Api.Config
|
|||||||
public bool AutoRedownloadFailed { get; set; }
|
public bool AutoRedownloadFailed { get; set; }
|
||||||
public bool RemoveFailedDownloads { get; set; }
|
public bool RemoveFailedDownloads { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DownloadClientConfigResourceMapper
|
|
||||||
{
|
|
||||||
public static DownloadClientConfigResource ToResource(IConfigService model)
|
|
||||||
{
|
|
||||||
return new DownloadClientConfigResource
|
|
||||||
{
|
|
||||||
DownloadedEpisodesFolder = model.DownloadedEpisodesFolder,
|
|
||||||
DownloadClientWorkingFolders = model.DownloadClientWorkingFolders,
|
|
||||||
DownloadedEpisodesScanInterval = model.DownloadedEpisodesScanInterval,
|
|
||||||
|
|
||||||
EnableCompletedDownloadHandling = model.EnableCompletedDownloadHandling,
|
|
||||||
RemoveCompletedDownloads = model.RemoveCompletedDownloads,
|
|
||||||
|
|
||||||
AutoRedownloadFailed = model.AutoRedownloadFailed,
|
|
||||||
RemoveFailedDownloads = model.RemoveFailedDownloads
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,20 +8,19 @@ using NzbDrone.Core.Configuration;
|
|||||||
using NzbDrone.Core.Update;
|
using NzbDrone.Core.Update;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
using NzbDrone.Core.Validation.Paths;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
public class HostConfigModule : NzbDroneRestModule<HostConfigResource>
|
public class HostConfigModule : NzbDroneRestModule<HostConfigResource>
|
||||||
{
|
{
|
||||||
private readonly IConfigFileProvider _configFileProvider;
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
private readonly IConfigService _configService;
|
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
|
|
||||||
public HostConfigModule(IConfigFileProvider configFileProvider, IConfigService configService, IUserService userService)
|
public HostConfigModule(IConfigFileProvider configFileProvider, IUserService userService)
|
||||||
: base("/config/host")
|
: base("/config/host")
|
||||||
{
|
{
|
||||||
_configFileProvider = configFileProvider;
|
_configFileProvider = configFileProvider;
|
||||||
_configService = configService;
|
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
|
|
||||||
GetResourceSingle = GetHostConfig;
|
GetResourceSingle = GetHostConfig;
|
||||||
@@ -49,10 +48,12 @@ namespace NzbDrone.Api.Config
|
|||||||
|
|
||||||
private HostConfigResource GetHostConfig()
|
private HostConfigResource GetHostConfig()
|
||||||
{
|
{
|
||||||
var resource = _configFileProvider.ToResource(_configService);
|
var resource = new HostConfigResource();
|
||||||
|
resource.InjectFrom(_configFileProvider);
|
||||||
resource.Id = 1;
|
resource.Id = 1;
|
||||||
|
|
||||||
var user = _userService.FindUser();
|
var user = _userService.FindUser();
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
resource.Username = user.Username;
|
resource.Username = user.Username;
|
||||||
@@ -74,7 +75,6 @@ namespace NzbDrone.Api.Config
|
|||||||
.ToDictionary(prop => prop.Name, prop => prop.GetValue(resource, null));
|
.ToDictionary(prop => prop.Name, prop => prop.GetValue(resource, null));
|
||||||
|
|
||||||
_configFileProvider.SaveConfigDictionary(dictionary);
|
_configFileProvider.SaveConfigDictionary(dictionary);
|
||||||
_configService.SaveConfigDictionary(dictionary);
|
|
||||||
|
|
||||||
if (resource.Username.IsNotNullOrWhiteSpace() && resource.Password.IsNotNullOrWhiteSpace())
|
if (resource.Username.IsNotNullOrWhiteSpace() && resource.Password.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Authentication;
|
using NzbDrone.Core.Authentication;
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
using NzbDrone.Core.Update;
|
using NzbDrone.Core.Update;
|
||||||
using NzbDrone.Common.Http.Proxy;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
@@ -21,54 +19,11 @@ namespace NzbDrone.Api.Config
|
|||||||
public string LogLevel { get; set; }
|
public string LogLevel { get; set; }
|
||||||
public string Branch { get; set; }
|
public string Branch { get; set; }
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
public bool Torrent { get; set; }
|
||||||
public string SslCertHash { get; set; }
|
public string SslCertHash { get; set; }
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
public bool UpdateAutomatically { get; set; }
|
public bool UpdateAutomatically { get; set; }
|
||||||
public UpdateMechanism UpdateMechanism { get; set; }
|
public UpdateMechanism UpdateMechanism { get; set; }
|
||||||
public string UpdateScriptPath { get; set; }
|
public string UpdateScriptPath { get; set; }
|
||||||
public bool ProxyEnabled { get; set; }
|
|
||||||
public ProxyType ProxyType { get; set; }
|
|
||||||
public string ProxyHostname { get; set; }
|
|
||||||
public int ProxyPort { get; set; }
|
|
||||||
public string ProxyUsername { get; set; }
|
|
||||||
public string ProxyPassword { get; set; }
|
|
||||||
public string ProxyBypassFilter { get; set; }
|
|
||||||
public bool ProxyBypassLocalAddresses { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HostConfigResourceMapper
|
|
||||||
{
|
|
||||||
public static HostConfigResource ToResource(this IConfigFileProvider model, IConfigService configService)
|
|
||||||
{
|
|
||||||
// TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead?
|
|
||||||
return new HostConfigResource
|
|
||||||
{
|
|
||||||
BindAddress = model.BindAddress,
|
|
||||||
Port = model.Port,
|
|
||||||
SslPort = model.SslPort,
|
|
||||||
EnableSsl = model.EnableSsl,
|
|
||||||
LaunchBrowser = model.LaunchBrowser,
|
|
||||||
AuthenticationMethod = model.AuthenticationMethod,
|
|
||||||
AnalyticsEnabled = model.AnalyticsEnabled,
|
|
||||||
//Username
|
|
||||||
//Password
|
|
||||||
LogLevel = model.LogLevel,
|
|
||||||
Branch = model.Branch,
|
|
||||||
ApiKey = model.ApiKey,
|
|
||||||
SslCertHash = model.SslCertHash,
|
|
||||||
UrlBase = model.UrlBase,
|
|
||||||
UpdateAutomatically = model.UpdateAutomatically,
|
|
||||||
UpdateMechanism = model.UpdateMechanism,
|
|
||||||
UpdateScriptPath = model.UpdateScriptPath,
|
|
||||||
ProxyEnabled = configService.ProxyEnabled,
|
|
||||||
ProxyType = configService.ProxyType,
|
|
||||||
ProxyHostname = configService.ProxyHostname,
|
|
||||||
ProxyPort = configService.ProxyPort,
|
|
||||||
ProxyUsername = configService.ProxyUsername,
|
|
||||||
ProxyPassword = configService.ProxyPassword,
|
|
||||||
ProxyBypassFilter = configService.ProxyBypassFilter,
|
|
||||||
ProxyBypassLocalAddresses = configService.ProxyBypassLocalAddresses
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using FluentValidation;
|
||||||
using FluentValidation;
|
|
||||||
using NzbDrone.Api.Validation;
|
using NzbDrone.Api.Validation;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
|
||||||
@@ -20,10 +19,5 @@ namespace NzbDrone.Api.Config
|
|||||||
SharedValidator.RuleFor(c => c.RssSyncInterval)
|
SharedValidator.RuleFor(c => c.RssSyncInterval)
|
||||||
.IsValidRssSyncInterval();
|
.IsValidRssSyncInterval();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IndexerConfigResource ToResource(IConfigService model)
|
|
||||||
{
|
|
||||||
return IndexerConfigResourceMapper.ToResource(model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
@@ -10,17 +9,4 @@ namespace NzbDrone.Api.Config
|
|||||||
public int Retention { get; set; }
|
public int Retention { get; set; }
|
||||||
public int RssSyncInterval { get; set; }
|
public int RssSyncInterval { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IndexerConfigResourceMapper
|
|
||||||
{
|
|
||||||
public static IndexerConfigResource ToResource(IConfigService model)
|
|
||||||
{
|
|
||||||
return new IndexerConfigResource
|
|
||||||
{
|
|
||||||
MinimumAge = model.MinimumAge,
|
|
||||||
Retention = model.Retention,
|
|
||||||
RssSyncInterval = model.RssSyncInterval,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,5 @@ namespace NzbDrone.Api.Config
|
|||||||
SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
|
SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
|
||||||
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin));
|
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override MediaManagementConfigResource ToResource(IConfigService model)
|
|
||||||
{
|
|
||||||
return MediaManagementConfigResourceMapper.ToResource(model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
@@ -23,29 +22,4 @@ namespace NzbDrone.Api.Config
|
|||||||
public bool CopyUsingHardlinks { get; set; }
|
public bool CopyUsingHardlinks { get; set; }
|
||||||
public bool EnableMediaInfo { get; set; }
|
public bool EnableMediaInfo { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MediaManagementConfigResourceMapper
|
|
||||||
{
|
|
||||||
public static MediaManagementConfigResource ToResource(IConfigService model)
|
|
||||||
{
|
|
||||||
return new MediaManagementConfigResource
|
|
||||||
{
|
|
||||||
AutoUnmonitorPreviouslyDownloadedEpisodes = model.AutoUnmonitorPreviouslyDownloadedEpisodes,
|
|
||||||
RecycleBin = model.RecycleBin,
|
|
||||||
AutoDownloadPropers = model.AutoDownloadPropers,
|
|
||||||
CreateEmptySeriesFolders = model.CreateEmptySeriesFolders,
|
|
||||||
FileDate = model.FileDate,
|
|
||||||
|
|
||||||
SetPermissionsLinux = model.SetPermissionsLinux,
|
|
||||||
FileChmod = model.FileChmod,
|
|
||||||
FolderChmod = model.FolderChmod,
|
|
||||||
ChownUser = model.ChownUser,
|
|
||||||
ChownGroup = model.ChownGroup,
|
|
||||||
|
|
||||||
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
|
|
||||||
CopyUsingHardlinks = model.CopyUsingHardlinks,
|
|
||||||
EnableMediaInfo = model.EnableMediaInfo,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ using Nancy.Responses;
|
|||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using Nancy.ModelBinding;
|
using Nancy.ModelBinding;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
@@ -44,7 +46,7 @@ namespace NzbDrone.Api.Config
|
|||||||
|
|
||||||
private void UpdateNamingConfig(NamingConfigResource resource)
|
private void UpdateNamingConfig(NamingConfigResource resource)
|
||||||
{
|
{
|
||||||
var nameSpec = resource.ToModel();
|
var nameSpec = resource.InjectTo<NamingConfig>();
|
||||||
ValidateFormatResult(nameSpec);
|
ValidateFormatResult(nameSpec);
|
||||||
|
|
||||||
_namingConfigService.Save(nameSpec);
|
_namingConfigService.Save(nameSpec);
|
||||||
@@ -53,14 +55,16 @@ namespace NzbDrone.Api.Config
|
|||||||
private NamingConfigResource GetNamingConfig()
|
private NamingConfigResource GetNamingConfig()
|
||||||
{
|
{
|
||||||
var nameSpec = _namingConfigService.GetConfig();
|
var nameSpec = _namingConfigService.GetConfig();
|
||||||
var resource = nameSpec.ToResource();
|
var resource = nameSpec.InjectTo<NamingConfigResource>();
|
||||||
|
|
||||||
if (resource.StandardEpisodeFormat.IsNotNullOrWhiteSpace())
|
if (string.IsNullOrWhiteSpace(resource.StandardEpisodeFormat))
|
||||||
{
|
{
|
||||||
var basicConfig = _filenameBuilder.GetBasicNamingConfig(nameSpec);
|
return resource;
|
||||||
basicConfig.AddToResource(resource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var basicConfig = _filenameBuilder.GetBasicNamingConfig(nameSpec);
|
||||||
|
resource.InjectFrom(basicConfig);
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +75,7 @@ namespace NzbDrone.Api.Config
|
|||||||
|
|
||||||
private JsonResponse<NamingSampleResource> GetExamples(NamingConfigResource config)
|
private JsonResponse<NamingSampleResource> GetExamples(NamingConfigResource config)
|
||||||
{
|
{
|
||||||
var nameSpec = config.ToModel();
|
var nameSpec = config.InjectTo<NamingConfig>();
|
||||||
var sampleResource = new NamingSampleResource();
|
var sampleResource = new NamingSampleResource();
|
||||||
|
|
||||||
var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec);
|
var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Organizer;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
@@ -21,57 +20,4 @@ namespace NzbDrone.Api.Config
|
|||||||
public string Separator { get; set; }
|
public string Separator { get; set; }
|
||||||
public string NumberStyle { get; set; }
|
public string NumberStyle { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NamingConfigResourceMapper
|
|
||||||
{
|
|
||||||
public static NamingConfigResource ToResource(this NamingConfig model)
|
|
||||||
{
|
|
||||||
return new NamingConfigResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
RenameEpisodes = model.RenameEpisodes,
|
|
||||||
ReplaceIllegalCharacters = model.ReplaceIllegalCharacters,
|
|
||||||
MultiEpisodeStyle = model.MultiEpisodeStyle,
|
|
||||||
StandardEpisodeFormat = model.StandardEpisodeFormat,
|
|
||||||
DailyEpisodeFormat = model.DailyEpisodeFormat,
|
|
||||||
AnimeEpisodeFormat = model.AnimeEpisodeFormat,
|
|
||||||
SeriesFolderFormat = model.SeriesFolderFormat,
|
|
||||||
SeasonFolderFormat = model.SeasonFolderFormat
|
|
||||||
//IncludeSeriesTitle
|
|
||||||
//IncludeEpisodeTitle
|
|
||||||
//IncludeQuality
|
|
||||||
//ReplaceSpaces
|
|
||||||
//Separator
|
|
||||||
//NumberStyle
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddToResource(this BasicNamingConfig basicNamingConfig, NamingConfigResource resource)
|
|
||||||
{
|
|
||||||
resource.IncludeSeriesTitle = basicNamingConfig.IncludeSeriesTitle;
|
|
||||||
resource.IncludeEpisodeTitle = basicNamingConfig.IncludeEpisodeTitle;
|
|
||||||
resource.IncludeQuality = basicNamingConfig.IncludeQuality;
|
|
||||||
resource.ReplaceSpaces = basicNamingConfig.ReplaceSpaces;
|
|
||||||
resource.Separator = basicNamingConfig.Separator;
|
|
||||||
resource.NumberStyle = basicNamingConfig.NumberStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NamingConfig ToModel(this NamingConfigResource resource)
|
|
||||||
{
|
|
||||||
return new NamingConfig
|
|
||||||
{
|
|
||||||
Id = resource.Id,
|
|
||||||
|
|
||||||
RenameEpisodes = resource.RenameEpisodes,
|
|
||||||
ReplaceIllegalCharacters = resource.ReplaceIllegalCharacters,
|
|
||||||
MultiEpisodeStyle = resource.MultiEpisodeStyle,
|
|
||||||
StandardEpisodeFormat = resource.StandardEpisodeFormat,
|
|
||||||
DailyEpisodeFormat = resource.DailyEpisodeFormat,
|
|
||||||
AnimeEpisodeFormat = resource.AnimeEpisodeFormat,
|
|
||||||
SeriesFolderFormat = resource.SeriesFolderFormat,
|
|
||||||
SeasonFolderFormat = resource.SeasonFolderFormat
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
@@ -26,14 +27,13 @@ namespace NzbDrone.Api.Config
|
|||||||
|
|
||||||
private TResource GetConfig()
|
private TResource GetConfig()
|
||||||
{
|
{
|
||||||
var resource = ToResource(_configService);
|
var resource = new TResource();
|
||||||
|
resource.InjectFrom(_configService);
|
||||||
resource.Id = 1;
|
resource.Id = 1;
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract TResource ToResource(IConfigService model);
|
|
||||||
|
|
||||||
private TResource GetConfig(int id)
|
private TResource GetConfig(int id)
|
||||||
{
|
{
|
||||||
return GetConfig();
|
return GetConfig();
|
||||||
|
|||||||
@@ -1,21 +1,45 @@
|
|||||||
using System;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
public class UiConfigModule : NzbDroneConfigModule<UiConfigResource>
|
public class UiConfigModule : NzbDroneRestModule<UiConfigResource>
|
||||||
{
|
{
|
||||||
public UiConfigModule(IConfigService configService)
|
private readonly IConfigService _configService;
|
||||||
: base(configService)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
public UiConfigModule(IConfigService configService)
|
||||||
|
: base("/config/ui")
|
||||||
|
{
|
||||||
|
_configService = configService;
|
||||||
|
|
||||||
|
GetResourceSingle = GetUiConfig;
|
||||||
|
GetResourceById = GetUiConfig;
|
||||||
|
UpdateResource = SaveUiConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override UiConfigResource ToResource(IConfigService model)
|
private UiConfigResource GetUiConfig()
|
||||||
{
|
{
|
||||||
return UiConfigResourceMapper.ToResource(model);
|
var resource = new UiConfigResource();
|
||||||
|
resource.InjectFrom(_configService);
|
||||||
|
resource.Id = 1;
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UiConfigResource GetUiConfig(int id)
|
||||||
|
{
|
||||||
|
return GetUiConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveUiConfig(UiConfigResource resource)
|
||||||
|
{
|
||||||
|
var dictionary = resource.GetType()
|
||||||
|
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||||
|
.ToDictionary(prop => prop.Name, prop => prop.GetValue(resource, null));
|
||||||
|
|
||||||
|
_configService.SaveConfigDictionary(dictionary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
@@ -18,23 +17,4 @@ namespace NzbDrone.Api.Config
|
|||||||
|
|
||||||
public bool EnableColorImpairedMode { get; set; }
|
public bool EnableColorImpairedMode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UiConfigResourceMapper
|
|
||||||
{
|
|
||||||
public static UiConfigResource ToResource(IConfigService model)
|
|
||||||
{
|
|
||||||
return new UiConfigResource
|
|
||||||
{
|
|
||||||
FirstDayOfWeek = model.FirstDayOfWeek,
|
|
||||||
CalendarWeekColumnHeader = model.CalendarWeekColumnHeader,
|
|
||||||
|
|
||||||
ShortDateFormat = model.ShortDateFormat,
|
|
||||||
LongDateFormat = model.LongDateFormat,
|
|
||||||
TimeFormat = model.TimeFormat,
|
|
||||||
ShowRelativeDates = model.ShowRelativeDates,
|
|
||||||
|
|
||||||
EnableColorImpairedMode = model.EnableColorImpairedMode,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Core.DiskSpace;
|
using NzbDrone.Core.DiskSpace;
|
||||||
|
|
||||||
namespace NzbDrone.Api.DiskSpace
|
namespace NzbDrone.Api.DiskSpace
|
||||||
@@ -9,16 +8,15 @@ namespace NzbDrone.Api.DiskSpace
|
|||||||
private readonly IDiskSpaceService _diskSpaceService;
|
private readonly IDiskSpaceService _diskSpaceService;
|
||||||
|
|
||||||
public DiskSpaceModule(IDiskSpaceService diskSpaceService)
|
public DiskSpaceModule(IDiskSpaceService diskSpaceService)
|
||||||
: base("diskspace")
|
:base("diskspace")
|
||||||
{
|
{
|
||||||
_diskSpaceService = diskSpaceService;
|
_diskSpaceService = diskSpaceService;
|
||||||
GetResourceAll = GetFreeSpace;
|
GetResourceAll = GetFreeSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<DiskSpaceResource> GetFreeSpace()
|
public List<DiskSpaceResource> GetFreeSpace()
|
||||||
{
|
{
|
||||||
return _diskSpaceService.GetFreeSpace().ConvertAll(DiskSpaceResourceMapper.MapToResource);
|
return ToListResource(_diskSpaceService.GetFreeSpace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,20 +10,4 @@ namespace NzbDrone.Api.DiskSpace
|
|||||||
public long FreeSpace { get; set; }
|
public long FreeSpace { get; set; }
|
||||||
public long TotalSpace { get; set; }
|
public long TotalSpace { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DiskSpaceResourceMapper
|
|
||||||
{
|
|
||||||
public static DiskSpaceResource MapToResource(this Core.DiskSpace.DiskSpace model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new DiskSpaceResource
|
|
||||||
{
|
|
||||||
Path = model.Path,
|
|
||||||
Label = model.Label,
|
|
||||||
FreeSpace = model.FreeSpace,
|
|
||||||
TotalSpace = model.TotalSpace
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.DownloadClient
|
namespace NzbDrone.Api.DownloadClient
|
||||||
{
|
{
|
||||||
@@ -10,22 +9,6 @@ namespace NzbDrone.Api.DownloadClient
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void MapToResource(DownloadClientResource resource, DownloadClientDefinition definition)
|
|
||||||
{
|
|
||||||
base.MapToResource(resource, definition);
|
|
||||||
|
|
||||||
resource.Enable = definition.Enable;
|
|
||||||
resource.Protocol = definition.Protocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void MapToModel(DownloadClientDefinition definition, DownloadClientResource resource)
|
|
||||||
{
|
|
||||||
base.MapToModel(definition, resource);
|
|
||||||
|
|
||||||
definition.Enable = resource.Enable;
|
|
||||||
definition.Protocol = resource.Protocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Validate(DownloadClientDefinition definition, bool includeWarnings)
|
protected override void Validate(DownloadClientDefinition definition, bool includeWarnings)
|
||||||
{
|
{
|
||||||
if (!definition.Enable) return;
|
if (!definition.Enable) return;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using NLog;
|
|||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
@@ -13,7 +14,7 @@ using NzbDrone.SignalR;
|
|||||||
|
|
||||||
namespace NzbDrone.Api.EpisodeFiles
|
namespace NzbDrone.Api.EpisodeFiles
|
||||||
{
|
{
|
||||||
public class EpisodeFileModule : NzbDroneRestModuleWithSignalR<EpisodeFileResource, EpisodeFile>,
|
public class EpisodeModule : NzbDroneRestModuleWithSignalR<EpisodeFileResource, EpisodeFile>,
|
||||||
IHandle<EpisodeFileAddedEvent>
|
IHandle<EpisodeFileAddedEvent>
|
||||||
{
|
{
|
||||||
private readonly IMediaFileService _mediaFileService;
|
private readonly IMediaFileService _mediaFileService;
|
||||||
@@ -22,7 +23,7 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public EpisodeFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
public EpisodeModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
IMediaFileService mediaFileService,
|
IMediaFileService mediaFileService,
|
||||||
IRecycleBinProvider recycleBinProvider,
|
IRecycleBinProvider recycleBinProvider,
|
||||||
ISeriesService seriesService,
|
ISeriesService seriesService,
|
||||||
@@ -46,7 +47,7 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
var episodeFile = _mediaFileService.Get(id);
|
var episodeFile = _mediaFileService.Get(id);
|
||||||
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||||
|
|
||||||
return episodeFile.ToResource(series, _qualityUpgradableSpecification);
|
return MapToResource(series, episodeFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<EpisodeFileResource> GetEpisodeFiles()
|
private List<EpisodeFileResource> GetEpisodeFiles()
|
||||||
@@ -60,7 +61,8 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
|
|
||||||
var series = _seriesService.GetSeries(seriesId);
|
var series = _seriesService.GetSeries(seriesId);
|
||||||
|
|
||||||
return _mediaFileService.GetFilesBySeries(seriesId).ConvertAll(f => f.ToResource(series, _qualityUpgradableSpecification));
|
return _mediaFileService.GetFilesBySeries(seriesId)
|
||||||
|
.Select(f => MapToResource(series, f)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetQuality(EpisodeFileResource episodeFileResource)
|
private void SetQuality(EpisodeFileResource episodeFileResource)
|
||||||
@@ -81,6 +83,16 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EpisodeFileResource MapToResource(Core.Tv.Series series, EpisodeFile episodeFile)
|
||||||
|
{
|
||||||
|
var resource = episodeFile.InjectTo<EpisodeFileResource>();
|
||||||
|
resource.Path = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
|
resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(series.Profile.Value, episodeFile.Quality);
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeFileAddedEvent message)
|
public void Handle(EpisodeFileAddedEvent message)
|
||||||
{
|
{
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
@@ -18,47 +17,4 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
|
|
||||||
public bool QualityCutoffNotMet { get; set; }
|
public bool QualityCutoffNotMet { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EpisodeFileResourceMapper
|
|
||||||
{
|
|
||||||
private static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new EpisodeFileResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
RelativePath = model.RelativePath,
|
|
||||||
//Path
|
|
||||||
Size = model.Size,
|
|
||||||
DateAdded = model.DateAdded,
|
|
||||||
SceneName = model.SceneName,
|
|
||||||
Quality = model.Quality,
|
|
||||||
//QualityCutoffNotMet
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model, Core.Tv.Series series, Core.DecisionEngine.IQualityUpgradableSpecification qualityUpgradableSpecification)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new EpisodeFileResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
RelativePath = model.RelativePath,
|
|
||||||
Path = Path.Combine(series.Path, model.RelativePath),
|
|
||||||
Size = model.Size,
|
|
||||||
DateAdded = model.DateAdded,
|
|
||||||
SceneName = model.SceneName,
|
|
||||||
Quality = model.Quality,
|
|
||||||
QualityCutoffNotMet = qualityUpgradableSpecification.CutoffNotMet(series.Profile.Value, model.Quality)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace NzbDrone.Api.Episodes
|
|||||||
|
|
||||||
var seriesId = (int)Request.Query.SeriesId;
|
var seriesId = (int)Request.Query.SeriesId;
|
||||||
|
|
||||||
var resources = MapToResource(_episodeService.GetEpisodeBySeries(seriesId), false, true);
|
var resources = ToListResource(_episodeService.GetEpisodeBySeries(seriesId));
|
||||||
|
|
||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
@@ -36,5 +36,10 @@ namespace NzbDrone.Api.Episodes
|
|||||||
{
|
{
|
||||||
_episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored);
|
_episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override List<EpisodeResource> LoadSeries(List<EpisodeResource> resources)
|
||||||
|
{
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Api.EpisodeFiles;
|
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Api.Series;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
@@ -54,65 +53,41 @@ namespace NzbDrone.Api.Episodes
|
|||||||
protected EpisodeResource GetEpisode(int id)
|
protected EpisodeResource GetEpisode(int id)
|
||||||
{
|
{
|
||||||
var episode = _episodeService.GetEpisode(id);
|
var episode = _episodeService.GetEpisode(id);
|
||||||
var resource = MapToResource(episode, true, true);
|
episode.EpisodeFile.LazyLoad();
|
||||||
return resource;
|
episode.Series = _seriesService.GetSeries(episode.SeriesId);
|
||||||
|
return ToResource(episode);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EpisodeResource MapToResource(Episode episode, bool includeSeries, bool includeEpisodeFile)
|
protected override EpisodeResource ToResource<TModel>(TModel model)
|
||||||
{
|
{
|
||||||
var resource = episode.ToResource();
|
var resource = base.ToResource(model);
|
||||||
|
|
||||||
if (includeSeries || includeEpisodeFile)
|
var episode = model as Episode;
|
||||||
|
if (episode != null)
|
||||||
{
|
{
|
||||||
var series = episode.Series ?? _seriesService.GetSeries(episode.SeriesId);
|
if (episode.EpisodeFile.IsLoaded && episode.EpisodeFile.Value != null)
|
||||||
|
|
||||||
if (includeSeries)
|
|
||||||
{
|
{
|
||||||
resource.Series = series.ToResource();
|
resource.EpisodeFile.Path = Path.Combine(episode.Series.Path, episode.EpisodeFile.Value.RelativePath);
|
||||||
}
|
resource.EpisodeFile.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(episode.Series.Profile.Value, episode.EpisodeFile.Value.Quality);
|
||||||
if (includeEpisodeFile && episode.EpisodeFileId != 0)
|
|
||||||
{
|
|
||||||
resource.EpisodeFile = episode.EpisodeFile.Value.ToResource(series, _qualityUpgradableSpecification);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<EpisodeResource> MapToResource(List<Episode> episodes, bool includeSeries, bool includeEpisodeFile)
|
protected override List<EpisodeResource> ToListResource<TModel>(IEnumerable<TModel> modelList)
|
||||||
{
|
{
|
||||||
var result = episodes.ToResource();
|
var resources = base.ToListResource(modelList);
|
||||||
|
|
||||||
if (includeSeries || includeEpisodeFile)
|
return LoadSeries(resources);
|
||||||
{
|
|
||||||
var seriesDict = new Dictionary<int, Core.Tv.Series>();
|
|
||||||
for (var i = 0; i < episodes.Count; i++)
|
|
||||||
{
|
|
||||||
var episode = episodes[i];
|
|
||||||
var resource = result[i];
|
|
||||||
|
|
||||||
var series = episode.Series ?? seriesDict.GetValueOrDefault(episodes[i].SeriesId) ?? _seriesService.GetSeries(episodes[i].SeriesId);
|
|
||||||
seriesDict[series.Id] = series;
|
|
||||||
|
|
||||||
if (includeSeries)
|
|
||||||
{
|
|
||||||
resource.Series = series.ToResource();
|
|
||||||
}
|
|
||||||
if (includeEpisodeFile && episodes[i].EpisodeFileId != 0)
|
|
||||||
{
|
|
||||||
resource.EpisodeFile = episodes[i].EpisodeFile.Value.ToResource(series, _qualityUpgradableSpecification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeGrabbedEvent message)
|
public void Handle(EpisodeGrabbedEvent message)
|
||||||
{
|
{
|
||||||
foreach (var episode in message.Episode.Episodes)
|
foreach (var episode in message.Episode.Episodes)
|
||||||
{
|
{
|
||||||
var resource = episode.ToResource();
|
var resource = episode.InjectTo<EpisodeResource>();
|
||||||
resource.Grabbed = true;
|
resource.Grabbed = true;
|
||||||
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||||
@@ -126,5 +101,10 @@ namespace NzbDrone.Api.Episodes
|
|||||||
BroadcastResourceChange(ModelAction.Updated, episode.Id);
|
BroadcastResourceChange(ModelAction.Updated, episode.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual List<EpisodeResource> LoadSeries(List<EpisodeResource> resources)
|
||||||
|
{
|
||||||
|
return resources.LoadSubtype<EpisodeResource, SeriesResource, Core.Tv.Series>(e => e.SeriesId, _seriesService.GetSeries).ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NzbDrone.Api.EpisodeFiles;
|
using NzbDrone.Api.EpisodeFiles;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Api.Series;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Episodes
|
namespace NzbDrone.Api.Episodes
|
||||||
{
|
{
|
||||||
@@ -28,6 +25,8 @@ namespace NzbDrone.Api.Episodes
|
|||||||
public int? SceneEpisodeNumber { get; set; }
|
public int? SceneEpisodeNumber { get; set; }
|
||||||
public int? SceneSeasonNumber { get; set; }
|
public int? SceneSeasonNumber { get; set; }
|
||||||
public bool UnverifiedSceneNumbering { get; set; }
|
public bool UnverifiedSceneNumbering { get; set; }
|
||||||
|
public DateTime? EndTime { get; set; }
|
||||||
|
public DateTime? GrabDate { get; set; }
|
||||||
public string SeriesTitle { get; set; }
|
public string SeriesTitle { get; set; }
|
||||||
public SeriesResource Series { get; set; }
|
public SeriesResource Series { get; set; }
|
||||||
|
|
||||||
@@ -35,44 +34,4 @@ namespace NzbDrone.Api.Episodes
|
|||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||||
public bool Grabbed { get; set; }
|
public bool Grabbed { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EpisodeResourceMapper
|
|
||||||
{
|
|
||||||
public static EpisodeResource ToResource(this Episode model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new EpisodeResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
EpisodeFileId = model.EpisodeFileId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
EpisodeNumber = model.EpisodeNumber,
|
|
||||||
Title = model.Title,
|
|
||||||
AirDate = model.AirDate,
|
|
||||||
AirDateUtc = model.AirDateUtc,
|
|
||||||
Overview = model.Overview,
|
|
||||||
//EpisodeFile
|
|
||||||
|
|
||||||
HasFile = model.HasFile,
|
|
||||||
Monitored = model.Monitored,
|
|
||||||
AbsoluteEpisodeNumber = model.AbsoluteEpisodeNumber,
|
|
||||||
SceneAbsoluteEpisodeNumber = model.SceneAbsoluteEpisodeNumber,
|
|
||||||
SceneEpisodeNumber = model.SceneEpisodeNumber,
|
|
||||||
SceneSeasonNumber = model.SceneSeasonNumber,
|
|
||||||
UnverifiedSceneNumbering = model.UnverifiedSceneNumbering,
|
|
||||||
SeriesTitle = model.SeriesTitle,
|
|
||||||
//Series = model.Series.MapToResource(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<EpisodeResource> ToResource(this IEnumerable<Episode> models)
|
|
||||||
{
|
|
||||||
if (models == null) return null;
|
|
||||||
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ namespace NzbDrone.Api.Episodes
|
|||||||
if (Request.Query.SeasonNumber.HasValue)
|
if (Request.Query.SeasonNumber.HasValue)
|
||||||
{
|
{
|
||||||
var seasonNumber = (int)Request.Query.SeasonNumber;
|
var seasonNumber = (int)Request.Query.SeasonNumber;
|
||||||
return _renameEpisodeFileService.GetRenamePreviews(seriesId, seasonNumber).ToResource();
|
return ToListResource(() => _renameEpisodeFileService.GetRenamePreviews(seriesId, seasonNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _renameEpisodeFileService.GetRenamePreviews(seriesId).ToResource();
|
return ToListResource(() => _renameEpisodeFileService.GetRenamePreviews(seriesId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Episodes
|
namespace NzbDrone.Api.Episodes
|
||||||
@@ -14,27 +13,4 @@ namespace NzbDrone.Api.Episodes
|
|||||||
public string ExistingPath { get; set; }
|
public string ExistingPath { get; set; }
|
||||||
public string NewPath { get; set; }
|
public string NewPath { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RenameEpisodeResourceMapper
|
|
||||||
{
|
|
||||||
public static RenameEpisodeResource ToResource(this Core.MediaFiles.RenameEpisodeFilePreview model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new RenameEpisodeResource
|
|
||||||
{
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
EpisodeNumbers = model.EpisodeNumbers.ToList(),
|
|
||||||
EpisodeFileId = model.EpisodeFileId,
|
|
||||||
ExistingPath = model.ExistingPath,
|
|
||||||
NewPath = model.NewPath
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<RenameEpisodeResource> ToResource(this IEnumerable<Core.MediaFiles.RenameEpisodeFilePreview> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace NzbDrone.Api.ErrorManagement
|
|||||||
|
|
||||||
if (apiException != null)
|
if (apiException != null)
|
||||||
{
|
{
|
||||||
_logger.Warn(apiException, "API Error");
|
_logger.WarnException("API Error", apiException);
|
||||||
return apiException.ToErrorResponse();
|
return apiException.ToErrorResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,10 +65,10 @@ namespace NzbDrone.Api.ErrorManagement
|
|||||||
|
|
||||||
var sqlErrorMessage = string.Format("[{0} {1}]", context.Request.Method, context.Request.Path);
|
var sqlErrorMessage = string.Format("[{0} {1}]", context.Request.Method, context.Request.Path);
|
||||||
|
|
||||||
_logger.Error(sqLiteException, sqlErrorMessage);
|
_logger.ErrorException(sqlErrorMessage, sqLiteException);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Fatal(exception, "Request Failed");
|
_logger.FatalException("Request Failed", exception);
|
||||||
|
|
||||||
return new ErrorModel
|
return new ErrorModel
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Extensions
|
||||||
|
{
|
||||||
|
public static class LazyExtensions
|
||||||
|
{
|
||||||
|
private static readonly ICached<MethodInfo> SetterCache = new Cached<MethodInfo>();
|
||||||
|
|
||||||
|
public static IEnumerable<TParent> LoadSubtype<TParent, TChild, TSourceChild>(this IEnumerable<TParent> parents, Func<TParent, int> foreignKeySelector, Func<IEnumerable<int>, IEnumerable<TSourceChild>> sourceChildSelector)
|
||||||
|
where TSourceChild : ModelBase, new()
|
||||||
|
where TChild : RestResource, new()
|
||||||
|
where TParent : RestResource
|
||||||
|
{
|
||||||
|
var parentList = parents.Where(p => foreignKeySelector(p) != 0).ToList();
|
||||||
|
|
||||||
|
if (!parentList.Any())
|
||||||
|
{
|
||||||
|
return parents;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids = parentList.Select(foreignKeySelector).Distinct();
|
||||||
|
var childDictionary = sourceChildSelector(ids).ToDictionary(child => child.Id, child => child);
|
||||||
|
|
||||||
|
var childSetter = GetChildSetter<TParent, TChild>();
|
||||||
|
|
||||||
|
foreach (var episode in parentList)
|
||||||
|
{
|
||||||
|
childSetter.Invoke(episode, new object[] { childDictionary[foreignKeySelector(episode)].InjectTo<TChild>() });
|
||||||
|
}
|
||||||
|
|
||||||
|
return parents;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static MethodInfo GetChildSetter<TParent, TChild>()
|
||||||
|
where TChild : RestResource
|
||||||
|
where TParent : RestResource
|
||||||
|
{
|
||||||
|
var key = typeof(TChild).FullName + typeof(TParent).FullName;
|
||||||
|
|
||||||
|
return SetterCache.Get(key, () =>
|
||||||
|
{
|
||||||
|
var property = typeof(TParent).GetProperties().Single(c => c.PropertyType == typeof(TChild));
|
||||||
|
return property.GetSetMethod();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,8 +14,6 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
_cacheableSpecification = cacheableSpecification;
|
_cacheableSpecification = cacheableSpecification;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order { get { return 0; } }
|
|
||||||
|
|
||||||
public void Register(IPipelines pipelines)
|
public void Register(IPipelines pipelines)
|
||||||
{
|
{
|
||||||
pipelines.AfterRequest.AddItemToStartOfPipeline((Action<NancyContext>) Handle);
|
pipelines.AfterRequest.AddItemToStartOfPipeline((Action<NancyContext>) Handle);
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
{
|
{
|
||||||
public class CorsPipeline : IRegisterNancyPipeline
|
public class CorsPipeline : IRegisterNancyPipeline
|
||||||
{
|
{
|
||||||
public int Order { get { return 0; } }
|
|
||||||
|
|
||||||
public void Register(IPipelines pipelines)
|
public void Register(IPipelines pipelines)
|
||||||
{
|
{
|
||||||
pipelines.AfterRequest.AddItemToEndOfPipeline((Action<NancyContext>) Handle);
|
pipelines.AfterRequest.AddItemToEndOfPipeline((Action<NancyContext>) Handle);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using System.Linq;
|
|||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.Bootstrapper;
|
using Nancy.Bootstrapper;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Extensions.Pipelines
|
namespace NzbDrone.Api.Extensions.Pipelines
|
||||||
{
|
{
|
||||||
@@ -13,8 +12,6 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public int Order { get { return 0; } }
|
|
||||||
|
|
||||||
public GzipCompressionPipeline(Logger logger)
|
public GzipCompressionPipeline(Logger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@@ -22,62 +19,50 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
|
|
||||||
public void Register(IPipelines pipelines)
|
public void Register(IPipelines pipelines)
|
||||||
{
|
{
|
||||||
pipelines.AfterRequest.AddItemToEndOfPipeline(CompressResponse);
|
pipelines.AfterRequest.AddItemToEndOfPipeline(c => CompressResponse(c.Request, c.Response));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CompressResponse(NancyContext context)
|
private Response CompressResponse(Request request, Response response)
|
||||||
{
|
{
|
||||||
var request = context.Request;
|
|
||||||
var response = context.Response;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
!response.ContentType.Contains("image")
|
!response.ContentType.Contains("image")
|
||||||
&& !response.ContentType.Contains("font")
|
&& !response.ContentType.Contains("font")
|
||||||
&& request.Headers.AcceptEncoding.Any(x => x.Contains("gzip"))
|
&& request.Headers.AcceptEncoding.Any(x => x.Contains("gzip"))
|
||||||
&& !AlreadyGzipEncoded(response)
|
&& (!response.Headers.ContainsKey("Content-Encoding") || response.Headers["Content-Encoding"] != "gzip"))
|
||||||
&& !ContentLengthIsTooSmall(response))
|
|
||||||
{
|
{
|
||||||
var contents = response.Contents;
|
var data = new MemoryStream();
|
||||||
|
response.Contents.Invoke(data);
|
||||||
response.Headers["Content-Encoding"] = "gzip";
|
data.Position = 0;
|
||||||
response.Contents = responseStream =>
|
if (data.Length < 1024)
|
||||||
{
|
{
|
||||||
using (var gzip = new GZipStream(responseStream, CompressionMode.Compress, true))
|
response.Contents = stream =>
|
||||||
using (var buffered = new BufferedStream(gzip, 8192))
|
|
||||||
{
|
{
|
||||||
contents.Invoke(buffered);
|
data.CopyTo(stream);
|
||||||
}
|
stream.Flush();
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.Headers["Content-Encoding"] = "gzip";
|
||||||
|
response.Contents = s =>
|
||||||
|
{
|
||||||
|
var gzip = new GZipStream(s, CompressionMode.Compress, true);
|
||||||
|
data.CopyTo(gzip);
|
||||||
|
gzip.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Unable to gzip response");
|
_logger.ErrorException("Unable to gzip response", ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ContentLengthIsTooSmall(Response response)
|
|
||||||
{
|
|
||||||
var contentLength = response.Headers.GetValueOrDefault("Content-Length");
|
|
||||||
if (contentLength != null && long.Parse(contentLength) < 1024)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool AlreadyGzipEncoded(Response response)
|
|
||||||
{
|
|
||||||
var contentEncoding = response.Headers.GetValueOrDefault("Content-Encoding");
|
|
||||||
if (contentEncoding == "gzip")
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,8 +4,6 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
{
|
{
|
||||||
public interface IRegisterNancyPipeline
|
public interface IRegisterNancyPipeline
|
||||||
{
|
{
|
||||||
int Order { get; }
|
|
||||||
|
|
||||||
void Register(IPipelines pipelines);
|
void Register(IPipelines pipelines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,8 +14,6 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
_cacheableSpecification = cacheableSpecification;
|
_cacheableSpecification = cacheableSpecification;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order { get { return 0; } }
|
|
||||||
|
|
||||||
public void Register(IPipelines pipelines)
|
public void Register(IPipelines pipelines)
|
||||||
{
|
{
|
||||||
pipelines.BeforeRequest.AddItemToStartOfPipeline((Func<NancyContext, Response>) Handle);
|
pipelines.BeforeRequest.AddItemToStartOfPipeline((Func<NancyContext, Response>) Handle);
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
{
|
{
|
||||||
public class NzbDroneVersionPipeline : IRegisterNancyPipeline
|
public class NzbDroneVersionPipeline : IRegisterNancyPipeline
|
||||||
{
|
{
|
||||||
public int Order { get { return 0; } }
|
|
||||||
|
|
||||||
public void Register(IPipelines pipelines)
|
public void Register(IPipelines pipelines)
|
||||||
{
|
{
|
||||||
pipelines.AfterRequest.AddItemToStartOfPipeline((Action<NancyContext>) Handle);
|
pipelines.AfterRequest.AddItemToStartOfPipeline((Action<NancyContext>) Handle);
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using Nancy;
|
|
||||||
using Nancy.Bootstrapper;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Api.ErrorManagement;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Extensions.Pipelines
|
|
||||||
{
|
|
||||||
public class RequestLoggingPipeline : IRegisterNancyPipeline
|
|
||||||
{
|
|
||||||
private static readonly Logger _loggerHttp = LogManager.GetLogger("Http");
|
|
||||||
private static readonly Logger _loggerApi = LogManager.GetLogger("Api");
|
|
||||||
|
|
||||||
private static int _requestSequenceID;
|
|
||||||
|
|
||||||
private readonly NzbDroneErrorPipeline _errorPipeline;
|
|
||||||
|
|
||||||
public RequestLoggingPipeline(NzbDroneErrorPipeline errorPipeline)
|
|
||||||
{
|
|
||||||
_errorPipeline = errorPipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Order { get { return 100; } }
|
|
||||||
|
|
||||||
public void Register(IPipelines pipelines)
|
|
||||||
{
|
|
||||||
pipelines.BeforeRequest.AddItemToStartOfPipeline(LogStart);
|
|
||||||
pipelines.AfterRequest.AddItemToEndOfPipeline(LogEnd);
|
|
||||||
pipelines.OnError.AddItemToEndOfPipeline(LogError);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response LogStart(NancyContext context)
|
|
||||||
{
|
|
||||||
var id = Interlocked.Increment(ref _requestSequenceID);
|
|
||||||
|
|
||||||
context.Items["ApiRequestSequenceID"] = id;
|
|
||||||
context.Items["ApiRequestStartTime"] = DateTime.UtcNow;
|
|
||||||
|
|
||||||
var reqPath = GetRequestPathAndQuery(context.Request);
|
|
||||||
|
|
||||||
_loggerHttp.Trace("Req: {0} [{1}] {2}", id, context.Request.Method, reqPath);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogEnd(NancyContext context)
|
|
||||||
{
|
|
||||||
var id = (int)context.Items["ApiRequestSequenceID"];
|
|
||||||
var startTime = (DateTime)context.Items["ApiRequestStartTime"];
|
|
||||||
|
|
||||||
var endTime = DateTime.UtcNow;
|
|
||||||
var duration = endTime - startTime;
|
|
||||||
|
|
||||||
var reqPath = GetRequestPathAndQuery(context.Request);
|
|
||||||
|
|
||||||
_loggerHttp.Trace("Res: {0} [{1}] {2}: {3}.{4} ({5} ms)", id, context.Request.Method, reqPath, (int)context.Response.StatusCode, context.Response.StatusCode, (int)duration.TotalMilliseconds);
|
|
||||||
|
|
||||||
if (context.Request.IsApiRequest())
|
|
||||||
{
|
|
||||||
_loggerApi.Debug("[{0}] {1}: {2}.{3} ({4} ms)", context.Request.Method, reqPath, (int)context.Response.StatusCode, context.Response.StatusCode, (int)duration.TotalMilliseconds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response LogError(NancyContext context, Exception exception)
|
|
||||||
{
|
|
||||||
var response = _errorPipeline.HandleException(context, exception);
|
|
||||||
|
|
||||||
context.Response = response;
|
|
||||||
|
|
||||||
LogEnd(context);
|
|
||||||
|
|
||||||
context.Response = null;
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetRequestPathAndQuery(Request request)
|
|
||||||
{
|
|
||||||
if (request.Url.Query.IsNotNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
return string.Concat(request.Url.Path, "?", request.Url.Query);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return request.Url.Path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,7 @@ namespace NzbDrone.Api.Health
|
|||||||
|
|
||||||
private List<HealthResource> GetHealth()
|
private List<HealthResource> GetHealth()
|
||||||
{
|
{
|
||||||
return _healthCheckService.Results().ToResource();
|
return ToListResource(_healthCheckService.Results);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(HealthCheckCompleteEvent message)
|
public void Handle(HealthCheckCompleteEvent message)
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.HealthCheck;
|
using NzbDrone.Core.HealthCheck;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Health
|
namespace NzbDrone.Api.Health
|
||||||
@@ -11,28 +8,6 @@ namespace NzbDrone.Api.Health
|
|||||||
{
|
{
|
||||||
public HealthCheckResult Type { get; set; }
|
public HealthCheckResult Type { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public HttpUri WikiUrl { get; set; }
|
public Uri WikiUrl { get; set; }
|
||||||
}
|
|
||||||
|
|
||||||
public static class HealthResourceMapper
|
|
||||||
{
|
|
||||||
public static HealthResource ToResource(this HealthCheck model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new HealthResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
Type = model.Type,
|
|
||||||
Message = model.Message,
|
|
||||||
WikiUrl = model.WikiUrl
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<HealthResource> ToResource(this IEnumerable<HealthCheck> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.Episodes;
|
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
@@ -28,16 +26,15 @@ namespace NzbDrone.Api.History
|
|||||||
Post["/failed"] = x => MarkAsFailed();
|
Post["/failed"] = x => MarkAsFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HistoryResource MapToResource(Core.History.History model)
|
protected override HistoryResource ToResource<TModel>(TModel model)
|
||||||
{
|
{
|
||||||
var resource = model.ToResource();
|
var resource = base.ToResource(model);
|
||||||
|
|
||||||
resource.Series = model.Series.ToResource();
|
var history = model as Core.History.History;
|
||||||
resource.Episode = model.Episode.ToResource();
|
|
||||||
|
|
||||||
if (model.Series != null)
|
if (history != null && history.Series != null)
|
||||||
{
|
{
|
||||||
resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(model.Series.Profile.Value, model.Quality);
|
resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(history.Series.Profile.Value, history.Quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
@@ -47,7 +44,13 @@ namespace NzbDrone.Api.History
|
|||||||
{
|
{
|
||||||
var episodeId = Request.Query.EpisodeId;
|
var episodeId = Request.Query.EpisodeId;
|
||||||
|
|
||||||
var pagingSpec = pagingResource.MapToPagingSpec<HistoryResource, Core.History.History>("date", SortDirection.Descending);
|
var pagingSpec = new PagingSpec<Core.History.History>
|
||||||
|
{
|
||||||
|
Page = pagingResource.Page,
|
||||||
|
PageSize = pagingResource.PageSize,
|
||||||
|
SortKey = pagingResource.SortKey,
|
||||||
|
SortDirection = pagingResource.SortDirection
|
||||||
|
};
|
||||||
|
|
||||||
if (pagingResource.FilterKey == "eventType")
|
if (pagingResource.FilterKey == "eventType")
|
||||||
{
|
{
|
||||||
@@ -61,7 +64,7 @@ namespace NzbDrone.Api.History
|
|||||||
pagingSpec.FilterExpression = h => h.EpisodeId == i;
|
pagingSpec.FilterExpression = h => h.EpisodeId == i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ApplyToPage(_historyService.Paged, pagingSpec, MapToResource);
|
return ApplyToPage(_historyService.Paged, pagingSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response MarkAsFailed()
|
private Response MarkAsFailed()
|
||||||
@@ -71,4 +74,4 @@ namespace NzbDrone.Api.History
|
|||||||
return new object().AsResponse();
|
return new object().AsResponse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,8 @@ namespace NzbDrone.Api.History
|
|||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public bool QualityCutoffNotMet { get; set; }
|
public bool QualityCutoffNotMet { get; set; }
|
||||||
public DateTime Date { get; set; }
|
public DateTime Date { get; set; }
|
||||||
|
public string Indexer { get; set; }
|
||||||
|
public string ReleaseGroup { get; set; }
|
||||||
public string DownloadId { get; set; }
|
public string DownloadId { get; set; }
|
||||||
|
|
||||||
public HistoryEventType EventType { get; set; }
|
public HistoryEventType EventType { get; set; }
|
||||||
@@ -26,31 +28,4 @@ namespace NzbDrone.Api.History
|
|||||||
public EpisodeResource Episode { get; set; }
|
public EpisodeResource Episode { get; set; }
|
||||||
public SeriesResource Series { get; set; }
|
public SeriesResource Series { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class HistoryResourceMapper
|
|
||||||
{
|
|
||||||
public static HistoryResource ToResource(this Core.History.History model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new HistoryResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
EpisodeId = model.EpisodeId,
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
SourceTitle = model.SourceTitle,
|
|
||||||
Quality = model.Quality,
|
|
||||||
//QualityCutoffNotMet
|
|
||||||
Date = model.Date,
|
|
||||||
DownloadId = model.DownloadId,
|
|
||||||
|
|
||||||
EventType = model.EventType,
|
|
||||||
|
|
||||||
Data = model.Data
|
|
||||||
//Episode
|
|
||||||
//Series
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
@@ -10,25 +9,6 @@ namespace NzbDrone.Api.Indexers
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void MapToResource(IndexerResource resource, IndexerDefinition definition)
|
|
||||||
{
|
|
||||||
base.MapToResource(resource, definition);
|
|
||||||
|
|
||||||
resource.EnableRss = definition.EnableRss;
|
|
||||||
resource.EnableSearch = definition.EnableSearch;
|
|
||||||
resource.SupportsRss = definition.SupportsRss;
|
|
||||||
resource.SupportsSearch = definition.SupportsSearch;
|
|
||||||
resource.Protocol = definition.Protocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void MapToModel(IndexerDefinition definition, IndexerResource resource)
|
|
||||||
{
|
|
||||||
base.MapToModel(definition, resource);
|
|
||||||
|
|
||||||
definition.EnableRss = resource.EnableRss;
|
|
||||||
definition.EnableSearch = resource.EnableSearch;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Validate(IndexerDefinition definition, bool includeWarnings)
|
protected override void Validate(IndexerDefinition definition, bool includeWarnings)
|
||||||
{
|
{
|
||||||
if (!definition.Enable) return;
|
if (!definition.Enable) return;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace NzbDrone.Api.Indexers
|
|||||||
}
|
}
|
||||||
catch (ReleaseDownloadException ex)
|
catch (ReleaseDownloadException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.ErrorException(ex.Message, ex);
|
||||||
throw new NzbDroneClientException(HttpStatusCode.Conflict, "Getting release from indexer failed");
|
throw new NzbDroneClientException(HttpStatusCode.Conflict, "Getting release from indexer failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,14 +89,14 @@ namespace NzbDrone.Api.Indexers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var decisions = _nzbSearchService.EpisodeSearch(episodeId, true);
|
var decisions = _nzbSearchService.EpisodeSearch(episodeId);
|
||||||
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions);
|
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions);
|
||||||
|
|
||||||
return MapDecisions(prioritizedDecisions);
|
return MapDecisions(prioritizedDecisions);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Episode search failed: " + ex.Message);
|
_logger.ErrorException("Episode search failed: " + ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<ReleaseResource>();
|
return new List<ReleaseResource>();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
@@ -24,20 +25,42 @@ namespace NzbDrone.Api.Indexers
|
|||||||
|
|
||||||
protected virtual ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
|
protected virtual ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
|
||||||
{
|
{
|
||||||
var release = decision.ToResource();
|
var release = new ReleaseResource();
|
||||||
|
|
||||||
|
release.InjectFrom(decision.RemoteEpisode.Release);
|
||||||
|
release.InjectFrom(decision.RemoteEpisode.ParsedEpisodeInfo);
|
||||||
|
release.InjectFrom(decision);
|
||||||
|
release.Rejections = decision.Rejections.Select(r => r.Reason).ToList();
|
||||||
|
release.DownloadAllowed = decision.RemoteEpisode.DownloadAllowed;
|
||||||
release.ReleaseWeight = initialWeight;
|
release.ReleaseWeight = initialWeight;
|
||||||
|
|
||||||
if (decision.RemoteEpisode.Series != null)
|
if (decision.RemoteEpisode.Series != null)
|
||||||
{
|
{
|
||||||
release.QualityWeight = decision.RemoteEpisode.Series
|
release.QualityWeight = decision.RemoteEpisode
|
||||||
.Profile.Value
|
.Series
|
||||||
.Items.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
|
.Profile
|
||||||
|
.Value
|
||||||
|
.Items
|
||||||
|
.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
release.QualityWeight += release.Quality.Revision.Real * 10;
|
release.QualityWeight += release.Quality.Revision.Real * 10;
|
||||||
release.QualityWeight += release.Quality.Revision.Version;
|
release.QualityWeight += release.Quality.Revision.Version;
|
||||||
|
|
||||||
|
var torrentRelease = decision.RemoteEpisode.Release as TorrentInfo;
|
||||||
|
|
||||||
|
if (torrentRelease != null)
|
||||||
|
{
|
||||||
|
release.Protocol = DownloadProtocol.Torrent;
|
||||||
|
release.Seeders = torrentRelease.Seeders;
|
||||||
|
//TODO: move this up the chains
|
||||||
|
release.Leechers = torrentRelease.Peers - torrentRelease.Seeders;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
release.Protocol = DownloadProtocol.Usenet;
|
||||||
|
}
|
||||||
|
|
||||||
return release;
|
return release;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ using NzbDrone.Core.Download;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
@@ -30,7 +30,7 @@ namespace NzbDrone.Api.Indexers
|
|||||||
|
|
||||||
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
||||||
PostValidator.RuleFor(s => s.DownloadUrl).NotEmpty();
|
PostValidator.RuleFor(s => s.DownloadUrl).NotEmpty();
|
||||||
PostValidator.RuleFor(s => s.Protocol).NotEmpty();
|
PostValidator.RuleFor(s => s.DownloadProtocol).NotEmpty();
|
||||||
PostValidator.RuleFor(s => s.PublishDate).NotEmpty();
|
PostValidator.RuleFor(s => s.PublishDate).NotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,12 +38,11 @@ namespace NzbDrone.Api.Indexers
|
|||||||
{
|
{
|
||||||
_logger.Info("Release pushed: {0} - {1}", release.Title, release.DownloadUrl);
|
_logger.Info("Release pushed: {0} - {1}", release.Title, release.DownloadUrl);
|
||||||
|
|
||||||
var info = release.ToModel();
|
var info = release.InjectTo<ReleaseInfo>();
|
||||||
|
|
||||||
info.Guid = "PUSH-" + info.DownloadUrl;
|
info.Guid = "PUSH-" + info.DownloadUrl;
|
||||||
|
|
||||||
var decisions = _downloadDecisionMaker.GetRssDecision(new List<ReleaseInfo> { info });
|
var decisions = _downloadDecisionMaker.GetRssDecision(new List<ReleaseInfo> { info });
|
||||||
_downloadDecisionProcessor.ProcessDecisions(decisions);
|
var processed = _downloadDecisionProcessor.ProcessDecisions(decisions);
|
||||||
|
|
||||||
return MapDecisions(decisions).First().AsResponse();
|
return MapDecisions(decisions).First().AsResponse();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
@@ -23,9 +19,11 @@ namespace NzbDrone.Api.Indexers
|
|||||||
public int IndexerId { get; set; }
|
public int IndexerId { get; set; }
|
||||||
public string Indexer { get; set; }
|
public string Indexer { get; set; }
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
|
public string SubGroup { get; set; }
|
||||||
public string ReleaseHash { get; set; }
|
public string ReleaseHash { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public bool FullSeason { get; set; }
|
public bool FullSeason { get; set; }
|
||||||
|
public bool SceneSource { get; set; }
|
||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
public Language Language { get; set; }
|
public Language Language { get; set; }
|
||||||
public string AirDate { get; set; }
|
public string AirDate { get; set; }
|
||||||
@@ -46,129 +44,16 @@ namespace NzbDrone.Api.Indexers
|
|||||||
public int ReleaseWeight { get; set; }
|
public int ReleaseWeight { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string MagnetUrl { get; set; }
|
|
||||||
public string InfoHash { get; set; }
|
|
||||||
public int? Seeders { get; set; }
|
public int? Seeders { get; set; }
|
||||||
public int? Leechers { get; set; }
|
public int? Leechers { get; set; }
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
|
|
||||||
|
//TODO: besides a test I don't think this is used...
|
||||||
// TODO: Remove in v3
|
public DownloadProtocol DownloadProtocol { get; set; }
|
||||||
// Used to support the original Release Push implementation
|
|
||||||
// JsonIgnore so we don't serialize it, but can still parse it
|
|
||||||
[JsonIgnore]
|
|
||||||
public DownloadProtocol DownloadProtocol
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Protocol;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value > 0 && Protocol == 0)
|
|
||||||
{
|
|
||||||
Protocol = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsDaily { get; set; }
|
public bool IsDaily { get; set; }
|
||||||
public bool IsAbsoluteNumbering { get; set; }
|
public bool IsAbsoluteNumbering { get; set; }
|
||||||
public bool IsPossibleSpecialEpisode { get; set; }
|
public bool IsPossibleSpecialEpisode { get; set; }
|
||||||
public bool Special { get; set; }
|
public bool Special { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ReleaseResourceMapper
|
|
||||||
{
|
|
||||||
public static ReleaseResource ToResource(this DownloadDecision model)
|
|
||||||
{
|
|
||||||
var releaseInfo = model.RemoteEpisode.Release;
|
|
||||||
var parsedEpisodeInfo = model.RemoteEpisode.ParsedEpisodeInfo;
|
|
||||||
var remoteEpisode = model.RemoteEpisode;
|
|
||||||
var torrentInfo = (model.RemoteEpisode.Release as TorrentInfo) ?? new TorrentInfo();
|
|
||||||
|
|
||||||
// TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
|
|
||||||
return new ReleaseResource
|
|
||||||
{
|
|
||||||
Guid = releaseInfo.Guid,
|
|
||||||
Quality = parsedEpisodeInfo.Quality,
|
|
||||||
//QualityWeight
|
|
||||||
Age = releaseInfo.Age,
|
|
||||||
AgeHours = releaseInfo.AgeHours,
|
|
||||||
AgeMinutes = releaseInfo.AgeMinutes,
|
|
||||||
Size = releaseInfo.Size,
|
|
||||||
IndexerId = releaseInfo.IndexerId,
|
|
||||||
Indexer = releaseInfo.Indexer,
|
|
||||||
ReleaseGroup = parsedEpisodeInfo.ReleaseGroup,
|
|
||||||
ReleaseHash = parsedEpisodeInfo.ReleaseHash,
|
|
||||||
Title = releaseInfo.Title,
|
|
||||||
FullSeason = parsedEpisodeInfo.FullSeason,
|
|
||||||
SeasonNumber = parsedEpisodeInfo.SeasonNumber,
|
|
||||||
Language = parsedEpisodeInfo.Language,
|
|
||||||
AirDate = parsedEpisodeInfo.AirDate,
|
|
||||||
SeriesTitle = parsedEpisodeInfo.SeriesTitle,
|
|
||||||
EpisodeNumbers = parsedEpisodeInfo.EpisodeNumbers,
|
|
||||||
AbsoluteEpisodeNumbers = parsedEpisodeInfo.AbsoluteEpisodeNumbers,
|
|
||||||
Approved = model.Approved,
|
|
||||||
TemporarilyRejected = model.TemporarilyRejected,
|
|
||||||
Rejected = model.Rejected,
|
|
||||||
TvdbId = releaseInfo.TvdbId,
|
|
||||||
TvRageId = releaseInfo.TvRageId,
|
|
||||||
Rejections = model.Rejections.Select(r => r.Reason).ToList(),
|
|
||||||
PublishDate = releaseInfo.PublishDate,
|
|
||||||
CommentUrl = releaseInfo.CommentUrl,
|
|
||||||
DownloadUrl = releaseInfo.DownloadUrl,
|
|
||||||
InfoUrl = releaseInfo.InfoUrl,
|
|
||||||
DownloadAllowed = remoteEpisode.DownloadAllowed,
|
|
||||||
//ReleaseWeight
|
|
||||||
|
|
||||||
MagnetUrl = torrentInfo.MagnetUrl,
|
|
||||||
InfoHash = torrentInfo.InfoHash,
|
|
||||||
Seeders = torrentInfo.Seeders,
|
|
||||||
Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
|
|
||||||
Protocol = releaseInfo.DownloadProtocol,
|
|
||||||
|
|
||||||
IsDaily = parsedEpisodeInfo.IsDaily,
|
|
||||||
IsAbsoluteNumbering = parsedEpisodeInfo.IsAbsoluteNumbering,
|
|
||||||
IsPossibleSpecialEpisode = parsedEpisodeInfo.IsPossibleSpecialEpisode,
|
|
||||||
Special = parsedEpisodeInfo.Special,
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ReleaseInfo ToModel(this ReleaseResource resource)
|
|
||||||
{
|
|
||||||
ReleaseInfo model;
|
|
||||||
|
|
||||||
if (resource.Protocol == DownloadProtocol.Torrent)
|
|
||||||
{
|
|
||||||
model = new TorrentInfo
|
|
||||||
{
|
|
||||||
MagnetUrl = resource.MagnetUrl,
|
|
||||||
InfoHash = resource.InfoHash,
|
|
||||||
Seeders = resource.Seeders,
|
|
||||||
Peers = (resource.Seeders.HasValue && resource.Leechers.HasValue) ? (resource.Seeders + resource.Leechers) : null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
model = new ReleaseInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
model.Guid = resource.Guid;
|
|
||||||
model.Title = resource.Title;
|
|
||||||
model.Size = resource.Size;
|
|
||||||
model.DownloadUrl = resource.DownloadUrl;
|
|
||||||
model.InfoUrl = resource.InfoUrl;
|
|
||||||
model.CommentUrl = resource.CommentUrl;
|
|
||||||
model.IndexerId = resource.IndexerId;
|
|
||||||
model.Indexer = resource.Indexer;
|
|
||||||
model.DownloadProtocol = resource.DownloadProtocol;
|
|
||||||
model.TvdbId = resource.TvdbId;
|
|
||||||
model.TvRageId = resource.TvRageId;
|
|
||||||
model.PublishDate = resource.PublishDate;
|
|
||||||
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Instrumentation;
|
using NzbDrone.Core.Instrumentation;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Logs
|
namespace NzbDrone.Api.Logs
|
||||||
{
|
{
|
||||||
@@ -15,7 +16,7 @@ namespace NzbDrone.Api.Logs
|
|||||||
|
|
||||||
private PagingResource<LogResource> GetLogs(PagingResource<LogResource> pagingResource)
|
private PagingResource<LogResource> GetLogs(PagingResource<LogResource> pagingResource)
|
||||||
{
|
{
|
||||||
var pageSpec = pagingResource.MapToPagingSpec<LogResource, Log>();
|
var pageSpec = pagingResource.InjectTo<PagingSpec<Log>>();
|
||||||
|
|
||||||
if (pageSpec.SortKey == "time")
|
if (pageSpec.SortKey == "time")
|
||||||
{
|
{
|
||||||
@@ -47,7 +48,7 @@ namespace NzbDrone.Api.Logs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ApplyToPage(_logService.Paged, pageSpec, LogResourceMapper.ToResource);
|
return ApplyToPage(_logService.Paged, pageSpec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,25 +11,6 @@ namespace NzbDrone.Api.Logs
|
|||||||
public string Level { get; set; }
|
public string Level { get; set; }
|
||||||
public string Logger { get; set; }
|
public string Logger { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
}
|
public string Method { get; set; }
|
||||||
|
|
||||||
public static class LogResourceMapper
|
|
||||||
{
|
|
||||||
public static LogResource ToResource(this Core.Instrumentation.Log model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new LogResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
Time = model.Time,
|
|
||||||
Exception = model.Exception,
|
|
||||||
ExceptionType = model.ExceptionType,
|
|
||||||
Level = model.Level,
|
|
||||||
Logger = model.Logger,
|
|
||||||
Message = model.Message
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace NzbDrone.Api.ManualImport
|
|||||||
var downloadIdQuery = Request.Query.downloadId;
|
var downloadIdQuery = Request.Query.downloadId;
|
||||||
var downloadId = (string)downloadIdQuery.Value;
|
var downloadId = (string)downloadIdQuery.Value;
|
||||||
|
|
||||||
return _manualImportService.GetMediaFiles(folder, downloadId).ToResource().Select(AddQualityWeight).ToList();
|
return ToListResource(_manualImportService.GetMediaFiles(folder, downloadId)).Select(AddQualityWeight).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ManualImportResource AddQualityWeight(ManualImportResource item)
|
private ManualImportResource AddQualityWeight(ManualImportResource item)
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Episodes;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Api.Series;
|
||||||
using NzbDrone.Common.Crypto;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
@@ -22,35 +20,13 @@ namespace NzbDrone.Api.ManualImport
|
|||||||
public int QualityWeight { get; set; }
|
public int QualityWeight { get; set; }
|
||||||
public string DownloadId { get; set; }
|
public string DownloadId { get; set; }
|
||||||
public IEnumerable<Rejection> Rejections { get; set; }
|
public IEnumerable<Rejection> Rejections { get; set; }
|
||||||
}
|
|
||||||
|
|
||||||
public static class ManualImportResourceMapper
|
public int Id
|
||||||
{
|
|
||||||
public static ManualImportResource ToResource(this Core.MediaFiles.EpisodeImport.Manual.ManualImportItem model)
|
|
||||||
{
|
{
|
||||||
if (model == null) return null;
|
get
|
||||||
|
|
||||||
return new ManualImportResource
|
|
||||||
{
|
{
|
||||||
Id = HashConverter.GetHashInt31(model.Path),
|
return Path.GetHashCode();
|
||||||
|
}
|
||||||
Path = model.Path,
|
|
||||||
RelativePath = model.RelativePath,
|
|
||||||
Name = model.Name,
|
|
||||||
Size = model.Size,
|
|
||||||
Series = model.Series.ToResource(),
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
Episodes = model.Episodes.ToResource(),
|
|
||||||
Quality = model.Quality,
|
|
||||||
//QualityWeight
|
|
||||||
DownloadId = model.DownloadId,
|
|
||||||
Rejections = model.Rejections
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ManualImportResource> ToResource(this IEnumerable<Core.MediaFiles.EpisodeImport.Manual.ManualImportItem> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Marr.Data;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Mapping
|
||||||
|
{
|
||||||
|
public class CloneInjection : ConventionInjection
|
||||||
|
{
|
||||||
|
protected override bool Match(ConventionInfo conventionInfo)
|
||||||
|
{
|
||||||
|
return conventionInfo.SourceProp.Name == conventionInfo.TargetProp.Name &&
|
||||||
|
conventionInfo.SourceProp.Value != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override object SetValue(ConventionInfo conventionInfo)
|
||||||
|
{
|
||||||
|
if (conventionInfo.SourceProp.Type == conventionInfo.TargetProp.Type)
|
||||||
|
return conventionInfo.SourceProp.Value;
|
||||||
|
|
||||||
|
|
||||||
|
if (conventionInfo.SourceProp.Type.IsArray)
|
||||||
|
{
|
||||||
|
var array = (Array)conventionInfo.SourceProp.Value;
|
||||||
|
var clone = (Array)array.Clone();
|
||||||
|
|
||||||
|
for (var index = 0; index < array.Length; index++)
|
||||||
|
{
|
||||||
|
var item = array.GetValue(index);
|
||||||
|
if (!item.GetType().IsValueType && !(item is string))
|
||||||
|
{
|
||||||
|
clone.SetValue(Activator.CreateInstance(item.GetType()).InjectFrom<CloneInjection>(item), index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conventionInfo.SourceProp.Type.IsGenericType)
|
||||||
|
{
|
||||||
|
var genericInterfaces = conventionInfo.SourceProp.Type.GetGenericTypeDefinition().GetInterfaces();
|
||||||
|
if (genericInterfaces.Any(d => d == typeof(IEnumerable)))
|
||||||
|
{
|
||||||
|
return MapLists(conventionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genericInterfaces.Any(i => i == typeof(ILazyLoaded)))
|
||||||
|
{
|
||||||
|
return MapLazy(conventionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
//unhandled generic type, you could also return null or throw
|
||||||
|
return conventionInfo.SourceProp.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//for simple object types create a new instace and apply the clone injection on it
|
||||||
|
return Activator.CreateInstance(conventionInfo.TargetProp.Type)
|
||||||
|
.InjectFrom<CloneInjection>(conventionInfo.SourceProp.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object MapLazy(ConventionInfo conventionInfo)
|
||||||
|
{
|
||||||
|
var sourceArgument = conventionInfo.SourceProp.Type.GetGenericArguments()[0];
|
||||||
|
|
||||||
|
dynamic lazy = conventionInfo.SourceProp.Value;
|
||||||
|
|
||||||
|
if (lazy.IsLoaded && lazy.Value != null)
|
||||||
|
{
|
||||||
|
if (conventionInfo.TargetProp.Type.IsAssignableFrom(sourceArgument))
|
||||||
|
{
|
||||||
|
return lazy.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var genericArgument = conventionInfo.TargetProp.Type;
|
||||||
|
|
||||||
|
if (genericArgument.IsValueType || genericArgument == typeof(string))
|
||||||
|
{
|
||||||
|
return lazy.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genericArgument.IsGenericType)
|
||||||
|
{
|
||||||
|
if (conventionInfo.SourceProp.Type.GetGenericTypeDefinition().GetInterfaces().Any(d => d == typeof(IEnumerable)))
|
||||||
|
{
|
||||||
|
return MapLists(genericArgument, lazy.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Activator.CreateInstance(genericArgument).InjectFrom((object)lazy.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object MapLists(ConventionInfo conventionInfo)
|
||||||
|
{
|
||||||
|
var genericArgument = conventionInfo.TargetProp.Type.GetGenericArguments()[0];
|
||||||
|
|
||||||
|
return MapLists(genericArgument, conventionInfo.SourceProp.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object MapLists(Type targetType, object sourceValue)
|
||||||
|
{
|
||||||
|
if (targetType.IsValueType || targetType == typeof(string))
|
||||||
|
{
|
||||||
|
return sourceValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var listType = typeof(List<>).MakeGenericType(targetType);
|
||||||
|
var addMethod = listType.GetMethod("Add");
|
||||||
|
|
||||||
|
var result = Activator.CreateInstance(listType);
|
||||||
|
|
||||||
|
foreach (var sourceItem in (IEnumerable)sourceValue)
|
||||||
|
{
|
||||||
|
var e = Activator.CreateInstance(targetType).InjectFrom<CloneInjection>(sourceItem);
|
||||||
|
addMethod.Invoke(result, new[] { e });
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Common.Reflection;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Mapping
|
||||||
|
{
|
||||||
|
public static class MappingValidation
|
||||||
|
{
|
||||||
|
public static void ValidateMapping(Type modelType, Type resourceType)
|
||||||
|
{
|
||||||
|
var errors = modelType.GetSimpleProperties().Where(c=>!c.GetGetMethod().IsStatic).Select(p => GetError(resourceType, p)).Where(c => c != null).ToList();
|
||||||
|
|
||||||
|
if (errors.Any())
|
||||||
|
{
|
||||||
|
throw new ResourceMappingException(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintExtraProperties(modelType, resourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PrintExtraProperties(Type modelType, Type resourceType)
|
||||||
|
{
|
||||||
|
var resourceBaseProperties = typeof(RestResource).GetProperties().Select(c => c.Name);
|
||||||
|
var resourceProperties = resourceType.GetProperties().Select(c => c.Name).Except(resourceBaseProperties);
|
||||||
|
var modelProperties = modelType.GetProperties().Select(c => c.Name);
|
||||||
|
|
||||||
|
var extra = resourceProperties.Except(modelProperties);
|
||||||
|
|
||||||
|
foreach (var extraProp in extra)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Extra: [{0}]", extraProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetError(Type resourceType, PropertyInfo modelProperty)
|
||||||
|
{
|
||||||
|
var resourceProperty = resourceType.GetProperties().FirstOrDefault(c => c.Name == modelProperty.Name);
|
||||||
|
|
||||||
|
if (resourceProperty == null)
|
||||||
|
{
|
||||||
|
return string.Format("public {0} {1} {{ get; set; }}", modelProperty.PropertyType.Name, modelProperty.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceProperty.PropertyType != modelProperty.PropertyType && !typeof(RestResource).IsAssignableFrom(resourceProperty.PropertyType))
|
||||||
|
{
|
||||||
|
return string.Format("Expected {0}.{1} to have type of {2} but found {3}", resourceType.Name, resourceProperty.Name, modelProperty.PropertyType, resourceProperty.PropertyType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Mapping
|
||||||
|
{
|
||||||
|
public class ResourceMappingException : ApplicationException
|
||||||
|
{
|
||||||
|
public ResourceMappingException(IEnumerable<string> error)
|
||||||
|
: base(Environment.NewLine + string.Join(Environment.NewLine, error.OrderBy(c => c)))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Mapping
|
||||||
|
{
|
||||||
|
public static class ValueInjectorExtensions
|
||||||
|
{
|
||||||
|
public static TTarget InjectTo<TTarget>(this object source) where TTarget : new()
|
||||||
|
{
|
||||||
|
if (source == null) return default(TTarget);
|
||||||
|
|
||||||
|
var targetType = typeof(TTarget);
|
||||||
|
|
||||||
|
if (targetType.IsGenericType &&
|
||||||
|
targetType.GetGenericTypeDefinition() != null &&
|
||||||
|
targetType.GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable)) &&
|
||||||
|
source.GetType().IsGenericType &&
|
||||||
|
source.GetType().GetGenericTypeDefinition() != null &&
|
||||||
|
source.GetType().GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable)))
|
||||||
|
{
|
||||||
|
var result = new TTarget();
|
||||||
|
|
||||||
|
var listSubType = targetType.GetGenericArguments()[0];
|
||||||
|
var listType = typeof(List<>).MakeGenericType(listSubType);
|
||||||
|
var addMethod = listType.GetMethod("Add");
|
||||||
|
|
||||||
|
foreach (var sourceItem in (IEnumerable)source)
|
||||||
|
{
|
||||||
|
var e = Activator.CreateInstance(listSubType).InjectFrom<CloneInjection>(sourceItem);
|
||||||
|
addMethod.Invoke(result, new[] { e });
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TTarget)new TTarget().InjectFrom<CloneInjection>(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using NzbDrone.Core.Metadata;
|
||||||
using NzbDrone.Core.Metadata;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Metadata
|
namespace NzbDrone.Api.Metadata
|
||||||
{
|
{
|
||||||
@@ -10,20 +9,6 @@ namespace NzbDrone.Api.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void MapToResource(MetadataResource resource, MetadataDefinition definition)
|
|
||||||
{
|
|
||||||
base.MapToResource(resource, definition);
|
|
||||||
|
|
||||||
resource.Enable = definition.Enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void MapToModel(MetadataDefinition definition, MetadataResource resource)
|
|
||||||
{
|
|
||||||
base.MapToModel(definition, resource);
|
|
||||||
|
|
||||||
definition.Enable = resource.Enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Validate(MetadataDefinition definition, bool includeWarnings)
|
protected override void Validate(MetadataDefinition definition, bool includeWarnings)
|
||||||
{
|
{
|
||||||
if (!definition.Enable) return;
|
if (!definition.Enable) return;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using NLog;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.Bootstrapper;
|
using Nancy.Bootstrapper;
|
||||||
using Nancy.Diagnostics;
|
using Nancy.Diagnostics;
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Api.ErrorManagement;
|
using NzbDrone.Api.ErrorManagement;
|
||||||
using NzbDrone.Api.Extensions.Pipelines;
|
using NzbDrone.Api.Extensions.Pipelines;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
@@ -38,11 +37,13 @@ namespace NzbDrone.Api
|
|||||||
|
|
||||||
container.Resolve<DatabaseTarget>().Register();
|
container.Resolve<DatabaseTarget>().Register();
|
||||||
container.Resolve<IEventAggregator>().PublishEvent(new ApplicationStartedEvent());
|
container.Resolve<IEventAggregator>().PublishEvent(new ApplicationStartedEvent());
|
||||||
|
|
||||||
|
ApplicationPipelines.OnError.AddItemToEndOfPipeline((Func<NancyContext, Exception, Response>) container.Resolve<NzbDroneErrorPipeline>().HandleException);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterPipelines(IPipelines pipelines)
|
private void RegisterPipelines(IPipelines pipelines)
|
||||||
{
|
{
|
||||||
var pipelineRegistrars = _tinyIoCContainer.ResolveAll<IRegisterNancyPipeline>().OrderBy(v => v.Order).ToList();
|
var pipelineRegistrars = _tinyIoCContainer.ResolveAll<IRegisterNancyPipeline>();
|
||||||
|
|
||||||
foreach (var registerNancyPipeline in pipelineRegistrars)
|
foreach (var registerNancyPipeline in pipelineRegistrars)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using NzbDrone.Core.Notifications;
|
||||||
using NzbDrone.Core.Notifications;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Notifications
|
namespace NzbDrone.Api.Notifications
|
||||||
{
|
{
|
||||||
@@ -10,36 +9,6 @@ namespace NzbDrone.Api.Notifications
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void MapToResource(NotificationResource resource, NotificationDefinition definition)
|
|
||||||
{
|
|
||||||
base.MapToResource(resource, definition);
|
|
||||||
|
|
||||||
resource.OnGrab = definition.OnGrab;
|
|
||||||
resource.OnDownload = definition.OnDownload;
|
|
||||||
resource.OnUpgrade = definition.OnUpgrade;
|
|
||||||
resource.OnRename = definition.OnRename;
|
|
||||||
resource.SupportsOnGrab = definition.SupportsOnGrab;
|
|
||||||
resource.SupportsOnDownload = definition.SupportsOnDownload;
|
|
||||||
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
|
||||||
resource.SupportsOnRename = definition.SupportsOnRename;
|
|
||||||
resource.Tags = definition.Tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void MapToModel(NotificationDefinition definition, NotificationResource resource)
|
|
||||||
{
|
|
||||||
base.MapToModel(definition, resource);
|
|
||||||
|
|
||||||
definition.OnGrab = resource.OnGrab;
|
|
||||||
definition.OnDownload = resource.OnDownload;
|
|
||||||
definition.OnUpgrade = resource.OnUpgrade;
|
|
||||||
definition.OnRename = resource.OnRename;
|
|
||||||
definition.SupportsOnGrab = resource.SupportsOnGrab;
|
|
||||||
definition.SupportsOnDownload = resource.SupportsOnDownload;
|
|
||||||
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
|
||||||
definition.SupportsOnRename = resource.SupportsOnRename;
|
|
||||||
definition.Tags = resource.Tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Validate(NotificationDefinition definition, bool includeWarnings)
|
protected override void Validate(NotificationDefinition definition, bool includeWarnings)
|
||||||
{
|
{
|
||||||
if (!definition.OnGrab && !definition.OnDownload) return;
|
if (!definition.OnGrab && !definition.OnDownload) return;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace NzbDrone.Api.Notifications
|
|||||||
{
|
{
|
||||||
public class NotificationResource : ProviderResource
|
public class NotificationResource : ProviderResource
|
||||||
{
|
{
|
||||||
|
public string Link { get; set; }
|
||||||
public bool OnGrab { get; set; }
|
public bool OnGrab { get; set; }
|
||||||
public bool OnDownload { get; set; }
|
public bool OnDownload { get; set; }
|
||||||
public bool OnUpgrade { get; set; }
|
public bool OnUpgrade { get; set; }
|
||||||
@@ -12,6 +13,7 @@ namespace NzbDrone.Api.Notifications
|
|||||||
public bool SupportsOnDownload { get; set; }
|
public bool SupportsOnDownload { get; set; }
|
||||||
public bool SupportsOnUpgrade { get; set; }
|
public bool SupportsOnUpgrade { get; set; }
|
||||||
public bool SupportsOnRename { get; set; }
|
public bool SupportsOnRename { get; set; }
|
||||||
|
public string TestCommand { get; set; }
|
||||||
public HashSet<int> Tags { get; set; }
|
public HashSet<int> Tags { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,8 +40,8 @@
|
|||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="FluentValidation, Version=6.2.1.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="FluentValidation, Version=6.0.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\FluentValidation.6.2.1.0\lib\portable-net40+sl50+wp80+win8+wpa81\FluentValidation.dll</HintPath>
|
<HintPath>..\packages\FluentValidation.6.0.2.0\lib\portable-net40+sl50+wp80+win8+wpa81\FluentValidation.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Nancy, Version=0.23.2.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Nancy, Version=0.23.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
@@ -59,10 +59,6 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\NLog.4.3.4\lib\net40\NLog.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
@@ -70,6 +66,12 @@
|
|||||||
<Reference Include="DDay.iCal">
|
<Reference Include="DDay.iCal">
|
||||||
<HintPath>..\packages\DDay.iCal.1.0.2.575\lib\DDay.iCal.dll</HintPath>
|
<HintPath>..\packages\DDay.iCal.1.0.2.575\lib\DDay.iCal.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="NLog">
|
||||||
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Omu.ValueInjecter">
|
||||||
|
<HintPath>..\packages\ValueInjecter.2.3.3\lib\net35\Omu.ValueInjecter.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Data.SQLite, Version=1.0.84.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
<Reference Include="System.Data.SQLite, Version=1.0.84.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
|
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
|
||||||
@@ -97,7 +99,6 @@
|
|||||||
<Compile Include="Commands\CommandResource.cs" />
|
<Compile Include="Commands\CommandResource.cs" />
|
||||||
<Compile Include="Extensions\AccessControlHeaders.cs" />
|
<Compile Include="Extensions\AccessControlHeaders.cs" />
|
||||||
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
|
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
|
||||||
<Compile Include="Extensions\Pipelines\RequestLoggingPipeline.cs" />
|
|
||||||
<Compile Include="Frontend\Mappers\LoginHtmlMapper.cs" />
|
<Compile Include="Frontend\Mappers\LoginHtmlMapper.cs" />
|
||||||
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
||||||
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
||||||
@@ -108,6 +109,7 @@
|
|||||||
<Compile Include="ManualImport\ManualImportResource.cs" />
|
<Compile Include="ManualImport\ManualImportResource.cs" />
|
||||||
<Compile Include="Profiles\Delay\DelayProfileModule.cs" />
|
<Compile Include="Profiles\Delay\DelayProfileModule.cs" />
|
||||||
<Compile Include="Profiles\Delay\DelayProfileResource.cs" />
|
<Compile Include="Profiles\Delay\DelayProfileResource.cs" />
|
||||||
|
<Compile Include="Profiles\Delay\DelayProfileValidator.cs" />
|
||||||
<Compile Include="Queue\QueueActionModule.cs" />
|
<Compile Include="Queue\QueueActionModule.cs" />
|
||||||
<Compile Include="RemotePathMappings\RemotePathMappingModule.cs" />
|
<Compile Include="RemotePathMappings\RemotePathMappingModule.cs" />
|
||||||
<Compile Include="RemotePathMappings\RemotePathMappingResource.cs" />
|
<Compile Include="RemotePathMappings\RemotePathMappingResource.cs" />
|
||||||
@@ -142,6 +144,7 @@
|
|||||||
<Compile Include="ErrorManagement\ErrorModel.cs" />
|
<Compile Include="ErrorManagement\ErrorModel.cs" />
|
||||||
<Compile Include="ErrorManagement\NzbDroneErrorPipeline.cs" />
|
<Compile Include="ErrorManagement\NzbDroneErrorPipeline.cs" />
|
||||||
<Compile Include="Exceptions\InvalidApiKeyException.cs" />
|
<Compile Include="Exceptions\InvalidApiKeyException.cs" />
|
||||||
|
<Compile Include="Extensions\LazyExtensions.cs" />
|
||||||
<Compile Include="Extensions\NancyJsonSerializer.cs" />
|
<Compile Include="Extensions\NancyJsonSerializer.cs" />
|
||||||
<Compile Include="Extensions\Pipelines\CacheHeaderPipeline.cs" />
|
<Compile Include="Extensions\Pipelines\CacheHeaderPipeline.cs" />
|
||||||
<Compile Include="Extensions\Pipelines\GZipPipeline.cs" />
|
<Compile Include="Extensions\Pipelines\GZipPipeline.cs" />
|
||||||
@@ -176,6 +179,10 @@
|
|||||||
<Compile Include="Logs\LogModule.cs" />
|
<Compile Include="Logs\LogModule.cs" />
|
||||||
<Compile Include="Logs\LogResource.cs" />
|
<Compile Include="Logs\LogResource.cs" />
|
||||||
<Compile Include="Logs\UpdateLogFileModule.cs" />
|
<Compile Include="Logs\UpdateLogFileModule.cs" />
|
||||||
|
<Compile Include="Mapping\CloneInjection.cs" />
|
||||||
|
<Compile Include="Mapping\MappingValidation.cs" />
|
||||||
|
<Compile Include="Mapping\ResourceMappingException.cs" />
|
||||||
|
<Compile Include="Mapping\ValueInjectorExtensions.cs" />
|
||||||
<Compile Include="MediaCovers\MediaCoverModule.cs" />
|
<Compile Include="MediaCovers\MediaCoverModule.cs" />
|
||||||
<Compile Include="Metadata\MetadataModule.cs" />
|
<Compile Include="Metadata\MetadataModule.cs" />
|
||||||
<Compile Include="Metadata\MetadataResource.cs" />
|
<Compile Include="Metadata\MetadataResource.cs" />
|
||||||
@@ -223,6 +230,7 @@
|
|||||||
<Compile Include="Series\SeasonStatisticsResource.cs" />
|
<Compile Include="Series\SeasonStatisticsResource.cs" />
|
||||||
<Compile Include="System\Backup\BackupModule.cs" />
|
<Compile Include="System\Backup\BackupModule.cs" />
|
||||||
<Compile Include="System\Backup\BackupResource.cs" />
|
<Compile Include="System\Backup\BackupResource.cs" />
|
||||||
|
<Compile Include="System\Statistics\StatisticsModule.cs" />
|
||||||
<Compile Include="System\Tasks\TaskModule.cs" />
|
<Compile Include="System\Tasks\TaskModule.cs" />
|
||||||
<Compile Include="System\Tasks\TaskResource.cs" />
|
<Compile Include="System\Tasks\TaskResource.cs" />
|
||||||
<Compile Include="System\SystemModule.cs" />
|
<Compile Include="System\SystemModule.cs" />
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Validation;
|
using NzbDrone.Api.Validation;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
|
|
||||||
namespace NzbDrone.Api
|
namespace NzbDrone.Api
|
||||||
{
|
{
|
||||||
@@ -24,19 +25,42 @@ namespace NzbDrone.Api
|
|||||||
PutValidator.RuleFor(r => r.Id).ValidId();
|
PutValidator.RuleFor(r => r.Id).ValidId();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PagingResource<TResource> ApplyToPage<TModel>(Func<PagingSpec<TModel>, PagingSpec<TModel>> function, PagingSpec<TModel> pagingSpec, Converter<TModel, TResource> mapper)
|
protected int GetNewId<TModel>(Func<TModel, TModel> function, TResource resource) where TModel : ModelBase, new()
|
||||||
|
{
|
||||||
|
var model = resource.InjectTo<TModel>();
|
||||||
|
function(model);
|
||||||
|
return model.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<TResource> ToListResource<TModel>(Func<IEnumerable<TModel>> function) where TModel : class
|
||||||
|
{
|
||||||
|
var modelList = function();
|
||||||
|
return ToListResource(modelList);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual List<TResource> ToListResource<TModel>(IEnumerable<TModel> modelList) where TModel : class
|
||||||
|
{
|
||||||
|
return modelList.Select(ToResource).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual TResource ToResource<TModel>(TModel model) where TModel : class
|
||||||
|
{
|
||||||
|
return model.InjectTo<TResource>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PagingResource<TResource> ApplyToPage<TModel>(Func<PagingSpec<TModel>, PagingSpec<TModel>> function, PagingSpec<TModel> pagingSpec) where TModel : ModelBase, new()
|
||||||
{
|
{
|
||||||
pagingSpec = function(pagingSpec);
|
pagingSpec = function(pagingSpec);
|
||||||
|
|
||||||
return new PagingResource<TResource>
|
return new PagingResource<TResource>
|
||||||
{
|
{
|
||||||
Page = pagingSpec.Page,
|
Page = pagingSpec.Page,
|
||||||
PageSize = pagingSpec.PageSize,
|
PageSize = pagingSpec.PageSize,
|
||||||
SortDirection = pagingSpec.SortDirection,
|
SortDirection = pagingSpec.SortDirection,
|
||||||
SortKey = pagingSpec.SortKey,
|
SortKey = pagingSpec.SortKey,
|
||||||
TotalRecords = pagingSpec.TotalRecords,
|
TotalRecords = pagingSpec.TotalRecords,
|
||||||
Records = pagingSpec.Records.ConvertAll(mapper)
|
Records = ToListResource(pagingSpec.Records)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ namespace NzbDrone.Api
|
|||||||
{
|
{
|
||||||
public abstract class NzbDroneRestModuleWithSignalR<TResource, TModel> : NzbDroneRestModule<TResource>, IHandle<ModelEvent<TModel>>
|
public abstract class NzbDroneRestModuleWithSignalR<TResource, TModel> : NzbDroneRestModule<TResource>, IHandle<ModelEvent<TModel>>
|
||||||
where TResource : RestResource, new()
|
where TResource : RestResource, new()
|
||||||
where TModel : ModelBase, new()
|
where TModel : ModelBase
|
||||||
{
|
{
|
||||||
private readonly IBroadcastSignalRMessage _signalRBroadcaster;
|
private readonly IBroadcastSignalRMessage _signalRBroadcaster;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using NzbDrone.Core.Datastore;
|
|||||||
|
|
||||||
namespace NzbDrone.Api
|
namespace NzbDrone.Api
|
||||||
{
|
{
|
||||||
public class PagingResource<TResource>
|
public class PagingResource<TModel>
|
||||||
{
|
{
|
||||||
public int Page { get; set; }
|
public int Page { get; set; }
|
||||||
public int PageSize { get; set; }
|
public int PageSize { get; set; }
|
||||||
@@ -12,31 +12,6 @@ namespace NzbDrone.Api
|
|||||||
public string FilterKey { get; set; }
|
public string FilterKey { get; set; }
|
||||||
public string FilterValue { get; set; }
|
public string FilterValue { get; set; }
|
||||||
public int TotalRecords { get; set; }
|
public int TotalRecords { get; set; }
|
||||||
public List<TResource> Records { get; set; }
|
public List<TModel> Records { get; set; }
|
||||||
}
|
|
||||||
|
|
||||||
public static class PagingResourceMapper
|
|
||||||
{
|
|
||||||
public static PagingSpec<TModel> MapToPagingSpec<TResource, TModel>(this PagingResource<TResource> pagingResource, string defaultSortKey = "Id", SortDirection defaultSortDirection = SortDirection.Ascending)
|
|
||||||
{
|
|
||||||
var pagingSpec = new PagingSpec<TModel>
|
|
||||||
{
|
|
||||||
Page = pagingResource.Page,
|
|
||||||
PageSize = pagingResource.PageSize,
|
|
||||||
SortKey = pagingResource.SortKey,
|
|
||||||
SortDirection = pagingResource.SortDirection,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (pagingResource.SortKey == null)
|
|
||||||
{
|
|
||||||
pagingSpec.SortKey = defaultSortKey;
|
|
||||||
if(pagingResource.SortDirection == SortDirection.Default)
|
|
||||||
{
|
|
||||||
pagingSpec.SortDirection = defaultSortDirection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pagingSpec;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Parser;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Parse
|
namespace NzbDrone.Api.Parse
|
||||||
{
|
{
|
||||||
@@ -17,7 +16,7 @@ namespace NzbDrone.Api.Parse
|
|||||||
|
|
||||||
private ParseResource Parse()
|
private ParseResource Parse()
|
||||||
{
|
{
|
||||||
var title = Request.Query.Title.Value as string;
|
var title = Request.Query.Title.Value;
|
||||||
var parsedEpisodeInfo = Parser.ParseTitle(title);
|
var parsedEpisodeInfo = Parser.ParseTitle(title);
|
||||||
|
|
||||||
if (parsedEpisodeInfo == null)
|
if (parsedEpisodeInfo == null)
|
||||||
@@ -27,24 +26,24 @@ namespace NzbDrone.Api.Parse
|
|||||||
|
|
||||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
|
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
|
||||||
|
|
||||||
if (remoteEpisode != null)
|
if (remoteEpisode == null)
|
||||||
{
|
{
|
||||||
|
remoteEpisode = new RemoteEpisode
|
||||||
|
{
|
||||||
|
ParsedEpisodeInfo = parsedEpisodeInfo
|
||||||
|
};
|
||||||
|
|
||||||
return new ParseResource
|
return new ParseResource
|
||||||
{
|
{
|
||||||
Title = title,
|
Title = title,
|
||||||
ParsedEpisodeInfo = remoteEpisode.ParsedEpisodeInfo,
|
ParsedEpisodeInfo = parsedEpisodeInfo
|
||||||
Series = remoteEpisode.Series.ToResource(),
|
};
|
||||||
Episodes = remoteEpisode.Episodes.ToResource()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new ParseResource
|
|
||||||
{
|
|
||||||
Title = title,
|
|
||||||
ParsedEpisodeInfo = parsedEpisodeInfo
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var resource = ToResource(remoteEpisode);
|
||||||
|
resource.Title = title;
|
||||||
|
|
||||||
|
return resource;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Validation;
|
using NzbDrone.Api.Validation;
|
||||||
using NzbDrone.Core.Profiles.Delay;
|
using NzbDrone.Core.Profiles.Delay;
|
||||||
@@ -26,21 +26,12 @@ namespace NzbDrone.Api.Profiles.Delay
|
|||||||
SharedValidator.RuleFor(d => d.Tags).SetValidator(tagInUseValidator);
|
SharedValidator.RuleFor(d => d.Tags).SetValidator(tagInUseValidator);
|
||||||
SharedValidator.RuleFor(d => d.UsenetDelay).GreaterThanOrEqualTo(0);
|
SharedValidator.RuleFor(d => d.UsenetDelay).GreaterThanOrEqualTo(0);
|
||||||
SharedValidator.RuleFor(d => d.TorrentDelay).GreaterThanOrEqualTo(0);
|
SharedValidator.RuleFor(d => d.TorrentDelay).GreaterThanOrEqualTo(0);
|
||||||
|
SharedValidator.RuleFor(d => d.Id).SetValidator(new DelayProfileValidator());
|
||||||
SharedValidator.Custom(delayProfile =>
|
|
||||||
{
|
|
||||||
if (!delayProfile.EnableUsenet && !delayProfile.EnableTorrent)
|
|
||||||
{
|
|
||||||
return new ValidationFailure("", "Either Usenet or Torrent should be enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int Create(DelayProfileResource resource)
|
private int Create(DelayProfileResource resource)
|
||||||
{
|
{
|
||||||
var model = resource.ToModel();
|
var model = resource.InjectTo<DelayProfile>();
|
||||||
model = _delayProfileService.Add(model);
|
model = _delayProfileService.Add(model);
|
||||||
|
|
||||||
return model.Id;
|
return model.Id;
|
||||||
@@ -58,18 +49,17 @@ namespace NzbDrone.Api.Profiles.Delay
|
|||||||
|
|
||||||
private void Update(DelayProfileResource resource)
|
private void Update(DelayProfileResource resource)
|
||||||
{
|
{
|
||||||
var model = resource.ToModel();
|
GetNewId<DelayProfile>(_delayProfileService.Update, resource);
|
||||||
_delayProfileService.Update(model);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DelayProfileResource GetById(int id)
|
private DelayProfileResource GetById(int id)
|
||||||
{
|
{
|
||||||
return _delayProfileService.Get(id).ToResource();
|
return _delayProfileService.Get(id).InjectTo<DelayProfileResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DelayProfileResource> GetAll()
|
private List<DelayProfileResource> GetAll()
|
||||||
{
|
{
|
||||||
return _delayProfileService.All().ToResource();
|
return _delayProfileService.All().InjectTo<List<DelayProfileResource>>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Profiles.Delay;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Profiles.Delay
|
namespace NzbDrone.Api.Profiles.Delay
|
||||||
{
|
{
|
||||||
@@ -16,48 +14,4 @@ namespace NzbDrone.Api.Profiles.Delay
|
|||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
public HashSet<int> Tags { get; set; }
|
public HashSet<int> Tags { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DelayProfileResourceMapper
|
|
||||||
{
|
|
||||||
public static DelayProfileResource ToResource(this DelayProfile model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new DelayProfileResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
EnableUsenet = model.EnableUsenet,
|
|
||||||
EnableTorrent = model.EnableTorrent,
|
|
||||||
PreferredProtocol = model.PreferredProtocol,
|
|
||||||
UsenetDelay = model.UsenetDelay,
|
|
||||||
TorrentDelay = model.TorrentDelay,
|
|
||||||
Order = model.Order,
|
|
||||||
Tags = new HashSet<int>(model.Tags)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DelayProfile ToModel(this DelayProfileResource resource)
|
|
||||||
{
|
|
||||||
if (resource == null) return null;
|
|
||||||
|
|
||||||
return new DelayProfile
|
|
||||||
{
|
|
||||||
Id = resource.Id,
|
|
||||||
|
|
||||||
EnableUsenet = resource.EnableUsenet,
|
|
||||||
EnableTorrent = resource.EnableTorrent,
|
|
||||||
PreferredProtocol = resource.PreferredProtocol,
|
|
||||||
UsenetDelay = resource.UsenetDelay,
|
|
||||||
TorrentDelay = resource.TorrentDelay,
|
|
||||||
Order = resource.Order,
|
|
||||||
Tags = new HashSet<int>(resource.Tags)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<DelayProfileResource> ToResource(this IEnumerable<DelayProfile> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using FluentValidation.Validators;
|
||||||
|
using NzbDrone.Core.Profiles.Delay;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Profiles.Delay
|
||||||
|
{
|
||||||
|
public class DelayProfileValidator : PropertyValidator
|
||||||
|
{
|
||||||
|
public DelayProfileValidator()
|
||||||
|
: base("Usenet or Torrent must be enabled")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
|
{
|
||||||
|
var delayProfile = new DelayProfile();
|
||||||
|
delayProfile.InjectFrom(context.ParentContext.InstanceToValidate);
|
||||||
|
|
||||||
|
if (!delayProfile.EnableUsenet && !delayProfile.EnableTorrent)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ namespace NzbDrone.Api.Profiles.Languages
|
|||||||
public class LanguageResource : RestResource
|
public class LanguageResource : RestResource
|
||||||
{
|
{
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]
|
||||||
public new int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string NameLower { get { return Name.ToLowerInvariant(); } }
|
public string NameLower { get { return Name.ToLowerInvariant(); } }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Core.Profiles;
|
using NzbDrone.Core.Profiles;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
@@ -27,9 +28,9 @@ namespace NzbDrone.Api.Profiles
|
|||||||
|
|
||||||
private int Create(ProfileResource resource)
|
private int Create(ProfileResource resource)
|
||||||
{
|
{
|
||||||
var model = resource.ToModel();
|
var model = resource.InjectTo<Profile>();
|
||||||
|
model = _profileService.Add(model);
|
||||||
return _profileService.Add(model).Id;
|
return model.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteProfile(int id)
|
private void DeleteProfile(int id)
|
||||||
@@ -39,19 +40,26 @@ namespace NzbDrone.Api.Profiles
|
|||||||
|
|
||||||
private void Update(ProfileResource resource)
|
private void Update(ProfileResource resource)
|
||||||
{
|
{
|
||||||
var model = resource.ToModel();
|
var model = _profileService.Get(resource.Id);
|
||||||
|
|
||||||
|
model.Name = resource.Name;
|
||||||
|
model.Cutoff = (Quality)resource.Cutoff.Id;
|
||||||
|
model.Items = resource.Items.InjectTo<List<ProfileQualityItem>>();
|
||||||
|
model.Language = resource.Language;
|
||||||
|
|
||||||
_profileService.Update(model);
|
_profileService.Update(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProfileResource GetById(int id)
|
private ProfileResource GetById(int id)
|
||||||
{
|
{
|
||||||
return _profileService.Get(id).ToResource();
|
return _profileService.Get(id).InjectTo<ProfileResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ProfileResource> GetAll()
|
private List<ProfileResource> GetAll()
|
||||||
{
|
{
|
||||||
return _profileService.All().ToResource();
|
var profiles = _profileService.All().InjectTo<List<ProfileResource>>();
|
||||||
|
|
||||||
|
return profiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Profiles;
|
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Profiles
|
namespace NzbDrone.Api.Profiles
|
||||||
@@ -21,64 +19,4 @@ namespace NzbDrone.Api.Profiles
|
|||||||
public Quality Quality { get; set; }
|
public Quality Quality { get; set; }
|
||||||
public bool Allowed { get; set; }
|
public bool Allowed { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ProfileResourceMapper
|
|
||||||
{
|
|
||||||
public static ProfileResource ToResource(this Profile model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new ProfileResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
Name = model.Name,
|
|
||||||
Cutoff = model.Cutoff,
|
|
||||||
Items = model.Items.ConvertAll(ToResource),
|
|
||||||
Language = model.Language
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProfileQualityItemResource ToResource(this ProfileQualityItem model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new ProfileQualityItemResource
|
|
||||||
{
|
|
||||||
Quality = model.Quality,
|
|
||||||
Allowed = model.Allowed
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Profile ToModel(this ProfileResource resource)
|
|
||||||
{
|
|
||||||
if (resource == null) return null;
|
|
||||||
|
|
||||||
return new Profile
|
|
||||||
{
|
|
||||||
Id = resource.Id,
|
|
||||||
|
|
||||||
Name = resource.Name,
|
|
||||||
Cutoff = (Quality)resource.Cutoff.Id,
|
|
||||||
Items = resource.Items.ConvertAll(ToModel),
|
|
||||||
Language = resource.Language
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProfileQualityItem ToModel(this ProfileQualityItemResource resource)
|
|
||||||
{
|
|
||||||
if (resource == null) return null;
|
|
||||||
|
|
||||||
return new ProfileQualityItem
|
|
||||||
{
|
|
||||||
Quality = (Quality)resource.Quality.Id,
|
|
||||||
Allowed = resource.Allowed
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ProfileResource> ToResource(this IEnumerable<Profile> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Profiles;
|
using NzbDrone.Core.Profiles;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
@@ -30,7 +31,7 @@ namespace NzbDrone.Api.Profiles
|
|||||||
profile.Items = items;
|
profile.Items = items;
|
||||||
profile.Language = Language.English;
|
profile.Language = Language.English;
|
||||||
|
|
||||||
return new List<ProfileResource> { profile.ToResource() };
|
return new List<ProfileResource> { profile.InjectTo<ProfileResource>() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,9 +6,11 @@ using FluentValidation.Results;
|
|||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.ClientSchema;
|
using NzbDrone.Api.ClientSchema;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Common.Reflection;
|
using NzbDrone.Common.Reflection;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace NzbDrone.Api
|
namespace NzbDrone.Api
|
||||||
@@ -27,7 +29,7 @@ namespace NzbDrone.Api
|
|||||||
|
|
||||||
Get["schema"] = x => GetTemplates();
|
Get["schema"] = x => GetTemplates();
|
||||||
Post["test"] = x => Test(ReadResourceFromRequest(true));
|
Post["test"] = x => Test(ReadResourceFromRequest(true));
|
||||||
Post["action/{action}"] = x => RequestAction(x.action, ReadResourceFromRequest(true));
|
Post["connectData/{stage}"] = x => ConnectData(x.stage, ReadResourceFromRequest(true));
|
||||||
|
|
||||||
GetResourceAll = GetAll;
|
GetResourceAll = GetAll;
|
||||||
GetResourceById = GetProviderById;
|
GetResourceById = GetProviderById;
|
||||||
@@ -46,10 +48,9 @@ namespace NzbDrone.Api
|
|||||||
private TProviderResource GetProviderById(int id)
|
private TProviderResource GetProviderById(int id)
|
||||||
{
|
{
|
||||||
var definition = _providerFactory.Get(id);
|
var definition = _providerFactory.Get(id);
|
||||||
_providerFactory.SetProviderCharacteristics(definition);
|
var resource = definition.InjectTo<TProviderResource>();
|
||||||
|
|
||||||
var resource = new TProviderResource();
|
resource.InjectFrom(_providerFactory.GetProviderCharacteristics(_providerFactory.GetInstance(definition), definition));
|
||||||
MapToResource(resource, definition);
|
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
@@ -62,10 +63,10 @@ namespace NzbDrone.Api
|
|||||||
|
|
||||||
foreach (var definition in providerDefinitions)
|
foreach (var definition in providerDefinitions)
|
||||||
{
|
{
|
||||||
_providerFactory.SetProviderCharacteristics(definition);
|
|
||||||
|
|
||||||
var providerResource = new TProviderResource();
|
var providerResource = new TProviderResource();
|
||||||
MapToResource(providerResource, definition);
|
providerResource.InjectFrom(definition);
|
||||||
|
providerResource.InjectFrom(_providerFactory.GetProviderCharacteristics(_providerFactory.GetInstance(definition), definition));
|
||||||
|
providerResource.Fields = SchemaBuilder.ToSchema(definition.Settings);
|
||||||
|
|
||||||
result.Add(providerResource);
|
result.Add(providerResource);
|
||||||
}
|
}
|
||||||
@@ -91,6 +92,11 @@ namespace NzbDrone.Api
|
|||||||
{
|
{
|
||||||
var providerDefinition = GetDefinition(providerResource, false);
|
var providerDefinition = GetDefinition(providerResource, false);
|
||||||
|
|
||||||
|
if (providerDefinition.Enable)
|
||||||
|
{
|
||||||
|
Test(providerDefinition, false);
|
||||||
|
}
|
||||||
|
|
||||||
_providerFactory.Update(providerDefinition);
|
_providerFactory.Update(providerDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,8 +104,15 @@ namespace NzbDrone.Api
|
|||||||
{
|
{
|
||||||
var definition = new TProviderDefinition();
|
var definition = new TProviderDefinition();
|
||||||
|
|
||||||
MapToModel(definition, providerResource);
|
definition.InjectFrom(providerResource);
|
||||||
|
|
||||||
|
var preset = _providerFactory.GetPresetDefinitions(definition)
|
||||||
|
.Where(v => v.Name == definition.Name)
|
||||||
|
.Select(v => v.Settings)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract);
|
||||||
|
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(providerResource.Fields, configContract, preset);
|
||||||
if (validate)
|
if (validate)
|
||||||
{
|
{
|
||||||
Validate(definition, includeWarnings);
|
Validate(definition, includeWarnings);
|
||||||
@@ -108,37 +121,6 @@ namespace NzbDrone.Api
|
|||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void MapToResource(TProviderResource resource, TProviderDefinition definition)
|
|
||||||
{
|
|
||||||
resource.Id = definition.Id;
|
|
||||||
|
|
||||||
resource.Name = definition.Name;
|
|
||||||
resource.ImplementationName = definition.ImplementationName;
|
|
||||||
resource.Implementation = definition.Implementation;
|
|
||||||
resource.ConfigContract = definition.ConfigContract;
|
|
||||||
resource.Message = definition.Message;
|
|
||||||
|
|
||||||
resource.Fields = SchemaBuilder.ToSchema(definition.Settings);
|
|
||||||
|
|
||||||
resource.InfoLink = string.Format("https://github.com/Sonarr/Sonarr/wiki/Supported-{0}#{1}",
|
|
||||||
typeof(TProviderResource).Name.Replace("Resource", "s"),
|
|
||||||
definition.Implementation.ToLower());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void MapToModel(TProviderDefinition definition, TProviderResource resource)
|
|
||||||
{
|
|
||||||
definition.Id = resource.Id;
|
|
||||||
|
|
||||||
definition.Name = resource.Name;
|
|
||||||
definition.ImplementationName = resource.ImplementationName;
|
|
||||||
definition.Implementation = resource.Implementation;
|
|
||||||
definition.ConfigContract = resource.ConfigContract;
|
|
||||||
definition.Message = resource.Message;
|
|
||||||
|
|
||||||
var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract);
|
|
||||||
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFromSchema(resource.Fields, configContract);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeleteProvider(int id)
|
private void DeleteProvider(int id)
|
||||||
{
|
{
|
||||||
_providerFactory.Delete(id);
|
_providerFactory.Delete(id);
|
||||||
@@ -153,14 +135,19 @@ namespace NzbDrone.Api
|
|||||||
foreach (var providerDefinition in defaultDefinitions)
|
foreach (var providerDefinition in defaultDefinitions)
|
||||||
{
|
{
|
||||||
var providerResource = new TProviderResource();
|
var providerResource = new TProviderResource();
|
||||||
MapToResource(providerResource, providerDefinition);
|
providerResource.InjectFrom(providerDefinition);
|
||||||
|
providerResource.Fields = SchemaBuilder.ToSchema(providerDefinition.Settings);
|
||||||
|
providerResource.InfoLink = string.Format("https://github.com/NzbDrone/NzbDrone/wiki/Supported-{0}#{1}",
|
||||||
|
typeof(TProviderResource).Name.Replace("Resource", "s"),
|
||||||
|
providerDefinition.Implementation.ToLower());
|
||||||
|
|
||||||
var presetDefinitions = _providerFactory.GetPresetDefinitions(providerDefinition);
|
var presetDefinitions = _providerFactory.GetPresetDefinitions(providerDefinition);
|
||||||
|
|
||||||
providerResource.Presets = presetDefinitions.Select(v =>
|
providerResource.Presets = presetDefinitions.Select(v =>
|
||||||
{
|
{
|
||||||
var presetResource = new TProviderResource();
|
var presetResource = new TProviderResource();
|
||||||
MapToResource(presetResource, v);
|
presetResource.InjectFrom(v);
|
||||||
|
presetResource.Fields = SchemaBuilder.ToSchema(v.Settings);
|
||||||
|
|
||||||
return presetResource as ProviderResource;
|
return presetResource as ProviderResource;
|
||||||
}).ToList();
|
}).ToList();
|
||||||
@@ -173,23 +160,21 @@ namespace NzbDrone.Api
|
|||||||
|
|
||||||
private Response Test(TProviderResource providerResource)
|
private Response Test(TProviderResource providerResource)
|
||||||
{
|
{
|
||||||
// Don't validate when getting the definition so we can validate afterwards (avoids validation being skipped because the provider is disabled)
|
var providerDefinition = GetDefinition(providerResource, true);
|
||||||
var providerDefinition = GetDefinition(providerResource, true, false);
|
|
||||||
|
|
||||||
Validate(providerDefinition, true);
|
|
||||||
Test(providerDefinition, true);
|
Test(providerDefinition, true);
|
||||||
|
|
||||||
return "{}";
|
return "{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Response RequestAction(string action, TProviderResource providerResource)
|
private Response ConnectData(string stage, TProviderResource providerResource)
|
||||||
{
|
{
|
||||||
var providerDefinition = GetDefinition(providerResource, true, false);
|
TProviderDefinition providerDefinition = GetDefinition(providerResource, true, false);
|
||||||
|
|
||||||
var query = ((IDictionary<string, object>)Request.Query.ToDictionary()).ToDictionary(k => k.Key, k => k.Value.ToString());
|
if (!providerDefinition.Enable) return "{}";
|
||||||
|
|
||||||
var data = _providerFactory.RequestAction(providerDefinition, action, query);
|
object data = _providerFactory.ConnectData(providerDefinition, stage, (IDictionary<string, object>) Request.Query.ToDictionary());
|
||||||
Response resp = JsonConvert.SerializeObject(data);
|
Response resp = JsonConvert.SerializeObject(data);
|
||||||
resp.ContentType = "application/json";
|
resp.ContentType = "application/json";
|
||||||
return resp;
|
return resp;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Qualities
|
namespace NzbDrone.Api.Qualities
|
||||||
{
|
{
|
||||||
@@ -20,18 +21,18 @@ namespace NzbDrone.Api.Qualities
|
|||||||
|
|
||||||
private void Update(QualityDefinitionResource resource)
|
private void Update(QualityDefinitionResource resource)
|
||||||
{
|
{
|
||||||
var model = resource.ToModel();
|
var model = resource.InjectTo<QualityDefinition>();
|
||||||
_qualityDefinitionService.Update(model);
|
_qualityDefinitionService.Update(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
private QualityDefinitionResource GetById(int id)
|
private QualityDefinitionResource GetById(int id)
|
||||||
{
|
{
|
||||||
return _qualityDefinitionService.GetById(id).ToResource();
|
return _qualityDefinitionService.GetById(id).InjectTo<QualityDefinitionResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<QualityDefinitionResource> GetAll()
|
private List<QualityDefinitionResource> GetAll()
|
||||||
{
|
{
|
||||||
return _qualityDefinitionService.All().ToResource();
|
return ToListResource(_qualityDefinitionService.All);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
@@ -17,50 +15,4 @@ namespace NzbDrone.Api.Qualities
|
|||||||
public double? MinSize { get; set; }
|
public double? MinSize { get; set; }
|
||||||
public double? MaxSize { get; set; }
|
public double? MaxSize { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class QualityDefinitionResourceMapper
|
|
||||||
{
|
|
||||||
public static QualityDefinitionResource ToResource(this QualityDefinition model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new QualityDefinitionResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
Quality = model.Quality,
|
|
||||||
|
|
||||||
Title = model.Title,
|
|
||||||
|
|
||||||
Weight = model.Weight,
|
|
||||||
|
|
||||||
MinSize = model.MinSize,
|
|
||||||
MaxSize = model.MaxSize
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static QualityDefinition ToModel(this QualityDefinitionResource resource)
|
|
||||||
{
|
|
||||||
if (resource == null) return null;
|
|
||||||
|
|
||||||
return new QualityDefinition
|
|
||||||
{
|
|
||||||
Id = resource.Id,
|
|
||||||
|
|
||||||
Quality = resource.Quality,
|
|
||||||
|
|
||||||
Title = resource.Title,
|
|
||||||
|
|
||||||
Weight = resource.Weight,
|
|
||||||
|
|
||||||
MinSize = resource.MinSize,
|
|
||||||
MaxSize = resource.MaxSize
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<QualityDefinitionResource> ToResource(this IEnumerable<QualityDefinition> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ namespace NzbDrone.Api.Queue
|
|||||||
|
|
||||||
private List<QueueResource> GetQueue()
|
private List<QueueResource> GetQueue()
|
||||||
{
|
{
|
||||||
return GetQueueItems().ToResource();
|
return ToListResource(GetQueueItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<Core.Queue.Queue> GetQueueItems()
|
private IEnumerable<Core.Queue.Queue> GetQueueItems()
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using NzbDrone.Api.Series;
|
|||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Episodes;
|
||||||
using NzbDrone.Core.Download.TrackedDownloads;
|
using NzbDrone.Core.Download.TrackedDownloads;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Queue
|
namespace NzbDrone.Api.Queue
|
||||||
{
|
{
|
||||||
@@ -26,36 +25,4 @@ namespace NzbDrone.Api.Queue
|
|||||||
public string DownloadId { get; set; }
|
public string DownloadId { get; set; }
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class QueueResourceMapper
|
|
||||||
{
|
|
||||||
public static QueueResource ToResource(this Core.Queue.Queue model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new QueueResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
Series = model.Series.ToResource(),
|
|
||||||
Episode = model.Episode.ToResource(),
|
|
||||||
Quality = model.Quality,
|
|
||||||
Size = model.Size,
|
|
||||||
Title = model.Title,
|
|
||||||
Sizeleft = model.Sizeleft,
|
|
||||||
Timeleft = model.Timeleft,
|
|
||||||
EstimatedCompletionTime = model.EstimatedCompletionTime,
|
|
||||||
Status = model.Status,
|
|
||||||
TrackedDownloadStatus = model.TrackedDownloadStatus,
|
|
||||||
StatusMessages = model.StatusMessages,
|
|
||||||
DownloadId = model.DownloadId,
|
|
||||||
Protocol = model.Protocol
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<QueueResource> ToResource(this IEnumerable<Core.Queue.Queue> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.Validation.Paths;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Api.RemotePathMappings
|
namespace NzbDrone.Api.RemotePathMappings
|
||||||
{
|
{
|
||||||
@@ -37,19 +39,17 @@ namespace NzbDrone.Api.RemotePathMappings
|
|||||||
|
|
||||||
private RemotePathMappingResource GetMappingById(int id)
|
private RemotePathMappingResource GetMappingById(int id)
|
||||||
{
|
{
|
||||||
return _remotePathMappingService.Get(id).ToResource();
|
return _remotePathMappingService.Get(id).InjectTo<RemotePathMappingResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int CreateMapping(RemotePathMappingResource resource)
|
private int CreateMapping(RemotePathMappingResource rootFolderResource)
|
||||||
{
|
{
|
||||||
var model = resource.ToModel();
|
return GetNewId<RemotePathMapping>(_remotePathMappingService.Add, rootFolderResource);
|
||||||
|
|
||||||
return _remotePathMappingService.Add(model).Id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RemotePathMappingResource> GetMappings()
|
private List<RemotePathMappingResource> GetMappings()
|
||||||
{
|
{
|
||||||
return _remotePathMappingService.All().ToResource();
|
return ToListResource(_remotePathMappingService.All);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteMapping(int id)
|
private void DeleteMapping(int id)
|
||||||
@@ -59,7 +59,9 @@ namespace NzbDrone.Api.RemotePathMappings
|
|||||||
|
|
||||||
private void UpdateMapping(RemotePathMappingResource resource)
|
private void UpdateMapping(RemotePathMappingResource resource)
|
||||||
{
|
{
|
||||||
var mapping = resource.ToModel();
|
var mapping = _remotePathMappingService.Get(resource.Id);
|
||||||
|
|
||||||
|
mapping.InjectFrom(resource);
|
||||||
|
|
||||||
_remotePathMappingService.Update(mapping);
|
_remotePathMappingService.Update(mapping);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.RemotePathMappings
|
namespace NzbDrone.Api.RemotePathMappings
|
||||||
{
|
{
|
||||||
@@ -12,40 +9,4 @@ namespace NzbDrone.Api.RemotePathMappings
|
|||||||
public string RemotePath { get; set; }
|
public string RemotePath { get; set; }
|
||||||
public string LocalPath { get; set; }
|
public string LocalPath { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RemotePathMappingResourceMapper
|
|
||||||
{
|
|
||||||
public static RemotePathMappingResource ToResource(this RemotePathMapping model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new RemotePathMappingResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
Host = model.Host,
|
|
||||||
RemotePath = model.RemotePath,
|
|
||||||
LocalPath = model.LocalPath
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RemotePathMapping ToModel(this RemotePathMappingResource resource)
|
|
||||||
{
|
|
||||||
if (resource == null) return null;
|
|
||||||
|
|
||||||
return new RemotePathMapping
|
|
||||||
{
|
|
||||||
Id = resource.Id,
|
|
||||||
|
|
||||||
Host = resource.Host,
|
|
||||||
RemotePath = resource.RemotePath,
|
|
||||||
LocalPath = resource.LocalPath
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<RemotePathMappingResource> ToResource(this IEnumerable<RemotePathMapping> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Restrictions;
|
using NzbDrone.Core.Restrictions;
|
||||||
|
|
||||||
@@ -15,11 +16,11 @@ namespace NzbDrone.Api.Restrictions
|
|||||||
{
|
{
|
||||||
_restrictionService = restrictionService;
|
_restrictionService = restrictionService;
|
||||||
|
|
||||||
GetResourceById = GetRestriction;
|
GetResourceById = Get;
|
||||||
GetResourceAll = GetAllRestrictions;
|
GetResourceAll = GetAll;
|
||||||
CreateResource = CreateRestriction;
|
CreateResource = Create;
|
||||||
UpdateResource = UpdateRestriction;
|
UpdateResource = Update;
|
||||||
DeleteResource = DeleteRestriction;
|
DeleteResource = Delete;
|
||||||
|
|
||||||
SharedValidator.Custom(restriction =>
|
SharedValidator.Custom(restriction =>
|
||||||
{
|
{
|
||||||
@@ -32,27 +33,27 @@ namespace NzbDrone.Api.Restrictions
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private RestrictionResource GetRestriction(int id)
|
private RestrictionResource Get(int id)
|
||||||
{
|
{
|
||||||
return _restrictionService.Get(id).ToResource();
|
return _restrictionService.Get(id).InjectTo<RestrictionResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RestrictionResource> GetAllRestrictions()
|
private List<RestrictionResource> GetAll()
|
||||||
{
|
{
|
||||||
return _restrictionService.All().ToResource();
|
return ToListResource(_restrictionService.All);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int CreateRestriction(RestrictionResource resource)
|
private int Create(RestrictionResource resource)
|
||||||
{
|
{
|
||||||
return _restrictionService.Add(resource.ToModel()).Id;
|
return _restrictionService.Add(resource.InjectTo<Restriction>()).Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateRestriction(RestrictionResource resource)
|
private void Update(RestrictionResource resource)
|
||||||
{
|
{
|
||||||
_restrictionService.Update(resource.ToModel());
|
_restrictionService.Update(resource.InjectTo<Restriction>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteRestriction(int id)
|
private void Delete(int id)
|
||||||
{
|
{
|
||||||
_restrictionService.Delete(id);
|
_restrictionService.Delete(id);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user