Merge branch 'develop'
This commit is contained in:
commit
db690adadf
126
Gruntfile.js
126
Gruntfile.js
|
@ -105,69 +105,65 @@ module.exports = function (grunt) {
|
||||||
},
|
},
|
||||||
|
|
||||||
copy: {
|
copy: {
|
||||||
index : {
|
content: {
|
||||||
cwd : srcRoot,
|
cwd : srcRoot,
|
||||||
expand: true,
|
expand: true,
|
||||||
src : '*ndex.html',
|
src : [
|
||||||
|
'index.html',
|
||||||
|
'**/*.css',
|
||||||
|
'**/*.png',
|
||||||
|
'**/*.jpg',
|
||||||
|
'**/*.ico',
|
||||||
|
'**/FontAwesome/*.*',
|
||||||
|
'**/fonts/*.*'
|
||||||
|
],
|
||||||
dest : outputDir
|
dest : outputDir
|
||||||
},
|
},
|
||||||
scripts: {
|
scripts: {
|
||||||
cwd : srcRoot,
|
cwd : srcRoot,
|
||||||
expand: true,
|
expand: true,
|
||||||
src : '**/*.js',
|
src : [
|
||||||
dest : outputDir
|
'**/*.js',
|
||||||
},
|
],
|
||||||
styles : {
|
|
||||||
cwd : srcRoot,
|
|
||||||
expand: true,
|
|
||||||
src : '**/*.css',
|
|
||||||
dest : outputDir
|
|
||||||
},
|
|
||||||
images : {
|
|
||||||
cwd : srcRoot,
|
|
||||||
expand: true,
|
|
||||||
src : '**/*.png',
|
|
||||||
dest : outputDir
|
|
||||||
},
|
|
||||||
jpg : {
|
|
||||||
cwd : srcRoot,
|
|
||||||
expand: true,
|
|
||||||
src : '**/*.jpg',
|
|
||||||
dest : outputDir
|
|
||||||
},
|
|
||||||
icon : {
|
|
||||||
cwd : srcRoot,
|
|
||||||
expand: true,
|
|
||||||
src : '**/*.ico',
|
|
||||||
dest : outputDir
|
|
||||||
},
|
|
||||||
fontAwesome : {
|
|
||||||
cwd : srcRoot,
|
|
||||||
expand: true,
|
|
||||||
src : '**/FontAwesome/*.*',
|
|
||||||
dest : outputDir
|
|
||||||
},
|
|
||||||
fonts : {
|
|
||||||
cwd : srcRoot,
|
|
||||||
expand: true,
|
|
||||||
src : '**/fonts/*.*',
|
|
||||||
dest : outputDir
|
dest : outputDir
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
jshint: {
|
||||||
|
options: {
|
||||||
|
'-W030': false,
|
||||||
|
'-W064': false,
|
||||||
|
'-W097': false,
|
||||||
|
'-W100': false,
|
||||||
|
'undef': true,
|
||||||
|
'globals': {
|
||||||
|
'require': true,
|
||||||
|
'define': true,
|
||||||
|
'window': true,
|
||||||
|
'document': true,
|
||||||
|
'console': true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
all: [
|
||||||
|
srcRoot + '**/*.js',
|
||||||
|
'!**/JsLibraries/*.js'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
requirejs: {
|
requirejs: {
|
||||||
compile:{
|
compile:{
|
||||||
options: {
|
options: {
|
||||||
mainConfigFile: "_output/UI/app.js",
|
mainConfigFile: "src/UI/app.js",
|
||||||
fileExclusionRegExp: /^.*\.(?!js$)[^.]+$/,
|
fileExclusionRegExp: /^.*\.(?!js$)[^.]+$/,
|
||||||
preserveLicenseComments: true,
|
preserveLicenseComments: false,
|
||||||
dir: "rjs/",
|
dir: outputDir,
|
||||||
optimize: 'none',
|
optimize: 'none',
|
||||||
removeCombined: true,
|
removeCombined: true,
|
||||||
inlineText: false,
|
inlineText: false,
|
||||||
|
keepBuildDir : true,
|
||||||
modules: [{
|
modules: [{
|
||||||
name: 'app',
|
name: 'app',
|
||||||
exclude: ['JsLibraries/jquery']
|
exclude: ['JsLibraries/jquery', 'templates.js']
|
||||||
}],
|
}],
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -190,37 +186,21 @@ module.exports = function (grunt) {
|
||||||
files: '<%= handlebars.files.src %>',
|
files: '<%= handlebars.files.src %>',
|
||||||
tasks: ['handlebars']
|
tasks: ['handlebars']
|
||||||
},
|
},
|
||||||
copyIndex : {
|
content : {
|
||||||
files: '<%= copy.index.cwd %><%= copy.index.src %>',
|
files: [
|
||||||
tasks: ['copy:index']
|
'**/index.html',
|
||||||
|
'**/*.css',
|
||||||
|
'**/*.png',
|
||||||
|
'**/*.jpg',
|
||||||
|
'**/*.ico',
|
||||||
|
'**/FontAwesome/*.*',
|
||||||
|
'**/fonts/*.*'
|
||||||
|
],
|
||||||
|
tasks: ['copy:content']
|
||||||
},
|
},
|
||||||
copyScripts: {
|
scripts: {
|
||||||
files: '<%= copy.scripts.cwd %><%= copy.scripts.src %>',
|
files: '<%= copy.scripts.cwd %><%= copy.scripts.src %>',
|
||||||
tasks: ['copy:scripts']
|
tasks: ['copy:scripts']
|
||||||
},
|
|
||||||
copyStyles : {
|
|
||||||
files: '<%= copy.styles.cwd %><%= copy.styles.src %>',
|
|
||||||
tasks: ['copy:styles']
|
|
||||||
},
|
|
||||||
copyImages : {
|
|
||||||
files: '<%= copy.images.cwd %><%= copy.images.src %>',
|
|
||||||
tasks: ['copy:images']
|
|
||||||
},
|
|
||||||
copyJpg : {
|
|
||||||
files: '<%= copy.jpg.cwd %><%= copy.jpg.src %>',
|
|
||||||
tasks: ['copy:jpg']
|
|
||||||
},
|
|
||||||
copyIcon : {
|
|
||||||
files: '<%= copy.icon.cwd %><%= copy.icon.src %>',
|
|
||||||
tasks: ['copy:icon']
|
|
||||||
},
|
|
||||||
copyFontAwesome : {
|
|
||||||
files: '<%= copy.fontAwesome.cwd %><%= copy.fontAwesome.src %>',
|
|
||||||
tasks: ['copy:fontAwesome']
|
|
||||||
},
|
|
||||||
copyFonts : {
|
|
||||||
files: '<%= copy.fonts.cwd %><%= copy.fonts.src %>',
|
|
||||||
tasks: ['copy:fonts']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -233,8 +213,10 @@ module.exports = function (grunt) {
|
||||||
grunt.loadNpmTasks('grunt-notify');
|
grunt.loadNpmTasks('grunt-notify');
|
||||||
grunt.loadNpmTasks('grunt-curl');
|
grunt.loadNpmTasks('grunt-curl');
|
||||||
grunt.loadNpmTasks('grunt-contrib-requirejs');
|
grunt.loadNpmTasks('grunt-contrib-requirejs');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||||
|
|
||||||
grunt.registerTask('package', ['clean:output', 'copy', 'less', 'handlebars']);
|
grunt.registerTask('package', ['clean:output', 'jshint', 'handlebars', 'copy', 'less']);
|
||||||
|
grunt.registerTask('packagerjs', ['clean:output','jshint', 'handlebars', 'requirejs', 'copy:content', 'less']);
|
||||||
grunt.registerTask('default', ['package', 'watch']);
|
grunt.registerTask('default', ['package', 'watch']);
|
||||||
grunt.registerTask('update', ['curl']);
|
grunt.registerTask('update', ['curl']);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
|
15
build.ps1
15
build.ps1
|
@ -6,6 +6,8 @@ $testSearchPattern = '*.Test\bin\x86\Release'
|
||||||
|
|
||||||
Function Build()
|
Function Build()
|
||||||
{
|
{
|
||||||
|
Write-Host "##teamcity[progressStart 'Build']"
|
||||||
|
|
||||||
$clean = $msbuild + " src\nzbdrone.sln /t:Clean /m"
|
$clean = $msbuild + " src\nzbdrone.sln /t:Clean /m"
|
||||||
$build = $msbuild + " src\nzbdrone.sln /p:Configuration=Release /p:Platform=x86 /t:Build /m"
|
$build = $msbuild + " src\nzbdrone.sln /p:Configuration=Release /p:Platform=x86 /t:Build /m"
|
||||||
|
|
||||||
|
@ -23,6 +25,8 @@ Function Build()
|
||||||
CleanFolder $outputFolder
|
CleanFolder $outputFolder
|
||||||
|
|
||||||
AddJsonNet
|
AddJsonNet
|
||||||
|
|
||||||
|
Write-Host "##teamcity[progressFinish 'Build']"
|
||||||
}
|
}
|
||||||
|
|
||||||
Function CleanFolder($path)
|
Function CleanFolder($path)
|
||||||
|
@ -53,6 +57,8 @@ Function CleanFolder($path)
|
||||||
|
|
||||||
Function PackageMono()
|
Function PackageMono()
|
||||||
{
|
{
|
||||||
|
Write-Host "##teamcity[progressStart 'Creating Mono Package']"
|
||||||
|
|
||||||
if(Test-Path $outputFolderMono)
|
if(Test-Path $outputFolderMono)
|
||||||
{
|
{
|
||||||
Remove-Item -Recurse -Force $outputFolderMono -ErrorAction Continue
|
Remove-Item -Recurse -Force $outputFolderMono -ErrorAction Continue
|
||||||
|
@ -77,6 +83,8 @@ Function PackageMono()
|
||||||
Write-Host Renaming NzbDrone.Console.exe to NzbDrone.exe
|
Write-Host Renaming NzbDrone.Console.exe to NzbDrone.exe
|
||||||
get-childitem $outputFolderMono -File -Filter NzbDrone.exe -Recurse | foreach ($_) {remove-item $_.fullname}
|
get-childitem $outputFolderMono -File -Filter NzbDrone.exe -Recurse | foreach ($_) {remove-item $_.fullname}
|
||||||
Rename-Item "$outputFolderMono\NzbDrone.Console.exe" "NzbDrone.exe"
|
Rename-Item "$outputFolderMono\NzbDrone.Console.exe" "NzbDrone.exe"
|
||||||
|
|
||||||
|
Write-Host "##teamcity[progressFinish 'Creating Mono Package']"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,7 +97,9 @@ Function AddJsonNet()
|
||||||
|
|
||||||
Function PackageTests()
|
Function PackageTests()
|
||||||
{
|
{
|
||||||
|
|
||||||
Write-Host Packaging Tests
|
Write-Host Packaging Tests
|
||||||
|
Write-Host "##teamcity[progressStart 'Creating Mono Package']"
|
||||||
|
|
||||||
if(Test-Path $testPackageFolder)
|
if(Test-Path $testPackageFolder)
|
||||||
{
|
{
|
||||||
|
@ -111,17 +121,22 @@ Function PackageTests()
|
||||||
get-childitem $testPackageFolder -File -Filter *log.config | foreach ($_) {remove-item $_.fullname}
|
get-childitem $testPackageFolder -File -Filter *log.config | foreach ($_) {remove-item $_.fullname}
|
||||||
|
|
||||||
CleanFolder $testPackageFolder
|
CleanFolder $testPackageFolder
|
||||||
|
|
||||||
|
Write-Host "##teamcity[progressFinish 'Creating Mono Package']"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Function RunGrunt()
|
Function RunGrunt()
|
||||||
{
|
{
|
||||||
|
Write-Host "##teamcity[progressStart 'Running Grunt']"
|
||||||
$gruntPath = [environment]::getfolderpath("applicationdata") + '\npm\node_modules\grunt-cli\bin\grunt'
|
$gruntPath = [environment]::getfolderpath("applicationdata") + '\npm\node_modules\grunt-cli\bin\grunt'
|
||||||
Invoke-Expression 'npm install'
|
Invoke-Expression 'npm install'
|
||||||
CheckExitCode
|
CheckExitCode
|
||||||
|
|
||||||
Invoke-Expression ('node ' + $gruntPath + ' package')
|
Invoke-Expression ('node ' + $gruntPath + ' package')
|
||||||
CheckExitCode
|
CheckExitCode
|
||||||
|
|
||||||
|
Write-Host "##teamcity[progressFinish 'Running Grunt']"
|
||||||
}
|
}
|
||||||
|
|
||||||
Function CheckExitCode()
|
Function CheckExitCode()
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"grunt-curl": "*",
|
"grunt-curl": "*",
|
||||||
"grunt-notify": "*",
|
"grunt-notify": "*",
|
||||||
"grunt-contrib-clean": "*",
|
"grunt-contrib-clean": "*",
|
||||||
"grunt-contrib-requirejs": "*"
|
"grunt-contrib-requirejs": "*",
|
||||||
|
"grunt-contrib-jshint": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -3,37 +3,61 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
|
||||||
|
|
||||||
|
<!-- Enable the restore command to run before builds -->
|
||||||
|
<RestorePackages Condition=" '$(RestorePackages)' == '' ">false</RestorePackages>
|
||||||
|
|
||||||
|
<!-- Property that enables building a package from a project -->
|
||||||
|
<BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
|
||||||
|
|
||||||
|
<!-- Determines if package restore consent is required to restore packages -->
|
||||||
|
<RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
|
||||||
|
|
||||||
|
<!-- Download NuGet.exe if it does not already exist -->
|
||||||
|
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition=" '$(PackageSources)' == '' ">
|
||||||
|
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
|
||||||
|
<!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
|
||||||
|
<!--
|
||||||
|
<PackageSource Include="https://www.nuget.org/api/v2/" />
|
||||||
|
<PackageSource Include="https://my-nuget-source/nuget/" />
|
||||||
|
-->
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
|
||||||
<!-- Windows specific commands -->
|
<!-- Windows specific commands -->
|
||||||
<NuGetToolsPath Condition=" '$(OS)' == 'Windows_NT'">$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
|
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
|
||||||
<PackagesConfig Condition=" '$(OS)' == 'Windows_NT'">$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
|
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
|
||||||
<PackagesDir Condition=" '$(OS)' == 'Windows_NT'">$([System.IO.Path]::Combine($(SolutionDir), "packages"))</PackagesDir>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
|
||||||
<!-- We need to launch nuget.exe with the mono command if we're not on windows -->
|
<!-- We need to launch nuget.exe with the mono command if we're not on windows -->
|
||||||
<NuGetToolsPath Condition=" '$(OS)' != 'Windows_NT'">$(SolutionDir).nuget</NuGetToolsPath>
|
<NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
|
||||||
<PackagesConfig Condition=" '$(OS)' != 'Windows_NT' ">packages.config</PackagesConfig>
|
<PackagesConfig>packages.config</PackagesConfig>
|
||||||
<PackagesDir Condition=" '$(OS)' != 'Windows_NT'">$(SolutionDir)packages</PackagesDir>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
<!-- NuGet command -->
|
<!-- NuGet command -->
|
||||||
<NuGetExePath>$(NuGetToolsPath)\nuget.exe</NuGetExePath>
|
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
|
||||||
|
<PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
|
||||||
|
|
||||||
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
|
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
|
||||||
<NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>
|
<NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>
|
||||||
|
|
||||||
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
|
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
|
||||||
|
|
||||||
<!-- Package sources used to restore packages. By default will used the registered sources under %APPDATA%\NuGet\NuGet.Config -->
|
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
|
||||||
<PackageSources>"http://build.nzbdrone.com/guestAuth/app/nuget/v1/FeedService.svc";"https://nuget.org/api/v2/"</PackageSources>
|
<NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
|
||||||
|
|
||||||
<!-- Enable the restore command to run before builds -->
|
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
|
||||||
<RestorePackages Condition="$(RestorePackages) == ''">false</RestorePackages>
|
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
|
||||||
|
|
||||||
<!-- Property that enables building a package from a project -->
|
|
||||||
<BuildPackage Condition="$(BuildPackage) == ''">false</BuildPackage>
|
|
||||||
|
|
||||||
<!-- Commands -->
|
<!-- Commands -->
|
||||||
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source $(PackageSources) -o "$(PackagesDir)"</RestoreCommand>
|
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
|
||||||
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols</BuildCommand>
|
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
|
||||||
|
|
||||||
<!-- Make the build depend on restore packages -->
|
<!-- We need to ensure packages are restored prior to assembly resolve -->
|
||||||
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
|
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
|
||||||
RestorePackages;
|
RestorePackages;
|
||||||
$(BuildDependsOn);
|
$(BuildDependsOn);
|
||||||
|
@ -48,7 +72,17 @@
|
||||||
|
|
||||||
<Target Name="CheckPrerequisites">
|
<Target Name="CheckPrerequisites">
|
||||||
<!-- Raise an error if we're unable to locate nuget.exe -->
|
<!-- Raise an error if we're unable to locate nuget.exe -->
|
||||||
<Error Condition="!Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
|
<Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
|
||||||
|
<!--
|
||||||
|
Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
|
||||||
|
This effectively acts as a lock that makes sure that the download operation will only happen once and all
|
||||||
|
parallel builds will have to wait for it to complete.
|
||||||
|
-->
|
||||||
|
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="_DownloadNuGet">
|
||||||
|
<DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
|
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
|
||||||
|
@ -68,4 +102,35 @@
|
||||||
LogStandardErrorAsError="true"
|
LogStandardErrorAsError="true"
|
||||||
Condition=" '$(OS)' == 'Windows_NT' " />
|
Condition=" '$(OS)' == 'Windows_NT' " />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||||
|
<ParameterGroup>
|
||||||
|
<OutputFilename ParameterType="System.String" Required="true" />
|
||||||
|
</ParameterGroup>
|
||||||
|
<Task>
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Using Namespace="System" />
|
||||||
|
<Using Namespace="System.IO" />
|
||||||
|
<Using Namespace="System.Net" />
|
||||||
|
<Using Namespace="Microsoft.Build.Framework" />
|
||||||
|
<Using Namespace="Microsoft.Build.Utilities" />
|
||||||
|
<Code Type="Fragment" Language="cs">
|
||||||
|
<![CDATA[
|
||||||
|
try {
|
||||||
|
OutputFilename = Path.GetFullPath(OutputFilename);
|
||||||
|
|
||||||
|
Log.LogMessage("Downloading latest version of NuGet.exe...");
|
||||||
|
WebClient webClient = new WebClient();
|
||||||
|
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Log.LogErrorFromException(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</Code>
|
||||||
|
</Task>
|
||||||
|
</UsingTask>
|
||||||
</Project>
|
</Project>
|
|
@ -17,11 +17,10 @@ namespace NzbDrone.Api.ErrorManagement
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response HandleException(NancyContext context, Exception aggregateException)
|
public Response HandleException(NancyContext context, Exception exception)
|
||||||
{
|
{
|
||||||
var innerException = (aggregateException.InnerException).InnerException;
|
|
||||||
|
|
||||||
var apiException = innerException as ApiException;
|
var apiException = exception as ApiException;
|
||||||
|
|
||||||
if (apiException != null)
|
if (apiException != null)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +28,7 @@ namespace NzbDrone.Api.ErrorManagement
|
||||||
return apiException.ToErrorResponse();
|
return apiException.ToErrorResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
var validationException = innerException as ValidationException;
|
var validationException = exception as ValidationException;
|
||||||
|
|
||||||
if (validationException != null)
|
if (validationException != null)
|
||||||
{
|
{
|
||||||
|
@ -38,23 +37,23 @@ namespace NzbDrone.Api.ErrorManagement
|
||||||
return validationException.Errors.AsResponse(HttpStatusCode.BadRequest);
|
return validationException.Errors.AsResponse(HttpStatusCode.BadRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientException = innerException as NzbDroneClientException;
|
var clientException = exception as NzbDroneClientException;
|
||||||
|
|
||||||
if (clientException != null)
|
if (clientException != null)
|
||||||
{
|
{
|
||||||
return new ErrorModel
|
return new ErrorModel
|
||||||
{
|
{
|
||||||
Message = innerException.Message,
|
Message = exception.Message,
|
||||||
Description = innerException.ToString()
|
Description = exception.ToString()
|
||||||
}.AsResponse((HttpStatusCode)clientException.StatusCode);
|
}.AsResponse((HttpStatusCode)clientException.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.FatalException("Request Failed", innerException);
|
_logger.FatalException("Request Failed", exception);
|
||||||
|
|
||||||
return new ErrorModel
|
return new ErrorModel
|
||||||
{
|
{
|
||||||
Message = innerException.Message,
|
Message = exception.Message,
|
||||||
Description = innerException.ToString()
|
Description = exception.ToString()
|
||||||
}.AsResponse(HttpStatusCode.InternalServerError);
|
}.AsResponse(HttpStatusCode.InternalServerError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Nancy;
|
using Nancy;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Extensions
|
namespace NzbDrone.Api.Extensions
|
||||||
|
|
|
@ -19,7 +19,6 @@ namespace NzbDrone.Api.Mapping
|
||||||
source.GetType().GetGenericTypeDefinition() != null &&
|
source.GetType().GetGenericTypeDefinition() != null &&
|
||||||
source.GetType().GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable)))
|
source.GetType().GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable)))
|
||||||
{
|
{
|
||||||
|
|
||||||
var result = new TTarget();
|
var result = new TTarget();
|
||||||
|
|
||||||
var listSubType = targetType.GetGenericArguments()[0];
|
var listSubType = targetType.GetGenericArguments()[0];
|
||||||
|
|
|
@ -38,29 +38,29 @@
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="FluentValidation, Version=4.0.0.1, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="FluentValidation, Version=5.0.0.1, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\FluentValidation.4.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
|
<HintPath>..\packages\FluentValidation.5.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.AspNet.SignalR.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.AspNet.SignalR.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Microsoft.AspNet.SignalR.Core.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Core.dll</HintPath>
|
<HintPath>..\packages\Microsoft.AspNet.SignalR.Core.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Core.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Nancy, Version=0.20.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Nancy, Version=0.21.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Nancy.0.20.0\lib\net40\Nancy.dll</HintPath>
|
<HintPath>..\packages\Nancy.0.21.1\lib\net40\Nancy.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Nancy.Authentication.Basic, Version=0.20.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Nancy.Authentication.Basic, Version=0.21.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Nancy.Authentication.Basic.0.20.0\lib\net40\Nancy.Authentication.Basic.dll</HintPath>
|
<HintPath>..\packages\Nancy.Authentication.Basic.0.21.1\lib\net40\Nancy.Authentication.Basic.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Omu.ValueInjecter">
|
<Reference Include="Omu.ValueInjecter">
|
||||||
<HintPath>..\packages\ValueInjecter.2.3.3\lib\net35\Omu.ValueInjecter.dll</HintPath>
|
<HintPath>..\packages\ValueInjecter.2.3.3\lib\net35\Omu.ValueInjecter.dll</HintPath>
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.RootFolders;
|
using NzbDrone.Core.RootFolders;
|
||||||
using NzbDrone.Api.Mapping;
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Api.Validation;
|
using NzbDrone.Api.Validation;
|
||||||
|
|
||||||
namespace NzbDrone.Api.RootFolders
|
namespace NzbDrone.Api.RootFolders
|
||||||
{
|
{
|
||||||
public class RootFolderModule : NzbDroneRestModule<RootFolderResource>
|
public class RootFolderModule : NzbDroneRestModuleWithSignalR<RootFolderResource, RootFolder>
|
||||||
{
|
{
|
||||||
private readonly IRootFolderService _rootFolderService;
|
private readonly IRootFolderService _rootFolderService;
|
||||||
|
|
||||||
public RootFolderModule(IRootFolderService rootFolderService)
|
public RootFolderModule(IRootFolderService rootFolderService, ICommandExecutor commandExecutor)
|
||||||
|
: base(commandExecutor)
|
||||||
{
|
{
|
||||||
_rootFolderService = rootFolderService;
|
_rootFolderService = rootFolderService;
|
||||||
|
|
||||||
|
@ -18,7 +20,7 @@ namespace NzbDrone.Api.RootFolders
|
||||||
CreateResource = CreateRootFolder;
|
CreateResource = CreateRootFolder;
|
||||||
DeleteResource = DeleteFolder;
|
DeleteResource = DeleteFolder;
|
||||||
|
|
||||||
SharedValidator.RuleFor(c=>c.Path).IsValidPath();
|
SharedValidator.RuleFor(c => c.Path).IsValidPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
private RootFolderResource GetRootFolder(int id)
|
private RootFolderResource GetRootFolder(int id)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="FluentValidation" version="4.0.0.1" targetFramework="net40" />
|
<package id="FluentValidation" version="5.0.0.1" targetFramework="net40" />
|
||||||
<package id="Microsoft.AspNet.SignalR.Core" version="1.1.3" targetFramework="net40" />
|
<package id="Microsoft.AspNet.SignalR.Core" version="1.1.3" targetFramework="net40" />
|
||||||
<package id="Nancy" version="0.20.0" targetFramework="net40" />
|
<package id="Nancy" version="0.21.1" targetFramework="net40" />
|
||||||
<package id="Nancy.Authentication.Basic" version="0.20.0" targetFramework="net40" />
|
<package id="Nancy.Authentication.Basic" version="0.21.1" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="ValueInjecter" version="2.3.3" targetFramework="net40" />
|
<package id="ValueInjecter" version="2.3.3" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -44,9 +44,9 @@
|
||||||
<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="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
||||||
<package id="Moq" version="4.0.10827" />
|
<package id="Moq" version="4.0.10827" />
|
||||||
<package id="NBuilder" version="3.0.1.1" />
|
<package id="NBuilder" version="3.0.1.1" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -0,0 +1,76 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NLog;
|
||||||
|
using NLog.Config;
|
||||||
|
using NLog.Targets;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Automation.Test.PageModel;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using OpenQA.Selenium;
|
||||||
|
using OpenQA.Selenium.Firefox;
|
||||||
|
using OpenQA.Selenium.IE;
|
||||||
|
using OpenQA.Selenium.Remote;
|
||||||
|
using OpenQA.Selenium.Support.UI;
|
||||||
|
|
||||||
|
namespace NzbDrone.Automation.Test
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
[AutomationTest]
|
||||||
|
public abstract class AutomationTest
|
||||||
|
{
|
||||||
|
private NzbDroneRunner _runner;
|
||||||
|
protected RemoteWebDriver driver;
|
||||||
|
|
||||||
|
public AutomationTest()
|
||||||
|
{
|
||||||
|
new StartupArguments();
|
||||||
|
|
||||||
|
LogManager.Configuration = new LoggingConfiguration();
|
||||||
|
var consoleTarget = new ConsoleTarget { Layout = "${level}: ${message} ${exception}" };
|
||||||
|
LogManager.Configuration.AddTarget(consoleTarget.GetType().Name, consoleTarget);
|
||||||
|
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, consoleTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public void SmokeTestSetup()
|
||||||
|
{
|
||||||
|
driver = new FirefoxDriver();
|
||||||
|
|
||||||
|
_runner = new NzbDroneRunner();
|
||||||
|
_runner.KillAll();
|
||||||
|
_runner.Start();
|
||||||
|
|
||||||
|
|
||||||
|
driver.Url = "http://localhost:8989";
|
||||||
|
|
||||||
|
var page = new PageBase(driver);
|
||||||
|
page.WaitForNoSpinner();
|
||||||
|
|
||||||
|
GetPageErrors().Should().BeEmpty();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<string> GetPageErrors()
|
||||||
|
{
|
||||||
|
return driver.FindElements(By.CssSelector("#errors div"))
|
||||||
|
.Select(e => e.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestFixtureTearDown]
|
||||||
|
public void SmokeTestTearDown()
|
||||||
|
{
|
||||||
|
_runner.KillAll();
|
||||||
|
driver.Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void AutomationTearDown()
|
||||||
|
{
|
||||||
|
GetPageErrors().Should().BeEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Automation.Test
|
||||||
|
{
|
||||||
|
public class AutomationTestAttribute : CategoryAttribute
|
||||||
|
{
|
||||||
|
public AutomationTestAttribute()
|
||||||
|
: base("AutomationTest")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Automation.Test.PageModel;
|
||||||
|
using OpenQA.Selenium;
|
||||||
|
|
||||||
|
namespace NzbDrone.Automation.Test
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class MainPagesTest : AutomationTest
|
||||||
|
{
|
||||||
|
private PageBase page;
|
||||||
|
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
page = new PageBase(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void series_page()
|
||||||
|
{
|
||||||
|
page.SeriesNavIcon.Click();
|
||||||
|
page.WaitForNoSpinner();
|
||||||
|
page.FindByClass("iv-series-index-seriesindexlayout").Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void calendar_page()
|
||||||
|
{
|
||||||
|
page.CalendarNavIcon.Click();
|
||||||
|
page.WaitForNoSpinner();
|
||||||
|
|
||||||
|
page.FindByClass("iv-calendar-calendarlayout").Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void history_page()
|
||||||
|
{
|
||||||
|
page.HistoryNavIcon.Click();
|
||||||
|
page.WaitForNoSpinner();
|
||||||
|
|
||||||
|
page.FindByClass("iv-history-historylayout").Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void missing_page()
|
||||||
|
{
|
||||||
|
page.MissingNavIcon.Click();
|
||||||
|
page.WaitForNoSpinner();
|
||||||
|
|
||||||
|
page.FindByClass("iv-missing-missinglayout").Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void system_page()
|
||||||
|
{
|
||||||
|
page.SystemNavIcon.Click();
|
||||||
|
page.WaitForNoSpinner();
|
||||||
|
|
||||||
|
page.FindByClass("iv-system-systemlayout").Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void add_series_page()
|
||||||
|
{
|
||||||
|
page.SeriesNavIcon.Click();
|
||||||
|
page.WaitForNoSpinner();
|
||||||
|
|
||||||
|
page.Find(By.LinkText("Add Series")).Click();
|
||||||
|
|
||||||
|
page.WaitForNoSpinner();
|
||||||
|
|
||||||
|
page.FindByClass("iv-addseries-addserieslayout").Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{CC26800D-F67E-464B-88DE-8EB1A0C227A3}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>NzbDrone.Automation.Test</RootNamespace>
|
||||||
|
<AssemblyName>NzbDrone.Automation.Test</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||||
|
<RestorePackages>true</RestorePackages>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="FluentAssertions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\FluentAssertions.2.1.0.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="NLog">
|
||||||
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="nunit.framework">
|
||||||
|
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WebDriver">
|
||||||
|
<HintPath>..\packages\Selenium.WebDriver.2.37.0\lib\net40\WebDriver.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="WebDriver.Support">
|
||||||
|
<HintPath>..\packages\Selenium.Support.2.37.0\lib\net40\WebDriver.Support.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="AutomationTestAttribute.cs" />
|
||||||
|
<Compile Include="AutomationTest.cs" />
|
||||||
|
<Compile Include="MainPagesTest.cs" />
|
||||||
|
<Compile Include="PageModel\PageBase.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
|
||||||
|
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
|
||||||
|
<Name>NzbDrone.Common</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
|
||||||
|
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
|
||||||
|
<Name>NzbDrone.Test.Common</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
|
@ -0,0 +1,100 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using OpenQA.Selenium;
|
||||||
|
using OpenQA.Selenium.Remote;
|
||||||
|
using OpenQA.Selenium.Support.UI;
|
||||||
|
|
||||||
|
namespace NzbDrone.Automation.Test.PageModel
|
||||||
|
{
|
||||||
|
public class PageBase
|
||||||
|
{
|
||||||
|
private readonly RemoteWebDriver _driver;
|
||||||
|
|
||||||
|
public PageBase(RemoteWebDriver driver)
|
||||||
|
{
|
||||||
|
_driver = driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWebElement FindByClass(string className, int timeout = 5)
|
||||||
|
{
|
||||||
|
return Find(By.ClassName(className), timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWebElement Find(By by, int timeout = 5)
|
||||||
|
{
|
||||||
|
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(timeout));
|
||||||
|
return wait.Until(d => d.FindElement(by));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void WaitForNoSpinner(int timeout = 20)
|
||||||
|
{
|
||||||
|
//give the spinner some time to show up.
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(timeout));
|
||||||
|
wait.Until(d =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IWebElement element = d.FindElement(By.Id("followingBalls"));
|
||||||
|
return !element.Displayed;
|
||||||
|
}
|
||||||
|
catch (NoSuchElementException)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IWebElement SeriesNavIcon
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Find(By.LinkText("Series"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWebElement CalendarNavIcon
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Find(By.LinkText("Calendar"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWebElement HistoryNavIcon
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Find(By.LinkText("History"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWebElement MissingNavIcon
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Find(By.LinkText("Missing"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWebElement SettingNavIcon
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Find(By.LinkText("Settings"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWebElement SystemNavIcon
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Find(By.LinkText("System"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("NzbDrone.Automation.Test")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("NzbDrone.Automation.Test")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("6b8945f5-f5b5-4729-865d-f958fbd673d9")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
||||||
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
|
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
||||||
|
<package id="Selenium.Support" version="2.37.0" targetFramework="net40" />
|
||||||
|
<package id="Selenium.WebDriver" version="2.37.0" targetFramework="net40" />
|
||||||
|
</packages>
|
|
@ -155,10 +155,14 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
||||||
[Test]
|
[Test]
|
||||||
public void folder_should_return_correct_value_for_last_write()
|
public void folder_should_return_correct_value_for_last_write()
|
||||||
{
|
{
|
||||||
var testFile = GetTestFilePath();
|
var testDir = Path.Combine(SandboxFolder, "LastWrite");
|
||||||
|
var testFile = Path.Combine(testDir, Path.GetRandomFileName());
|
||||||
|
|
||||||
|
Directory.CreateDirectory(testDir);
|
||||||
|
|
||||||
TestLogger.Info("Path is: {0}", testFile);
|
TestLogger.Info("Path is: {0}", testFile);
|
||||||
|
|
||||||
|
|
||||||
Subject.WriteAllText(testFile, "Test");
|
Subject.WriteAllText(testFile, "Test");
|
||||||
|
|
||||||
Subject.GetLastFolderWrite(SandboxFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1));
|
Subject.GetLastFolderWrite(SandboxFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1));
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
<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="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
<packages>
|
<packages>
|
||||||
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
||||||
<package id="Moq" version="4.0.10827" />
|
<package id="Moq" version="4.0.10827" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -301,27 +301,18 @@ namespace NzbDrone.Common
|
||||||
|
|
||||||
if (OsInfo.IsLinux)
|
if (OsInfo.IsLinux)
|
||||||
{
|
{
|
||||||
var drives = DriveInfo.GetDrives();
|
try
|
||||||
|
|
||||||
foreach (var drive in drives)
|
|
||||||
{
|
{
|
||||||
try
|
return GetDriveInfoLinux(path).AvailableFreeSpace;
|
||||||
{
|
}
|
||||||
if (drive.IsReady && path.StartsWith(drive.Name, StringComparison.CurrentCultureIgnoreCase))
|
catch (InvalidOperationException e)
|
||||||
{
|
{
|
||||||
return drive.AvailableFreeSpace;
|
Logger.ErrorException("Couldn't get free space for " + path, e);
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InvalidOperationException e)
|
|
||||||
{
|
|
||||||
Logger.ErrorException("Couldn't get free space for " + path, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return DriveFreeSpaceEx(root);
|
return DriveFreeSpaceEx(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,27 +462,18 @@ namespace NzbDrone.Common
|
||||||
|
|
||||||
if (OsInfo.IsLinux)
|
if (OsInfo.IsLinux)
|
||||||
{
|
{
|
||||||
var drives = DriveInfo.GetDrives();
|
try
|
||||||
|
|
||||||
foreach (var drive in drives)
|
|
||||||
{
|
{
|
||||||
try
|
return GetDriveInfoLinux(path).TotalSize;
|
||||||
{
|
}
|
||||||
if (drive.IsReady && path.StartsWith(drive.Name, StringComparison.CurrentCultureIgnoreCase))
|
catch (InvalidOperationException e)
|
||||||
{
|
{
|
||||||
return drive.TotalSize;
|
Logger.ErrorException("Couldn't get total space for " + path, e);
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InvalidOperationException e)
|
|
||||||
{
|
|
||||||
Logger.ErrorException("Couldn't get total space for " + path, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return DriveTotalSizeEx(root);
|
return DriveTotalSizeEx(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,5 +536,16 @@ namespace NzbDrone.Common
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DriveInfo GetDriveInfoLinux(string path)
|
||||||
|
{
|
||||||
|
var drives = DriveInfo.GetDrives();
|
||||||
|
|
||||||
|
return
|
||||||
|
drives.Where(drive =>
|
||||||
|
drive.IsReady && path.StartsWith(drive.Name, StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
.OrderByDescending(drive => drive.Name.Length)
|
||||||
|
.First();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -92,7 +92,6 @@ namespace NzbDrone.Common.EnsureThat
|
||||||
throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid relative path. relative paths can not start with \\", param.Value));
|
throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid relative path. relative paths can not start with \\", param.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return param;
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,11 +46,11 @@
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Configuration" />
|
<Reference Include="System.Configuration" />
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="loggly-csharp" version="2.3" targetFramework="net40" />
|
<package id="loggly-csharp" version="2.3" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
|
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -81,11 +81,11 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<package id="Microsoft.AspNet.SignalR.Owin" version="1.1.3" targetFramework="net40" />
|
<package id="Microsoft.AspNet.SignalR.Owin" version="1.1.3" targetFramework="net40" />
|
||||||
<package id="Microsoft.Owin" version="1.1.0-beta2" targetFramework="net40" />
|
<package id="Microsoft.Owin" version="1.1.0-beta2" targetFramework="net40" />
|
||||||
<package id="Microsoft.Owin.Hosting" version="1.1.0-beta2" targetFramework="net40" />
|
<package id="Microsoft.Owin.Hosting" version="1.1.0-beta2" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="Owin" version="1.0" targetFramework="net40" />
|
<package id="Owin" version="1.0" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -0,0 +1,37 @@
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Housekeeping.Housekeepers;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CleanupAdditionalNamingSpecsFixture : DbTest<CleanupAdditionalNamingSpecs, NamingConfig>
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_delete_additional_naming_configs()
|
||||||
|
{
|
||||||
|
var specs = Builder<NamingConfig>.CreateListOfSize(5)
|
||||||
|
.BuildListOfNew();
|
||||||
|
|
||||||
|
Db.InsertMany(specs);
|
||||||
|
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Should().HaveCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_delete_if_only_one_spec()
|
||||||
|
{
|
||||||
|
var spec = Builder<NamingConfig>.CreateNew()
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(spec);
|
||||||
|
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Should().HaveCount(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -124,7 +124,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
imported.Add(new ImportDecision(localEpisode));
|
imported.Add(new ImportDecision(localEpisode));
|
||||||
|
|
||||||
Mocker.GetMock<IMakeImportDecision>()
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
.Setup(s => s.GetImportDecisions(It.IsAny<IEnumerable<String>>(), It.IsAny<Series>(), true))
|
.Setup(s => s.GetImportDecisions(It.IsAny<IEnumerable<String>>(), It.IsAny<Series>(), true, null))
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>()
|
Mocker.GetMock<IImportApprovedEpisodes>()
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
@ -21,6 +22,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
private List<string> _videoFiles;
|
private List<string> _videoFiles;
|
||||||
private LocalEpisode _localEpisode;
|
private LocalEpisode _localEpisode;
|
||||||
private Series _series;
|
private Series _series;
|
||||||
|
private QualityModel _quality;
|
||||||
|
|
||||||
private Mock<IImportDecisionEngineSpecification> _pass1;
|
private Mock<IImportDecisionEngineSpecification> _pass1;
|
||||||
private Mock<IImportDecisionEngineSpecification> _pass2;
|
private Mock<IImportDecisionEngineSpecification> _pass2;
|
||||||
|
@ -62,7 +64,13 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
_videoFiles = new List<string> { @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi" };
|
_videoFiles = new List<string> { @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi" };
|
||||||
_series = new Series();
|
_series = new Series();
|
||||||
_localEpisode = new LocalEpisode { Series = _series, Path = @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi" };
|
_quality = new QualityModel(Quality.DVD);
|
||||||
|
_localEpisode = new LocalEpisode
|
||||||
|
{
|
||||||
|
Series = _series,
|
||||||
|
Quality = _quality,
|
||||||
|
Path = @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi"
|
||||||
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Setup(c => c.GetEpisodes(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()))
|
.Setup(c => c.GetEpisodes(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()))
|
||||||
|
@ -161,5 +169,38 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
ExceptionVerification.ExpectedErrors(3);
|
ExceptionVerification.ExpectedErrors(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_file_quality_if_folder_quality_is_null()
|
||||||
|
{
|
||||||
|
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||||
|
var expectedQuality = QualityParser.ParseQuality(_videoFiles.Single());
|
||||||
|
|
||||||
|
var result = Subject.GetImportDecisions(_videoFiles, new Series(), false, null);
|
||||||
|
|
||||||
|
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_file_quality_if_folder_quality_is_lower_than_file_quality()
|
||||||
|
{
|
||||||
|
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||||
|
var expectedQuality = QualityParser.ParseQuality(_videoFiles.Single());
|
||||||
|
|
||||||
|
var result = Subject.GetImportDecisions(_videoFiles, new Series(), false, new QualityModel(Quality.SDTV));
|
||||||
|
|
||||||
|
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_folder_quality_when_it_is_greater_than_file_quality()
|
||||||
|
{
|
||||||
|
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||||
|
var expectedQuality = new QualityModel(Quality.Bluray1080p);
|
||||||
|
|
||||||
|
var result = Subject.GetImportDecisions(_videoFiles, new Series(), false, expectedQuality);
|
||||||
|
|
||||||
|
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,13 +46,14 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
Series = series,
|
Series = series,
|
||||||
Episodes = new List<Episode> {episode},
|
Episodes = new List<Episode> {episode},
|
||||||
Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilit.avi".AsOsAgnostic(),
|
Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilot.avi".AsOsAgnostic(),
|
||||||
Quality = new QualityModel(Quality.Bluray720p)
|
Quality = new QualityModel(Quality.Bluray720p)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Mocker.GetMock<IUpgradeMediaFiles>()
|
Mocker.GetMock<IUpgradeMediaFiles>()
|
||||||
.Setup(s => s.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>()));
|
.Setup(s => s.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>()))
|
||||||
|
.Returns(new EpisodeFileMoveResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
using Marr.Data;
|
using Marr.Data;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
@ -149,5 +150,21 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Never());
|
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_old_episode_file_in_oldFiles()
|
||||||
|
{
|
||||||
|
GivenSingleEpisodeWithSingleEpisodeFile();
|
||||||
|
|
||||||
|
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode).OldFiles.Count.Should().Be(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_old_episode_files_in_oldFiles()
|
||||||
|
{
|
||||||
|
GivenMultipleEpisodesWithMultipleEpisodeFiles();
|
||||||
|
|
||||||
|
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode).OldFiles.Count.Should().Be(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.Notifications;
|
||||||
|
using NzbDrone.Core.Notifications.Xbmc;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class OnDownloadFixture : CoreTest<Notifications.Xbmc.Xbmc>
|
||||||
|
{
|
||||||
|
private DownloadMessage _downloadMessage;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
var series = Builder<Series>.CreateNew()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_downloadMessage = Builder<DownloadMessage>.CreateNew()
|
||||||
|
.With(d => d.Series = series)
|
||||||
|
.With(d => d.EpisodeFile = episodeFile)
|
||||||
|
.With(d => d.OldFiles = new List<EpisodeFile>())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Subject.Definition = new NotificationDefinition();
|
||||||
|
Subject.Definition.Settings = new XbmcSettings
|
||||||
|
{
|
||||||
|
UpdateLibrary = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenOldFiles()
|
||||||
|
{
|
||||||
|
_downloadMessage.OldFiles = Builder<EpisodeFile>.CreateListOfSize(1)
|
||||||
|
.Build()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Subject.Definition.Settings = new XbmcSettings
|
||||||
|
{
|
||||||
|
UpdateLibrary = true,
|
||||||
|
CleanLibrary = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_clean_if_no_episode_was_replaced()
|
||||||
|
{
|
||||||
|
Subject.OnDownload(_downloadMessage);
|
||||||
|
|
||||||
|
Mocker.GetMock<IXbmcService>().Verify(v => v.Clean(It.IsAny<XbmcSettings>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_clean_if_episode_was_replaced()
|
||||||
|
{
|
||||||
|
GivenOldFiles();
|
||||||
|
Subject.OnDownload(_downloadMessage);
|
||||||
|
|
||||||
|
Mocker.GetMock<IXbmcService>().Verify(v => v.Clean(It.IsAny<XbmcSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,8 +55,9 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\FluentMigrator.1.1.1.0\tools\FluentMigrator.Runner.dll</HintPath>
|
<HintPath>..\packages\FluentMigrator.1.1.1.0\tools\FluentMigrator.Runner.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="FluentValidation">
|
<Reference Include="FluentValidation, Version=5.0.0.1, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\FluentValidation.4.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\FluentValidation.5.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
@ -79,11 +80,11 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
@ -131,6 +132,7 @@
|
||||||
<Compile Include="Framework\NBuilderExtensions.cs" />
|
<Compile Include="Framework\NBuilderExtensions.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodeFilesFixture.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodeFilesFixture.cs" />
|
||||||
|
<Compile Include="Housekeeping\Housekeepers\CleanupAdditionalNamingSpecsFixture.cs" />
|
||||||
<Compile Include="IndexerSearchTests\SearchDefinitionFixture.cs" />
|
<Compile Include="IndexerSearchTests\SearchDefinitionFixture.cs" />
|
||||||
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
|
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
|
||||||
<Compile Include="IndexerTests\IndexerServiceFixture.cs" />
|
<Compile Include="IndexerTests\IndexerServiceFixture.cs" />
|
||||||
|
@ -167,6 +169,7 @@
|
||||||
<Compile Include="NotificationTests\Xbmc\Json\CheckForErrorFixture.cs" />
|
<Compile Include="NotificationTests\Xbmc\Json\CheckForErrorFixture.cs" />
|
||||||
<Compile Include="NotificationTests\Xbmc\Json\GetSeriesPathFixture.cs" />
|
<Compile Include="NotificationTests\Xbmc\Json\GetSeriesPathFixture.cs" />
|
||||||
<Compile Include="NotificationTests\Xbmc\Json\UpdateFixture.cs" />
|
<Compile Include="NotificationTests\Xbmc\Json\UpdateFixture.cs" />
|
||||||
|
<Compile Include="NotificationTests\Xbmc\OnDownloadFixture.cs" />
|
||||||
<Compile Include="OrganizerTests\BuildFilePathFixture.cs" />
|
<Compile Include="OrganizerTests\BuildFilePathFixture.cs" />
|
||||||
<Compile Include="ParserTests\ParsingServiceTests\GetEpisodesFixture.cs" />
|
<Compile Include="ParserTests\ParsingServiceTests\GetEpisodesFixture.cs" />
|
||||||
<Compile Include="ParserTests\ParsingServiceTests\GetSeriesFixture.cs" />
|
<Compile Include="ParserTests\ParsingServiceTests\GetSeriesFixture.cs" />
|
||||||
|
|
|
@ -120,7 +120,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
ExceptionVerification.IgnoreWarns();
|
ExceptionVerification.IgnoreWarns();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("[DmonHiro] The Severing Crime Edge - Cut 02 - Portrait Of Heresy [BD, 720p] [BE36E9E0]")]
|
[TestCase("THIS SHOULD NEVER PARSE")]
|
||||||
public void unparsable_title_should_log_warn_and_return_null(string title)
|
public void unparsable_title_should_log_warn_and_return_null(string title)
|
||||||
{
|
{
|
||||||
Parser.Parser.ParseTitle(title).Should().BeNull();
|
Parser.Parser.ParseTitle(title).Should().BeNull();
|
||||||
|
@ -147,7 +147,9 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
[TestCase("Hell.on.Wheels.S02E09-E10.720p.HDTV.x264-EVOLVE", "Hell on Wheels", 2, new[] { 9, 10 })]
|
[TestCase("Hell.on.Wheels.S02E09-E10.720p.HDTV.x264-EVOLVE", "Hell on Wheels", 2, new[] { 9, 10 })]
|
||||||
[TestCase("Grey's Anatomy - 8x01_02 - Free Falling", "Grey's Anatomy", 8, new [] { 1,2 })]
|
[TestCase("Grey's Anatomy - 8x01_02 - Free Falling", "Grey's Anatomy", 8, new [] { 1,2 })]
|
||||||
[TestCase("8x01_02 - Free Falling", "", 8, new[] { 1, 2 })]
|
[TestCase("8x01_02 - Free Falling", "", 8, new[] { 1, 2 })]
|
||||||
[TestCase("Kaamelott.S01E91-E100", "Kaamelott", 1,new[] { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 })]
|
[TestCase("Kaamelott.S01E91-E100", "Kaamelott", 1, new[] { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 })]
|
||||||
|
[TestCase("Neighbours.S29E161-E165.PDTV.x264-FQM", "Neighbours", 29, new[] { 161, 162, 163, 164, 165 })]
|
||||||
|
[TestCase("Shortland.Street.S22E5363-E5366.HDTV.x264-FiHTV", "Shortland Street", 22, new[] { 5363, 5364, 5365, 5366 })]
|
||||||
public void TitleParse_multi(string postTitle, string title, int season, int[] episodes)
|
public void TitleParse_multi(string postTitle, string title, int season, int[] episodes)
|
||||||
{
|
{
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
@ -174,7 +176,39 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
result.Should().NotBeNull();
|
result.Should().NotBeNull();
|
||||||
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
||||||
result.AirDate.Should().Be(airDate.ToString(Episode.AIR_DATE_FORMAT));
|
result.AirDate.Should().Be(airDate.ToString(Episode.AIR_DATE_FORMAT));
|
||||||
result.EpisodeNumbers.Should().BeNull();
|
result.EpisodeNumbers.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)]
|
||||||
|
[TestCase("[Chihiro]_Working!!_-_06_[848x480_H.264_AAC][859EEAFA]", "Working!!", 6, 0, 0)]
|
||||||
|
[TestCase("[Commie]_Senki_Zesshou_Symphogear_-_11_[65F220B4]", "Senki_Zesshou_Symphogear", 11, 0, 0)]
|
||||||
|
[TestCase("[Underwater]_Rinne_no_Lagrange_-_12_(720p)_[5C7BC4F9]", "Rinne_no_Lagrange", 12, 0, 0)]
|
||||||
|
[TestCase("[Commie]_Rinne_no_Lagrange_-_15_[E76552EA]", "Rinne_no_Lagrange", 15, 0, 0)]
|
||||||
|
[TestCase("[HorribleSubs]_Hunter_X_Hunter_-_33_[720p]", "Hunter_X_Hunter", 33, 0, 0)]
|
||||||
|
[TestCase("[HorribleSubs]_Fairy_Tail_-_145_[720p]", "Fairy_Tail", 145, 0, 0)]
|
||||||
|
[TestCase("[HorribleSubs] Tonari no Kaibutsu-kun - 13 [1080p].mkv", "Tonari no Kaibutsu-kun", 13, 0, 0)]
|
||||||
|
[TestCase("[Doremi].Yes.Pretty.Cure.5.Go.Go!.31.[1280x720].[C65D4B1F].mkv", "Yes.Pretty.Cure.5.Go.Go!", 31, 0, 0)]
|
||||||
|
[TestCase("[K-F] One Piece 214", "One Piece", 214, 0, 0)]
|
||||||
|
[TestCase("[K-F] One Piece S10E14 214", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("[K-F] One Piece 10x14 214", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("[K-F] One Piece 214 10x14", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("One Piece S10E14 214", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("One Piece 10x14 214", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("One Piece 214 10x14", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("214 One Piece 10x14", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("Bleach - 031 - The Resolution to Kill [Lunar].avi", "Bleach", 31, 0, 0)]
|
||||||
|
[TestCase("Bleach - 031 - The Resolution to Kill [Lunar]", "Bleach", 31, 0, 0)]
|
||||||
|
[TestCase("[ACX]Hack Sign 01 Role Play [Kosaka] [9C57891E].mkv", "Hack Sign", 1, 0, 0)]
|
||||||
|
[TestCase("[SFW-sage] Bakuman S3 - 12 [720p][D07C91FC]", "Bakuman S3", 12, 0, 0)]
|
||||||
|
[TestCase("ducktales_e66_time_is_money_part_one_marking_time", "DuckTales", 66, 0, 0)]
|
||||||
|
public void parse_absolute_numbers(string postTitle, string title, int absoluteEpisodeNumber, int seasonNumber, int episodeNumber)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
result.Should().NotBeNull();
|
||||||
|
result.AbsoluteEpisodeNumbers.First().Should().Be(absoluteEpisodeNumber);
|
||||||
|
result.SeasonNumber.Should().Be(seasonNumber);
|
||||||
|
result.EpisodeNumbers.FirstOrDefault().Should().Be(episodeNumber);
|
||||||
|
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
{
|
{
|
||||||
SeriesTitle = _series.Title,
|
SeriesTitle = _series.Title,
|
||||||
SeasonNumber = 1,
|
SeasonNumber = 1,
|
||||||
EpisodeNumbers = new[] { 1 }
|
EpisodeNumbers = new[] { 1 },
|
||||||
|
AbsoluteEpisodeNumbers = new int[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
||||||
|
@ -69,6 +70,11 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
_series.UseSceneNumbering = true;
|
_series.UseSceneNumbering = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GivenAbsoluteNumberingSeries()
|
||||||
|
{
|
||||||
|
_parsedEpisodeInfo.AbsoluteEpisodeNumbers = new[] { 1 };
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_get_daily_episode_episode_when_search_criteria_is_null()
|
public void should_get_daily_episode_episode_when_search_criteria_is_null()
|
||||||
{
|
{
|
||||||
|
@ -105,6 +111,17 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<String>()), Times.Once());
|
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<String>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_search_criteria_episode_when_it_matches_absolute()
|
||||||
|
{
|
||||||
|
GivenAbsoluteNumberingSeries();
|
||||||
|
|
||||||
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||||
|
|
||||||
|
Mocker.GetMock<IEpisodeService>()
|
||||||
|
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<String>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_use_scene_numbering_when_series_uses_scene_numbering()
|
public void should_use_scene_numbering_when_series_uses_scene_numbering()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_one_drive_when_only_one_root_dir_exists()
|
public void should_return_one_drive_when_only_one_root_dir_exists()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>()
|
Mocker.GetMock<IRootFolderRepository>()
|
||||||
.Setup(s => s.All())
|
.Setup(s => s.All())
|
||||||
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" } });
|
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" } });
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_one_drive_when_two_rootDirs_on_the_same_drive_exist()
|
public void should_return_one_drive_when_two_rootDirs_on_the_same_drive_exist()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>()
|
Mocker.GetMock<IRootFolderRepository>()
|
||||||
.Setup(s => s.All())
|
.Setup(s => s.All())
|
||||||
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" },
|
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" },
|
||||||
new RootFolder { Id = 2, Path = @"C:\Test\TV2" }});
|
new RootFolder { Id = 2, Path = @"C:\Test\TV2" }});
|
||||||
|
@ -62,7 +62,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_two_drives_when_two_rootDirs_on_the_different_drive_exist()
|
public void should_return_two_drives_when_two_rootDirs_on_the_different_drive_exist()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>()
|
Mocker.GetMock<IRootFolderRepository>()
|
||||||
.Setup(s => s.All())
|
.Setup(s => s.All())
|
||||||
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" },
|
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" },
|
||||||
new RootFolder { Id = 2, Path = @"D:\Test\TV" }});
|
new RootFolder { Id = 2, Path = @"D:\Test\TV" }});
|
||||||
|
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_skip_rootDir_if_not_found_on_disk()
|
public void should_skip_rootDir_if_not_found_on_disk()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>()
|
Mocker.GetMock<IRootFolderRepository>()
|
||||||
.Setup(s => s.All())
|
.Setup(s => s.All())
|
||||||
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" } });
|
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" } });
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Datastore;
|
|
||||||
using NzbDrone.Core.RootFolders;
|
using NzbDrone.Core.RootFolders;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
@ -25,7 +22,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
.Setup(m => m.FolderExists(It.IsAny<string>()))
|
.Setup(m => m.FolderExists(It.IsAny<string>()))
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>()
|
Mocker.GetMock<IRootFolderRepository>()
|
||||||
.Setup(s => s.All())
|
.Setup(s => s.All())
|
||||||
.Returns(new List<RootFolder>());
|
.Returns(new List<RootFolder>());
|
||||||
}
|
}
|
||||||
|
@ -45,7 +42,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
|
|
||||||
Subject.Add(root);
|
Subject.Add(root);
|
||||||
|
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>().Verify(c => c.Insert(root), Times.Once());
|
Mocker.GetMock<IRootFolderRepository>().Verify(c => c.Insert(root), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -60,14 +57,15 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
public void should_be_able_to_remove_root_dir()
|
public void should_be_able_to_remove_root_dir()
|
||||||
{
|
{
|
||||||
Subject.Remove(1);
|
Subject.Remove(1);
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>().Verify(c => c.Delete(1), Times.Once());
|
Mocker.GetMock<IRootFolderRepository>().Verify(c => c.Delete(1), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
public void None_existing_folder_returns_empty_list()
|
public void None_existing_folder_returns_empty_list()
|
||||||
{
|
{
|
||||||
WithNoneExistingFolder();
|
WithNoneExistingFolder();
|
||||||
|
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>().Setup(c => c.All()).Returns(new List<RootFolder>());
|
Mocker.GetMock<IRootFolderRepository>().Setup(c => c.All()).Returns(new List<RootFolder>());
|
||||||
|
|
||||||
const string path = "d:\\bad folder";
|
const string path = "d:\\bad folder";
|
||||||
|
|
||||||
|
@ -97,7 +95,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
[Test]
|
[Test]
|
||||||
public void adding_duplicated_root_folder_should_throw()
|
public void adding_duplicated_root_folder_should_throw()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IBasicRepository<RootFolder>>().Setup(c => c.All()).Returns(new List<RootFolder> { new RootFolder { Path = "C:\\TV".AsOsAgnostic() } });
|
Mocker.GetMock<IRootFolderRepository>().Setup(c => c.All()).Returns(new List<RootFolder> { new RootFolder { Path = "C:\\TV".AsOsAgnostic() } });
|
||||||
|
|
||||||
Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = @"C:\TV".AsOsAgnostic() }));
|
Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = @"C:\TV".AsOsAgnostic() }));
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
.With(e => e.SeasonNumber = 1)
|
.With(e => e.SeasonNumber = 1)
|
||||||
.With(e => e.SceneSeasonNumber = 2)
|
.With(e => e.SceneSeasonNumber = 2)
|
||||||
.With(e => e.EpisodeNumber = 3)
|
.With(e => e.EpisodeNumber = 3)
|
||||||
|
.With(e => e.AbsoluteEpisodeNumber = 3)
|
||||||
.With(e => e.SceneEpisodeNumber = 4)
|
.With(e => e.SceneEpisodeNumber = 4)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
@ -51,5 +52,14 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
.Should()
|
.Should()
|
||||||
.BeNull();
|
.BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_find_episode_by_absolute_numbering()
|
||||||
|
{
|
||||||
|
Subject.Find(_episode.SeriesId, _episode.AbsoluteEpisodeNumber.Value)
|
||||||
|
.Id
|
||||||
|
.Should()
|
||||||
|
.Be(_episode.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
<package id="CommonServiceLocator" version="1.0" targetFramework="net40" />
|
<package id="CommonServiceLocator" version="1.0" targetFramework="net40" />
|
||||||
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
||||||
<package id="FluentMigrator" version="1.1.1.0" targetFramework="net40" />
|
<package id="FluentMigrator" version="1.1.1.0" targetFramework="net40" />
|
||||||
<package id="FluentValidation" version="4.0.0.1" targetFramework="net40" />
|
<package id="FluentValidation" version="5.0.0.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" />
|
<package id="NBuilder" version="3.0.1.1" />
|
||||||
<package id="NCrunch.Framework" version="1.46.0.9" targetFramework="net40" />
|
<package id="NCrunch.Framework" version="1.46.0.9" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
||||||
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
|
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
|
||||||
<package id="Unity" version="2.1.505.2" targetFramework="net40" />
|
<package id="Unity" version="2.1.505.2" targetFramework="net40" />
|
||||||
|
|
|
@ -116,6 +116,8 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
DataMapper.Insert(model);
|
DataMapper.Insert(model);
|
||||||
|
|
||||||
|
ModelCreated(model);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,12 +129,15 @@ namespace NzbDrone.Core.Datastore
|
||||||
}
|
}
|
||||||
|
|
||||||
DataMapper.Update(model, c => c.Id == model.Id);
|
DataMapper.Update(model, c => c.Id == model.Id);
|
||||||
|
|
||||||
|
ModelUpdated(model);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(TModel model)
|
public void Delete(TModel model)
|
||||||
{
|
{
|
||||||
DataMapper.Delete<TModel>(c => c.Id == model.Id);
|
Delete(model.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InsertMany(IList<TModel> models)
|
public void InsertMany(IList<TModel> models)
|
||||||
|
@ -199,6 +204,8 @@ namespace NzbDrone.Core.Datastore
|
||||||
.ColumnsIncluding(properties)
|
.ColumnsIncluding(properties)
|
||||||
.Entity(model)
|
.Entity(model)
|
||||||
.Execute();
|
.Execute();
|
||||||
|
|
||||||
|
ModelUpdated(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual PagingSpec<TModel> GetPaged(PagingSpec<TModel> pagingSpec)
|
public virtual PagingSpec<TModel> GetPaged(PagingSpec<TModel> pagingSpec)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using NLog;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
@ -16,10 +17,12 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
public class SabCommunicationProxy : ISabCommunicationProxy
|
public class SabCommunicationProxy : ISabCommunicationProxy
|
||||||
{
|
{
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public SabCommunicationProxy(IConfigService configService)
|
public SabCommunicationProxy(IConfigService configService, Logger logger)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DownloadNzb(Stream nzb, string title, string category, int priority)
|
public string DownloadNzb(Stream nzb, string title, string category, int priority)
|
||||||
|
@ -44,6 +47,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
{
|
{
|
||||||
var client = BuildClient(action);
|
var client = BuildClient(action);
|
||||||
var response = client.Execute(restRequest);
|
var response = client.Execute(restRequest);
|
||||||
|
_logger.Trace("Response: {0}", response);
|
||||||
|
|
||||||
CheckForError(response);
|
CheckForError(response);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
|
{
|
||||||
|
public class CleanupAdditionalNamingSpecs : IHousekeepingTask
|
||||||
|
{
|
||||||
|
private readonly IDatabase _database;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public CleanupAdditionalNamingSpecs(IDatabase database, Logger logger)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clean()
|
||||||
|
{
|
||||||
|
_logger.Trace("Running naming spec cleanup");
|
||||||
|
|
||||||
|
var mapper = _database.GetDataMapper();
|
||||||
|
|
||||||
|
mapper.ExecuteNonQuery(@"DELETE FROM NamingConfig
|
||||||
|
WHERE ID NOT IN (
|
||||||
|
SELECT ID FROM NamingConfig
|
||||||
|
LIMIT 1)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Housekeeping.Housekeepers
|
namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.History;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Housekeeping.Housekeepers
|
namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,10 +101,10 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
{
|
{
|
||||||
if (tvRageId > 0)
|
if (tvRageId > 0)
|
||||||
{
|
{
|
||||||
return RecentFeed.Select(url => String.Format("{0}&limit=100&rid={1}&season={2:yyyy}&ep={2:MM/dd}", url, tvRageId, date)).ToList();
|
return RecentFeed.Select(url => String.Format("{0}&limit=100&rid={1}&season={2:yyyy}&ep={2:MM}/{2:dd}", url, tvRageId, date)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return RecentFeed.Select(url => String.Format("{0}&limit=100&q={1}&season={2:yyyy}&ep={2:MM/dd}", url, NewsnabifyTitle(seriesTitle), date)).ToList();
|
return RecentFeed.Select(url => String.Format("{0}&limit=100&q={1}&season={2:yyyy}&ep={2:MM}/{2:dd}", url, NewsnabifyTitle(seriesTitle), date)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset)
|
public override IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset)
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
var decisions = _importDecisionMaker.GetImportDecisions(mediaFileList, series, false);
|
var decisions = _importDecisionMaker.GetImportDecisions(mediaFileList, series, false);
|
||||||
_importApprovedEpisodes.Import(decisions);
|
_importApprovedEpisodes.Import(decisions);
|
||||||
|
_logger.Info("Completed scanning disk for {0}", series.Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetVideoFiles(string path, bool allDirectories = true)
|
public string[] GetVideoFiles(string path, bool allDirectories = true)
|
||||||
|
@ -65,7 +66,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
var mediaFileList = filesOnDisk.Where(c => MediaFileExtensions.Extensions.Contains(Path.GetExtension(c).ToLower())).ToList();
|
var mediaFileList = filesOnDisk.Where(c => MediaFileExtensions.Extensions.Contains(Path.GetExtension(c).ToLower())).ToList();
|
||||||
|
|
||||||
_logger.Trace("{0} video files were found in {1}", mediaFileList.Count, path);
|
_logger.Debug("{0} video files were found in {1}", mediaFileList.Count, path);
|
||||||
return mediaFileList.ToArray();
|
return mediaFileList.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
{
|
{
|
||||||
var cleanedUpName = GetCleanedUpFolderName(subfolderInfo.Name);
|
var cleanedUpName = GetCleanedUpFolderName(subfolderInfo.Name);
|
||||||
var series = _parsingService.GetSeries(cleanedUpName);
|
var series = _parsingService.GetSeries(cleanedUpName);
|
||||||
|
var quality = QualityParser.ParseQuality(cleanedUpName);
|
||||||
|
|
||||||
if (series == null)
|
if (series == null)
|
||||||
{
|
{
|
||||||
|
@ -108,7 +109,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
var videoFiles = _diskScanService.GetVideoFiles(subfolderInfo.FullName);
|
var videoFiles = _diskScanService.GetVideoFiles(subfolderInfo.FullName);
|
||||||
|
|
||||||
return ProcessFiles(series, videoFiles);
|
return ProcessFiles(series, quality, videoFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessVideoFile(string videoFile)
|
private void ProcessVideoFile(string videoFile)
|
||||||
|
@ -127,12 +128,12 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessFiles(series, videoFile);
|
ProcessFiles(series, null, videoFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ImportDecision> ProcessFiles(Series series, params string[] videoFiles)
|
private List<ImportDecision> ProcessFiles(Series series, QualityModel quality, params string[] videoFiles)
|
||||||
{
|
{
|
||||||
var decisions = _importDecisionMaker.GetImportDecisions(videoFiles, series, true);
|
var decisions = _importDecisionMaker.GetImportDecisions(videoFiles, series, true, quality);
|
||||||
return _importApprovedEpisodes.Import(decisions, true);
|
return _importApprovedEpisodes.Import(decisions, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles
|
||||||
|
{
|
||||||
|
public class EpisodeFileMoveResult
|
||||||
|
{
|
||||||
|
public EpisodeFileMoveResult()
|
||||||
|
{
|
||||||
|
OldFiles = new List<EpisodeFile>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String Path { get; set; }
|
||||||
|
public List<EpisodeFile> OldFiles { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
foreach (var importDecision in qualifiedImports.OrderByDescending(e => e.LocalEpisode.Size))
|
foreach (var importDecision in qualifiedImports.OrderByDescending(e => e.LocalEpisode.Size))
|
||||||
{
|
{
|
||||||
var localEpisode = importDecision.LocalEpisode;
|
var localEpisode = importDecision.LocalEpisode;
|
||||||
|
var oldFiles = new List<EpisodeFile>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -65,11 +66,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
episodeFile.SeasonNumber = localEpisode.SeasonNumber;
|
episodeFile.SeasonNumber = localEpisode.SeasonNumber;
|
||||||
episodeFile.Episodes = localEpisode.Episodes;
|
episodeFile.Episodes = localEpisode.Episodes;
|
||||||
|
|
||||||
|
|
||||||
if (newDownload)
|
if (newDownload)
|
||||||
{
|
{
|
||||||
episodeFile.SceneName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath());
|
episodeFile.SceneName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath());
|
||||||
episodeFile.Path = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode);
|
var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode);
|
||||||
|
episodeFile.Path = moveResult.Path;
|
||||||
|
oldFiles = moveResult.OldFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mediaFileService.Add(episodeFile);
|
_mediaFileService.Add(episodeFile);
|
||||||
|
@ -78,7 +80,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
if (newDownload)
|
if (newDownload)
|
||||||
{
|
{
|
||||||
_eventAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile));
|
_eventAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile));
|
||||||
_eventAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode));
|
_eventAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode, episodeFile, oldFiles));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
@ -6,6 +6,7 @@ using NzbDrone.Common;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
{
|
{
|
||||||
public interface IMakeImportDecision
|
public interface IMakeImportDecision
|
||||||
{
|
{
|
||||||
List<ImportDecision> GetImportDecisions(IEnumerable<String> videoFiles, Series series, bool sceneSource);
|
List<ImportDecision> GetImportDecisions(IEnumerable<String> videoFiles, Series series, bool sceneSource, QualityModel quality = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportDecisionMaker : IMakeImportDecision
|
public class ImportDecisionMaker : IMakeImportDecision
|
||||||
|
@ -38,16 +39,16 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportDecision> GetImportDecisions(IEnumerable<string> videoFiles, Series series, bool sceneSource)
|
public List<ImportDecision> GetImportDecisions(IEnumerable<string> videoFiles, Series series, bool sceneSource, QualityModel quality = null)
|
||||||
{
|
{
|
||||||
var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), series.Id);
|
var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), series.Id);
|
||||||
|
|
||||||
_logger.Debug("Analysing {0}/{1} files.", newFiles.Count, videoFiles.Count());
|
_logger.Debug("Analysing {0}/{1} files.", newFiles.Count, videoFiles.Count());
|
||||||
|
|
||||||
return GetDecisions(newFiles, series, sceneSource).ToList();
|
return GetDecisions(newFiles, series, sceneSource, quality).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<ImportDecision> GetDecisions(IEnumerable<String> videoFiles, Series series, bool sceneSource)
|
private IEnumerable<ImportDecision> GetDecisions(IEnumerable<String> videoFiles, Series series, bool sceneSource, QualityModel quality = null)
|
||||||
{
|
{
|
||||||
foreach (var file in videoFiles)
|
foreach (var file in videoFiles)
|
||||||
{
|
{
|
||||||
|
@ -59,6 +60,11 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
if (parsedEpisode != null)
|
if (parsedEpisode != null)
|
||||||
{
|
{
|
||||||
|
if (quality != null && quality > parsedEpisode.Quality)
|
||||||
|
{
|
||||||
|
parsedEpisode.Quality = quality;
|
||||||
|
}
|
||||||
|
|
||||||
parsedEpisode.Size = _diskProvider.GetFileSize(file);
|
parsedEpisode.Size = _diskProvider.GetFileSize(file);
|
||||||
decision = GetDecision(parsedEpisode);
|
decision = GetDecision(parsedEpisode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using NzbDrone.Common.Messaging;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Common.Messaging;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.Events
|
namespace NzbDrone.Core.MediaFiles.Events
|
||||||
|
@ -6,10 +7,14 @@ namespace NzbDrone.Core.MediaFiles.Events
|
||||||
public class EpisodeDownloadedEvent : IEvent
|
public class EpisodeDownloadedEvent : IEvent
|
||||||
{
|
{
|
||||||
public LocalEpisode Episode { get; private set; }
|
public LocalEpisode Episode { get; private set; }
|
||||||
|
public EpisodeFile EpisodeFile { get; private set; }
|
||||||
|
public List<EpisodeFile> OldFiles { get; private set; }
|
||||||
|
|
||||||
public EpisodeDownloadedEvent(LocalEpisode episode)
|
public EpisodeDownloadedEvent(LocalEpisode episode, EpisodeFile episodeFile, List<EpisodeFile> oldFiles)
|
||||||
{
|
{
|
||||||
Episode = episode;
|
Episode = episode;
|
||||||
|
EpisodeFile = episodeFile;
|
||||||
|
OldFiles = oldFiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -61,7 +61,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||||
aBitRate = aBitRate.Remove(ABindex);
|
aBitRate = aBitRate.Remove(ABindex);
|
||||||
|
|
||||||
Int32.TryParse(aBitRate, out audioBitRate);
|
Int32.TryParse(aBitRate, out audioBitRate);
|
||||||
Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out runTime);
|
Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out runTime);
|
||||||
Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);
|
Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);
|
||||||
|
|
||||||
string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)");
|
string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)");
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
{
|
{
|
||||||
public interface IUpgradeMediaFiles
|
public interface IUpgradeMediaFiles
|
||||||
{
|
{
|
||||||
string UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode);
|
EpisodeFileMoveResult UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UpgradeMediaFileService : IUpgradeMediaFiles
|
public class UpgradeMediaFileService : IUpgradeMediaFiles
|
||||||
|
@ -31,8 +31,9 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode)
|
public EpisodeFileMoveResult UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode)
|
||||||
{
|
{
|
||||||
|
var moveFileResult = new EpisodeFileMoveResult();
|
||||||
var existingFiles = localEpisode.Episodes
|
var existingFiles = localEpisode.Episodes
|
||||||
.Where(e => e.EpisodeFileId > 0)
|
.Where(e => e.EpisodeFileId > 0)
|
||||||
.Select(e => e.EpisodeFile.Value)
|
.Select(e => e.EpisodeFile.Value)
|
||||||
|
@ -48,11 +49,14 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
_recycleBinProvider.DeleteFile(file.Path);
|
_recycleBinProvider.DeleteFile(file.Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveFileResult.OldFiles.Add(file);
|
||||||
_mediaFileService.Delete(file, true);
|
_mediaFileService.Delete(file, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Trace("Moving episode file: {0}", episodeFile);
|
_logger.Trace("Moving episode file: {0}", episodeFile);
|
||||||
return _episodeFileMover.MoveEpisodeFile(episodeFile, localEpisode);
|
moveFileResult.Path = _episodeFileMover.MoveEpisodeFile(episodeFile, localEpisode);
|
||||||
|
|
||||||
|
return moveFileResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace NzbDrone.Core.MetadataSource.Trakt
|
||||||
public int tvrage_id { get; set; }
|
public int tvrage_id { get; set; }
|
||||||
public int last_updated { get; set; }
|
public int last_updated { get; set; }
|
||||||
public string poster { get; set; }
|
public string poster { get; set; }
|
||||||
|
public bool? ended { get; set; }
|
||||||
public Images images { get; set; }
|
public Images images { get; set; }
|
||||||
public List<string> genres { get; set; }
|
public List<string> genres { get; set; }
|
||||||
public List<Season> seasons { get; set; }
|
public List<Season> seasons { get; set; }
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace NzbDrone.Core.MetadataSource
|
||||||
series.Network = show.network;
|
series.Network = show.network;
|
||||||
series.AirTime = show.air_time_utc;
|
series.AirTime = show.air_time_utc;
|
||||||
series.TitleSlug = show.url.ToLower().Replace("http://trakt.tv/show/", "");
|
series.TitleSlug = show.url.ToLower().Replace("http://trakt.tv/show/", "");
|
||||||
series.Status = GetSeriesStatus(show.status);
|
series.Status = GetSeriesStatus(show.status, show.ended);
|
||||||
|
|
||||||
series.Seasons = show.seasons.Select(s => new Tv.Season
|
series.Seasons = show.seasons.Select(s => new Tv.Season
|
||||||
{
|
{
|
||||||
|
@ -135,9 +135,17 @@ namespace NzbDrone.Core.MetadataSource
|
||||||
return withoutExtension + "-300" + extension;
|
return withoutExtension + "-300" + extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SeriesStatusType GetSeriesStatus(string status)
|
private static SeriesStatusType GetSeriesStatus(string status, bool? ended)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(status)) return SeriesStatusType.Continuing;
|
if (string.IsNullOrWhiteSpace(status))
|
||||||
|
{
|
||||||
|
if (ended.HasValue && ended.Value)
|
||||||
|
{
|
||||||
|
return SeriesStatusType.Ended;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SeriesStatusType.Continuing;
|
||||||
|
}
|
||||||
if (status.Equals("Ended", StringComparison.InvariantCultureIgnoreCase)) return SeriesStatusType.Ended;
|
if (status.Equals("Ended", StringComparison.InvariantCultureIgnoreCase)) return SeriesStatusType.Ended;
|
||||||
return SeriesStatusType.Continuing;
|
return SeriesStatusType.Continuing;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications
|
||||||
|
{
|
||||||
|
public class DownloadMessage
|
||||||
|
{
|
||||||
|
public String Message { get; set; }
|
||||||
|
public Series Series { get; set; }
|
||||||
|
public EpisodeFile EpisodeFile { get; set; }
|
||||||
|
public List<EpisodeFile> OldFiles { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,10 +25,10 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
_smtpProvider.SendEmail(Settings, subject, body);
|
_smtpProvider.SendEmail(Settings, subject, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string subject = "NzbDrone [TV] - Downloaded";
|
const string subject = "NzbDrone [TV] - Downloaded";
|
||||||
var body = String.Format("{0} Downloaded and sorted.", message);
|
var body = String.Format("{0} Downloaded and sorted.", message.Message);
|
||||||
|
|
||||||
_smtpProvider.SendEmail(Settings, subject, body);
|
_smtpProvider.SendEmail(Settings, subject, body);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,11 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||||
_growlProvider.SendNotification(title, message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
_growlProvider.SendNotification(title, message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_growlProvider.SendNotification(title, message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
_growlProvider.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
string Link { get; }
|
string Link { get; }
|
||||||
|
|
||||||
void OnGrab(string message);
|
void OnGrab(string message);
|
||||||
void OnDownload(string message, Series series);
|
void OnDownload(DownloadMessage message);
|
||||||
void AfterRename(Series series);
|
void AfterRename(Series series);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
public abstract string Link { get; }
|
public abstract string Link { get; }
|
||||||
|
|
||||||
public abstract void OnGrab(string message);
|
public abstract void OnGrab(string message);
|
||||||
public abstract void OnDownload(string message, Series series);
|
public abstract void OnDownload(DownloadMessage message);
|
||||||
public abstract void AfterRename(Series series);
|
public abstract void AfterRename(Series series);
|
||||||
|
|
||||||
protected TSettings Settings
|
protected TSettings Settings
|
||||||
|
|
|
@ -73,13 +73,17 @@ namespace NzbDrone.Core.Notifications
|
||||||
|
|
||||||
public void Handle(EpisodeDownloadedEvent message)
|
public void Handle(EpisodeDownloadedEvent message)
|
||||||
{
|
{
|
||||||
var messageBody = GetMessage(message.Episode.Series, message.Episode.Episodes, message.Episode.ParsedEpisodeInfo.Quality);
|
var downloadMessage = new DownloadMessage();
|
||||||
|
downloadMessage.Message = GetMessage(message.Episode.Series, message.Episode.Episodes, message.Episode.ParsedEpisodeInfo.Quality);
|
||||||
|
downloadMessage.Series = message.Episode.Series;
|
||||||
|
downloadMessage.EpisodeFile = message.EpisodeFile;
|
||||||
|
downloadMessage.OldFiles = message.OldFiles;
|
||||||
|
|
||||||
foreach (var notification in _notificationFactory.OnDownloadEnabled())
|
foreach (var notification in _notificationFactory.OnDownloadEnabled())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
notification.OnDownload(messageBody, message.Episode.Series);
|
notification.OnDownload(downloadMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
@ -23,11 +23,11 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
_notifyMyAndroidProxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
_notifyMyAndroidProxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_notifyMyAndroidProxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
_notifyMyAndroidProxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
|
|
|
@ -22,10 +22,10 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
_plexProvider.Notify(Settings, header, message);
|
_plexProvider.Notify(Settings, header, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string header = "NzbDrone [TV] - Downloaded";
|
const string header = "NzbDrone [TV] - Downloaded";
|
||||||
_plexProvider.Notify(Settings, header, message);
|
_plexProvider.Notify(Settings, header, message.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
UpdateIfEnabled();
|
UpdateIfEnabled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,11 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
_prowlProvider.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
_prowlProvider.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_prowlProvider.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
_prowlProvider.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
|
|
|
@ -23,11 +23,11 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
_pushBulletProxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId);
|
_pushBulletProxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_pushBulletProxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId);
|
_pushBulletProxy.SendNotification(title, message.Message, Settings.ApiKey, Settings.DeviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
|
|
|
@ -23,11 +23,11 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
_pushoverProxy.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority);
|
_pushoverProxy.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_pushoverProxy.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority);
|
_pushoverProxy.SendNotification(title, message.Message, Settings.UserKey, (PushoverPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
|
|
|
@ -119,7 +119,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
return String.Empty;
|
return String.Empty;
|
||||||
|
|
||||||
var xDoc = XDocument.Load(new StringReader(response.Replace("&", "&")));
|
var xDoc = XDocument.Load(new StringReader(response.Replace("&", "&")));
|
||||||
var xml = (from x in xDoc.Descendants("xml") select x).FirstOrDefault();
|
var xml = xDoc.Descendants("xml").Select(x => x).FirstOrDefault();
|
||||||
|
|
||||||
if (xml == null)
|
if (xml == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using NzbDrone.Core.Tv;
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Xbmc
|
namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
{
|
{
|
||||||
|
@ -26,16 +27,16 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string header = "NzbDrone [TV] - Downloaded";
|
const string header = "NzbDrone [TV] - Downloaded";
|
||||||
|
|
||||||
if (Settings.Notify)
|
if (Settings.Notify)
|
||||||
{
|
{
|
||||||
_xbmcProvider.Notify(Settings, header, message);
|
_xbmcProvider.Notify(Settings, header, message.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateAndClean(series);
|
UpdateAndClean(message.Series, message.OldFiles.Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
|
@ -43,14 +44,14 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
UpdateAndClean(series);
|
UpdateAndClean(series);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateAndClean(Series series)
|
private void UpdateAndClean(Series series, bool clean = true)
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
if (Settings.UpdateLibrary)
|
||||||
{
|
{
|
||||||
_xbmcProvider.Update(Settings, series);
|
_xbmcProvider.Update(Settings, series);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.CleanLibrary)
|
if (clean && Settings.CleanLibrary)
|
||||||
{
|
{
|
||||||
_xbmcProvider.Clean(Settings);
|
_xbmcProvider.Clean(Settings);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,9 +67,9 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\FluentMigrator.1.1.1.0\tools\FluentMigrator.Runner.dll</HintPath>
|
<HintPath>..\packages\FluentMigrator.1.1.1.0\tools\FluentMigrator.Runner.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="FluentValidation, Version=4.0.0.1, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="FluentValidation, Version=5.0.0.1, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\FluentValidation.4.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
|
<HintPath>..\packages\FluentValidation.5.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Growl.Connector">
|
<Reference Include="Growl.Connector">
|
||||||
<HintPath>..\packages\Growl.0.6\lib\Growl.Connector.dll</HintPath>
|
<HintPath>..\packages\Growl.0.6\lib\Growl.Connector.dll</HintPath>
|
||||||
|
@ -83,11 +83,11 @@
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Omu.ValueInjecter">
|
<Reference Include="Omu.ValueInjecter">
|
||||||
<HintPath>..\packages\valueinjecter.2.3.3\lib\net35\Omu.ValueInjecter.dll</HintPath>
|
<HintPath>..\packages\valueinjecter.2.3.3\lib\net35\Omu.ValueInjecter.dll</HintPath>
|
||||||
|
@ -96,9 +96,9 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Prowlin.0.9.4456.26422\lib\net40\Prowlin.dll</HintPath>
|
<HintPath>..\packages\Prowlin.0.9.4456.26422\lib\net40\Prowlin.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RestSharp, Version=104.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="RestSharp, Version=104.3.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\RestSharp.104.2.0\lib\net4\RestSharp.dll</HintPath>
|
<HintPath>..\packages\RestSharp.104.3.3\lib\net4\RestSharp.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
@ -247,6 +247,7 @@
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodes.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodes.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItems.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItems.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodeFiles.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodeFiles.cs" />
|
||||||
|
<Compile Include="Housekeeping\Housekeepers\CleanupAdditionalNamingSpecs.cs" />
|
||||||
<Compile Include="Housekeeping\HousekeepingCommand.cs" />
|
<Compile Include="Housekeeping\HousekeepingCommand.cs" />
|
||||||
<Compile Include="Housekeeping\HousekeepingService.cs" />
|
<Compile Include="Housekeeping\HousekeepingService.cs" />
|
||||||
<Compile Include="Housekeeping\IHousekeepingTask.cs" />
|
<Compile Include="Housekeeping\IHousekeepingTask.cs" />
|
||||||
|
@ -274,6 +275,7 @@
|
||||||
<Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" />
|
<Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" />
|
||||||
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
|
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
|
||||||
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
||||||
|
<Compile Include="MediaFiles\EpisodeFileMoveResult.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileExtensions.cs" />
|
<Compile Include="MediaFiles\MediaFileExtensions.cs" />
|
||||||
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" />
|
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" />
|
||||||
<Compile Include="Messaging\Commands\CommandExecutor.cs" />
|
<Compile Include="Messaging\Commands\CommandExecutor.cs" />
|
||||||
|
@ -289,6 +291,7 @@
|
||||||
<Compile Include="MetadataSource\Trakt\TraktException.cs" />
|
<Compile Include="MetadataSource\Trakt\TraktException.cs" />
|
||||||
<Compile Include="Notifications\NotificationFactory.cs" />
|
<Compile Include="Notifications\NotificationFactory.cs" />
|
||||||
<Compile Include="Notifications\NotificationService.cs" />
|
<Compile Include="Notifications\NotificationService.cs" />
|
||||||
|
<Compile Include="Notifications\DownloadMessage.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\PushBullet.cs" />
|
<Compile Include="Notifications\PushBullet\PushBullet.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\PushBulletProxy.cs" />
|
<Compile Include="Notifications\PushBullet\PushBulletProxy.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\PushBulletSettings.cs" />
|
<Compile Include="Notifications\PushBullet\PushBulletSettings.cs" />
|
||||||
|
@ -436,6 +439,7 @@
|
||||||
<Compile Include="Parser\Parser.cs" />
|
<Compile Include="Parser\Parser.cs" />
|
||||||
<Compile Include="Parser\ParsingService.cs" />
|
<Compile Include="Parser\ParsingService.cs" />
|
||||||
<Compile Include="Parser\QualityParser.cs" />
|
<Compile Include="Parser\QualityParser.cs" />
|
||||||
|
<Compile Include="RootFolders\RootFolderRepository.cs" />
|
||||||
<Compile Include="ThingiProvider\ConfigContractNotFoundException.cs" />
|
<Compile Include="ThingiProvider\ConfigContractNotFoundException.cs" />
|
||||||
<Compile Include="ThingiProvider\IProvider.cs" />
|
<Compile Include="ThingiProvider\IProvider.cs" />
|
||||||
<Compile Include="Qualities\QualityProfileInUseException.cs" />
|
<Compile Include="Qualities\QualityProfileInUseException.cs" />
|
||||||
|
|
|
@ -11,11 +11,27 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
public int[] EpisodeNumbers { get; set; }
|
public int[] EpisodeNumbers { get; set; }
|
||||||
|
public int[] AbsoluteEpisodeNumbers { get; set; }
|
||||||
public String AirDate { get; set; }
|
public String AirDate { get; set; }
|
||||||
public Language Language { get; set; }
|
public Language Language { get; set; }
|
||||||
|
|
||||||
public bool FullSeason { get; set; }
|
public bool FullSeason { get; set; }
|
||||||
|
|
||||||
|
public ParsedEpisodeInfo()
|
||||||
|
{
|
||||||
|
EpisodeNumbers = new int[0];
|
||||||
|
AbsoluteEpisodeNumbers = new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDaily()
|
||||||
|
{
|
||||||
|
return !String.IsNullOrWhiteSpace(AirDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAbsoluteNumbering()
|
||||||
|
{
|
||||||
|
return AbsoluteEpisodeNumbers.Any();
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
string episodeString = "[Unknown Episode]";
|
string episodeString = "[Unknown Episode]";
|
||||||
|
@ -35,10 +51,5 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
|
|
||||||
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
|
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDaily()
|
|
||||||
{
|
|
||||||
return !String.IsNullOrWhiteSpace(AirDate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,13 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
{
|
{
|
||||||
return DateTime.UtcNow.Subtract(PublishDate).Days;
|
return DateTime.UtcNow.Subtract(PublishDate).Days;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This prevents manually downloading a release from blowing up in mono
|
||||||
|
//TODO: Is there a better way?
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
@ -20,6 +21,22 @@ namespace NzbDrone.Core.Parser
|
||||||
new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>[0-1][0-9])\W+(?<airday>[0-3][0-9])(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>[0-1][0-9])\W+(?<airday>[0-3][0-9])(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//Anime - Absolute Episode Number + Title + Season+Episode
|
||||||
|
new Regex(@"^(?:(?<absoluteepisode>\d{2,3})(?:_|-|\s|\.)+)+(?<title>.+?)(?:\W|_)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//Anime - [SubGroup] Title Absolute Episode Number + Season+Episode
|
||||||
|
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.))?(?<title>.+?)(?:(?:\W|_)+(?<absoluteepisode>\d{2,3}))+(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//Anime - [SubGroup] Title Season+Episode + Absolute Episode Number
|
||||||
|
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.))?(?<title>.+?)(?:\W|_)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:\s|\.)(?:(?<absoluteepisode>\d{2,3})(?:_|-|\s|\.|$)+)+",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//Anime - [SubGroup] Title Absolute Episode Number
|
||||||
|
new Regex(@"^\[(?<subgroup>.+?)\](?:_|-|\s|\.)?(?<title>.+?)(?:(?:\W|_)+(?<absoluteepisode>\d{2,}))+",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Multi-Part episodes without a title (S01E05.S01E06)
|
//Multi-Part episodes without a title (S01E05.S01E06)
|
||||||
new Regex(@"^(?:\W*S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,3}(?!\d+)))+){2,}(\W+|_|$)(?!\\)",
|
new Regex(@"^(?:\W*S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,3}(?!\d+)))+){2,}(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
@ -44,6 +61,10 @@ namespace NzbDrone.Core.Parser
|
||||||
new Regex(@"^(?<title>.*?)(?:\W?S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]){1,2}(?<episode>\d{1}))+)+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>.*?)(?:\W?S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]){1,2}(?<episode>\d{1}))+)+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//Anime - Title Absolute Episode Number [SubGroup]
|
||||||
|
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{2,3}))+(?:.+?)\[(?<subgroup>.+?)\](?:\.|$)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Supports 103/113 naming
|
//Supports 103/113 naming
|
||||||
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+)\d{1})(?<episode>\d{2}(?!p|i|\d+)))+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+)\d{1})(?<episode>\d{2}(?!p|i|\d+)))+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
@ -53,7 +74,7 @@ namespace NzbDrone.Core.Parser
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Supports 1103/1113 naming
|
//Supports 1103/1113 naming
|
||||||
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+|\(|\[)\d{2})(?<episode>\d{2}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+|\(|\[|e|x)\d{2})(?<episode>(?<!e|x)\d{2}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Supports Season 01 Episode 03
|
//Supports Season 01 Episode 03
|
||||||
|
@ -62,7 +83,20 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
//Supports Season only releases
|
//Supports Season only releases
|
||||||
new Regex(@"^(?<title>.+?)\W(?:S|Season)\W?(?<season>\d{1,2}(?!\d+))(\W+|_|$)(?<extras>EXTRAS|SUBPACK)?(?!\\)",
|
new Regex(@"^(?<title>.+?)\W(?:S|Season)\W?(?<season>\d{1,2}(?!\d+))(\W+|_|$)(?<extras>EXTRAS|SUBPACK)?(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled)
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//4-digit episode number
|
||||||
|
//Episodes without a title, Single (S01E05, 1x05) AND Multi (S01E04E05, 1x04x05, etc)
|
||||||
|
new Regex(@"^(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{4}(?!\d+|i|p)))+)(\W+|_|$)(?!\\)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//Episodes with a title, Single episodes (S01E05, 1x05, etc) & Multi-episode (S01E05E06, S01E05-06, S01E05 E06, etc)
|
||||||
|
new Regex(@"^(?<title>.+?)(?:(\W|_)+S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{4}(?!\d+|i|p)))+)\W?(?!\\)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//Anime - Title Absolute Episode Number
|
||||||
|
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+e(?<absoluteepisode>\d{2,3}))+",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Regex NormalizeRegex = new Regex(@"((^|\W|_)(a|an|the|and|or|of)($|\W|_))|\W|_|(?:(?<=[^0-9]+)|\b)(?!(?:19\d{2}|20\d{2}))\d+(?=[^0-9ip]+|\b)",
|
private static readonly Regex NormalizeRegex = new Regex(@"((^|\W|_)(a|an|the|and|or|of)($|\W|_))|\W|_|(?:(?<=[^0-9]+)|\b)(?!(?:19\d{2}|20\d{2}))\d+(?=[^0-9ip]+|\b)",
|
||||||
|
@ -114,6 +148,7 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
if (match.Count != 0)
|
if (match.Count != 0)
|
||||||
{
|
{
|
||||||
|
Debug.WriteLine(regex);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = ParseMatchCollection(match);
|
var result = ParseMatchCollection(match);
|
||||||
|
@ -226,11 +261,13 @@ namespace NzbDrone.Core.Parser
|
||||||
{
|
{
|
||||||
SeasonNumber = seasons.First(),
|
SeasonNumber = seasons.First(),
|
||||||
EpisodeNumbers = new int[0],
|
EpisodeNumbers = new int[0],
|
||||||
|
AbsoluteEpisodeNumbers = new int[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (Match matchGroup in matchCollection)
|
foreach (Match matchGroup in matchCollection)
|
||||||
{
|
{
|
||||||
var episodeCaptures = matchGroup.Groups["episode"].Captures.Cast<Capture>().ToList();
|
var episodeCaptures = matchGroup.Groups["episode"].Captures.Cast<Capture>().ToList();
|
||||||
|
var absoluteEpisodeCaptures = matchGroup.Groups["absoluteepisode"].Captures.Cast<Capture>().ToList();
|
||||||
|
|
||||||
//Allows use to return a list of 0 episodes (We can handle that as a full season release)
|
//Allows use to return a list of 0 episodes (We can handle that as a full season release)
|
||||||
if (episodeCaptures.Any())
|
if (episodeCaptures.Any())
|
||||||
|
@ -246,6 +283,20 @@ namespace NzbDrone.Core.Parser
|
||||||
var count = last - first + 1;
|
var count = last - first + 1;
|
||||||
result.EpisodeNumbers = Enumerable.Range(first, count).ToArray();
|
result.EpisodeNumbers = Enumerable.Range(first, count).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (absoluteEpisodeCaptures.Any())
|
||||||
|
{
|
||||||
|
var first = Convert.ToInt32(absoluteEpisodeCaptures.First().Value);
|
||||||
|
var last = Convert.ToInt32(absoluteEpisodeCaptures.Last().Value);
|
||||||
|
|
||||||
|
if (first > last)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var count = last - first + 1;
|
||||||
|
result.AbsoluteEpisodeNumbers = Enumerable.Range(first, count).ToArray();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Check to see if this is an "Extras" or "SUBPACK" release, if it is, return NULL
|
//Check to see if this is an "Extras" or "SUBPACK" release, if it is, return NULL
|
||||||
|
@ -256,6 +307,10 @@ namespace NzbDrone.Core.Parser
|
||||||
result.FullSeason = true;
|
result.FullSeason = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result.AbsoluteEpisodeNumbers.Any() && !result.EpisodeNumbers.Any())
|
||||||
|
{
|
||||||
|
result.SeasonNumber = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
|
@ -129,6 +129,26 @@ namespace NzbDrone.Core.Parser
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parsedEpisodeInfo.IsAbsoluteNumbering())
|
||||||
|
{
|
||||||
|
foreach (var absoluteEpisodeNumber in parsedEpisodeInfo.AbsoluteEpisodeNumbers)
|
||||||
|
{
|
||||||
|
var episodeInfo = _episodeService.FindEpisode(series.Id, absoluteEpisodeNumber);
|
||||||
|
|
||||||
|
if (episodeInfo != null)
|
||||||
|
{
|
||||||
|
_logger.Info("Using absolute episode number {0} for: {1} - TVDB: {2}x{3:00}",
|
||||||
|
absoluteEpisodeNumber,
|
||||||
|
series.Title,
|
||||||
|
episodeInfo.SeasonNumber,
|
||||||
|
episodeInfo.EpisodeNumber);
|
||||||
|
result.Add(episodeInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (parsedEpisodeInfo.EpisodeNumbers == null)
|
if (parsedEpisodeInfo.EpisodeNumbers == null)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.RootFolders
|
||||||
|
{
|
||||||
|
public interface IRootFolderRepository : IBasicRepository<RootFolder>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RootFolderRepository : BasicRepository<RootFolder>, IRootFolderRepository
|
||||||
|
{
|
||||||
|
|
||||||
|
public RootFolderRepository(IDatabase database, IEventAggregator eventAggregator)
|
||||||
|
: base(database, eventAggregator)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool PublishModelEvents
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,15 +25,15 @@ namespace NzbDrone.Core.RootFolders
|
||||||
public class RootFolderService : IRootFolderService
|
public class RootFolderService : IRootFolderService
|
||||||
{
|
{
|
||||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||||
private readonly IBasicRepository<RootFolder> _rootFolderRepository;
|
private readonly IRootFolderRepository _rootFolderRepository;
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly ISeriesRepository _seriesRepository;
|
private readonly ISeriesRepository _seriesRepository;
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
|
|
||||||
private static readonly HashSet<string> SpecialFolders = new HashSet<string> { "$recycle.bin", "system volume information", "recycler" };
|
private static readonly HashSet<string> SpecialFolders = new HashSet<string> { "$recycle.bin", "system volume information", "recycler", "lost+found" };
|
||||||
|
|
||||||
|
|
||||||
public RootFolderService(IBasicRepository<RootFolder> rootFolderRepository,
|
public RootFolderService(IRootFolderRepository rootFolderRepository,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
ISeriesRepository seriesRepository,
|
ISeriesRepository seriesRepository,
|
||||||
IConfigService configService)
|
IConfigService configService)
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace NzbDrone.Core.Tv
|
||||||
public interface IEpisodeRepository : IBasicRepository<Episode>
|
public interface IEpisodeRepository : IBasicRepository<Episode>
|
||||||
{
|
{
|
||||||
Episode Find(int seriesId, int season, int episodeNumber);
|
Episode Find(int seriesId, int season, int episodeNumber);
|
||||||
|
Episode Find(int seriesId, int absoluteEpisodeNumber);
|
||||||
Episode Get(int seriesId, String date);
|
Episode Get(int seriesId, String date);
|
||||||
Episode Find(int seriesId, String date);
|
Episode Find(int seriesId, String date);
|
||||||
List<Episode> GetEpisodes(int seriesId);
|
List<Episode> GetEpisodes(int seriesId);
|
||||||
|
@ -39,6 +40,11 @@ namespace NzbDrone.Core.Tv
|
||||||
return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.SeasonNumber == season && s.EpisodeNumber == episodeNumber);
|
return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.SeasonNumber == season && s.EpisodeNumber == episodeNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Episode Find(int seriesId, int absoluteEpisodeNumber)
|
||||||
|
{
|
||||||
|
return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.AbsoluteEpisodeNumber == absoluteEpisodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
public Episode Get(int seriesId, String date)
|
public Episode Get(int seriesId, String date)
|
||||||
{
|
{
|
||||||
return Query.Single(s => s.SeriesId == seriesId && s.AirDate == date);
|
return Query.Single(s => s.SeriesId == seriesId && s.AirDate == date);
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
Episode GetEpisode(int id);
|
Episode GetEpisode(int id);
|
||||||
Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useScene = false);
|
Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useScene = false);
|
||||||
|
Episode FindEpisode(int seriesId, int absoluteEpisodeNumber);
|
||||||
Episode GetEpisode(int seriesId, String date);
|
Episode GetEpisode(int seriesId, String date);
|
||||||
Episode FindEpisode(int seriesId, String date);
|
Episode FindEpisode(int seriesId, String date);
|
||||||
List<Episode> GetEpisodeBySeries(int seriesId);
|
List<Episode> GetEpisodeBySeries(int seriesId);
|
||||||
|
@ -62,6 +63,11 @@ namespace NzbDrone.Core.Tv
|
||||||
return _episodeRepository.Find(seriesId, seasonNumber, episodeNumber);
|
return _episodeRepository.Find(seriesId, seasonNumber, episodeNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Episode FindEpisode(int seriesId, int absoluteEpisodeNumber)
|
||||||
|
{
|
||||||
|
return _episodeRepository.Find(seriesId, absoluteEpisodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
public Episode GetEpisode(int seriesId, String date)
|
public Episode GetEpisode(int seriesId, String date)
|
||||||
{
|
{
|
||||||
return _episodeRepository.Get(seriesId, date);
|
return _episodeRepository.Get(seriesId, date);
|
||||||
|
|
|
@ -106,7 +106,7 @@ namespace NzbDrone.Core.Tv
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var allSeries = _seriesService.GetAllSeries().OrderBy(c => c.LastInfoSync).ToList();
|
var allSeries = _seriesService.GetAllSeries().OrderBy(c => c.Title).ToList();
|
||||||
|
|
||||||
foreach (var series in allSeries)
|
foreach (var series in allSeries)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="FluentMigrator" version="1.1.1.0" targetFramework="net40" />
|
<package id="FluentMigrator" version="1.1.1.0" targetFramework="net40" />
|
||||||
<package id="FluentValidation" version="4.0.0.1" targetFramework="net40" />
|
<package id="FluentValidation" version="5.0.0.1" targetFramework="net40" />
|
||||||
<package id="Growl" version="0.6" />
|
<package id="Growl" version="0.6" />
|
||||||
<package id="MediaInfoNet" version="0.3" targetFramework="net40" />
|
<package id="MediaInfoNet" version="0.3" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
|
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
|
||||||
<package id="RestSharp" version="104.2.0" targetFramework="net40" />
|
<package id="RestSharp" version="104.3.3" targetFramework="net40" />
|
||||||
<package id="valueinjecter" version="2.3.3" targetFramework="net40" />
|
<package id="valueinjecter" version="2.3.3" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -22,7 +22,6 @@ namespace NzbDrone.Host
|
||||||
|
|
||||||
AutoRegisterImplementations<NzbDronePersistentConnection>();
|
AutoRegisterImplementations<NzbDronePersistentConnection>();
|
||||||
|
|
||||||
Container.Register(typeof(IBasicRepository<RootFolder>), typeof(BasicRepository<RootFolder>));
|
|
||||||
Container.Register(typeof(IBasicRepository<NamingConfig>), typeof(BasicRepository<NamingConfig>));
|
Container.Register(typeof(IBasicRepository<NamingConfig>), typeof(BasicRepository<NamingConfig>));
|
||||||
|
|
||||||
Container.Register<INancyBootstrapper, NancyBootstrapper>();
|
Container.Register<INancyBootstrapper, NancyBootstrapper>();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -89,21 +89,21 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Nancy, Version=0.20.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Nancy, Version=0.21.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Nancy.0.20.0\lib\net40\Nancy.dll</HintPath>
|
<HintPath>..\packages\Nancy.0.21.1\lib\net40\Nancy.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Nancy.Owin, Version=0.20.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Nancy.Owin, Version=0.21.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Nancy.Owin.0.20.0\lib\net40\Nancy.Owin.dll</HintPath>
|
<HintPath>..\packages\Nancy.Owin.0.21.1\lib\net40\Nancy.Owin.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace NzbDrone.Host.Owin.MiddleWare
|
||||||
{
|
{
|
||||||
SignalrDependencyResolver.Register(container);
|
SignalrDependencyResolver.Register(container);
|
||||||
|
|
||||||
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(300000);
|
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromMinutes(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Attach(IAppBuilder appBuilder)
|
public void Attach(IAppBuilder appBuilder)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
@ -72,6 +72,10 @@ namespace NzbDrone.Host.Owin
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// options.ServerFactory = new
|
||||||
|
//_host = WebApp.Start(OwinServiceProviderFactory.Create(), options, BuildApp);
|
||||||
|
//_host = WebApp.Start(options, BuildApp);
|
||||||
|
|
||||||
_host = WebApp.Start(OwinServiceProviderFactory.Create(), options, BuildApp);
|
_host = WebApp.Start(OwinServiceProviderFactory.Create(), options, BuildApp);
|
||||||
}
|
}
|
||||||
catch (TargetInvocationException ex)
|
catch (TargetInvocationException ex)
|
||||||
|
|
|
@ -5,11 +5,10 @@
|
||||||
<package id="Microsoft.Owin" version="1.1.0-beta2" targetFramework="net40" />
|
<package id="Microsoft.Owin" version="1.1.0-beta2" targetFramework="net40" />
|
||||||
<package id="Microsoft.Owin.Host.HttpListener" version="1.1.0-beta2" targetFramework="net40" />
|
<package id="Microsoft.Owin.Host.HttpListener" version="1.1.0-beta2" targetFramework="net40" />
|
||||||
<package id="Microsoft.Owin.Hosting" version="1.1.0-beta2" targetFramework="net40" />
|
<package id="Microsoft.Owin.Hosting" version="1.1.0-beta2" targetFramework="net40" />
|
||||||
<package id="Nancy" version="0.20.0" targetFramework="net40" />
|
<package id="Nancy" version="0.21.1" targetFramework="net40" />
|
||||||
<package id="Nancy.Owin" version="0.20.0" targetFramework="net40" />
|
<package id="Nancy.Owin" version="0.21.1" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="NLog.Config" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog.Schema" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="NLog.Schema" version="2.0.1.2" targetFramework="net40" />
|
|
||||||
<package id="Owin" version="1.0" targetFramework="net40" />
|
<package id="Owin" version="1.0" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -10,20 +10,28 @@ namespace NzbDrone.Integration.Test
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class EpisodeIntegrationTests : IntegrationTest
|
public class EpisodeIntegrationTests : IntegrationTest
|
||||||
{
|
{
|
||||||
|
private SeriesResource series;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
series = GivenSeriesWithEpisodes();
|
||||||
|
}
|
||||||
|
|
||||||
private SeriesResource GivenSeriesWithEpisodes()
|
private SeriesResource GivenSeriesWithEpisodes()
|
||||||
{
|
{
|
||||||
var series = Series.Lookup("archer").First();
|
var newSeries = Series.Lookup("archer").First();
|
||||||
|
|
||||||
series.QualityProfileId = 1;
|
newSeries.QualityProfileId = 1;
|
||||||
series.Path = @"C:\Test\Archer".AsOsAgnostic();
|
newSeries.Path = @"C:\Test\Archer".AsOsAgnostic();
|
||||||
|
|
||||||
series = Series.Post(series);
|
newSeries = Series.Post(newSeries);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (Episodes.GetEpisodesInSeries(series.Id).Count > 0)
|
if (Episodes.GetEpisodesInSeries(newSeries.Id).Count > 0)
|
||||||
{
|
{
|
||||||
return series;
|
return newSeries;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
|
@ -33,28 +41,33 @@ namespace NzbDrone.Integration.Test
|
||||||
[Test]
|
[Test]
|
||||||
public void should_be_able_to_get_all_episodes_in_series()
|
public void should_be_able_to_get_all_episodes_in_series()
|
||||||
{
|
{
|
||||||
var series = GivenSeriesWithEpisodes();
|
|
||||||
Episodes.GetEpisodesInSeries(series.Id).Count.Should().BeGreaterThan(0);
|
Episodes.GetEpisodesInSeries(series.Id).Count.Should().BeGreaterThan(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_be_able_to_get_a_single_episode()
|
public void should_be_able_to_get_a_single_episode()
|
||||||
{
|
{
|
||||||
var series = GivenSeriesWithEpisodes();
|
|
||||||
var episodes = Episodes.GetEpisodesInSeries(series.Id);
|
var episodes = Episodes.GetEpisodesInSeries(series.Id);
|
||||||
|
|
||||||
Episodes.Get(episodes.First().Id).Should().NotBeNull();
|
Episodes.Get(episodes.First().Id).Should().NotBeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_be_able_to_set_monitor_status_via_api()
|
public void should_be_able_to_set_monitor_status()
|
||||||
{
|
{
|
||||||
var series = GivenSeriesWithEpisodes();
|
|
||||||
var episodes = Episodes.GetEpisodesInSeries(series.Id);
|
var episodes = Episodes.GetEpisodesInSeries(series.Id);
|
||||||
var updatedEpisode = episodes.First();
|
var updatedEpisode = episodes.First();
|
||||||
updatedEpisode.Monitored = false;
|
updatedEpisode.Monitored = false;
|
||||||
|
|
||||||
Episodes.Put(updatedEpisode).Monitored.Should().BeFalse();
|
Episodes.Put(updatedEpisode).Monitored.Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown()
|
||||||
|
{
|
||||||
|
Series.Delete(series.Id);
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
using NLog;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.AspNet.SignalR.Client;
|
||||||
|
using Microsoft.AspNet.SignalR.Client.Transports;
|
||||||
|
using NLog;
|
||||||
using NLog.Config;
|
using NLog.Config;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
@ -7,7 +12,10 @@ using NzbDrone.Api.Config;
|
||||||
using NzbDrone.Api.History;
|
using NzbDrone.Api.History;
|
||||||
using NzbDrone.Api.RootFolders;
|
using NzbDrone.Api.RootFolders;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Integration.Test.Client;
|
using NzbDrone.Integration.Test.Client;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
using NzbDrone.Test.Common.Categories;
|
using NzbDrone.Test.Common.Categories;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
|
||||||
|
@ -29,6 +37,16 @@ namespace NzbDrone.Integration.Test
|
||||||
protected ClientBase<NamingConfigResource> NamingConfig;
|
protected ClientBase<NamingConfigResource> NamingConfig;
|
||||||
|
|
||||||
private NzbDroneRunner _runner;
|
private NzbDroneRunner _runner;
|
||||||
|
private List<SignalRMessage> _signalRReceived;
|
||||||
|
private Connection _signalrConnection;
|
||||||
|
|
||||||
|
protected IEnumerable<SignalRMessage> SignalRMessages
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _signalRReceived;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IntegrationTest()
|
public IntegrationTest()
|
||||||
{
|
{
|
||||||
|
@ -40,8 +58,8 @@ namespace NzbDrone.Integration.Test
|
||||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, consoleTarget));
|
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, consoleTarget));
|
||||||
}
|
}
|
||||||
|
|
||||||
//[TestFixtureSetUp]
|
[TestFixtureSetUp]
|
||||||
[SetUp]
|
//[SetUp]
|
||||||
public void SmokeTestSetup()
|
public void SmokeTestSetup()
|
||||||
{
|
{
|
||||||
_runner = new NzbDroneRunner();
|
_runner = new NzbDroneRunner();
|
||||||
|
@ -64,11 +82,61 @@ namespace NzbDrone.Integration.Test
|
||||||
NamingConfig = new ClientBase<NamingConfigResource>(RestClient, _runner.ApiKey, "config/naming");
|
NamingConfig = new ClientBase<NamingConfigResource>(RestClient, _runner.ApiKey, "config/naming");
|
||||||
}
|
}
|
||||||
|
|
||||||
//[TestFixtureTearDown]
|
[TestFixtureTearDown]
|
||||||
[TearDown]
|
//[TearDown]
|
||||||
public void SmokeTestTearDown()
|
public void SmokeTestTearDown()
|
||||||
{
|
{
|
||||||
_runner.KillAll();
|
_runner.KillAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void IntegrationSetup()
|
||||||
|
{
|
||||||
|
if (_signalrConnection != null)
|
||||||
|
{
|
||||||
|
switch (_signalrConnection.State)
|
||||||
|
{
|
||||||
|
case ConnectionState.Connected:
|
||||||
|
case ConnectionState.Connecting:
|
||||||
|
{
|
||||||
|
_signalrConnection.Stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_signalrConnection = null;
|
||||||
|
_signalRReceived = new List<SignalRMessage>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ConnectSignalR()
|
||||||
|
{
|
||||||
|
_signalRReceived = new List<SignalRMessage>();
|
||||||
|
_signalrConnection = new Connection("http://localhost:8989/signalr");
|
||||||
|
_signalrConnection.Start(new LongPollingTransport()).ContinueWith(task =>
|
||||||
|
{
|
||||||
|
if (task.IsFaulted)
|
||||||
|
{
|
||||||
|
Assert.Fail("SignalrConnection failed. {0}", task.Exception.GetBaseException());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var retryCount = 0;
|
||||||
|
|
||||||
|
while (_signalrConnection.State != ConnectionState.Connected)
|
||||||
|
{
|
||||||
|
if (retryCount > 25)
|
||||||
|
{
|
||||||
|
Assert.Fail("Couldn't establish signalr connection. State: {0}", _signalrConnection.State);
|
||||||
|
}
|
||||||
|
|
||||||
|
retryCount++;
|
||||||
|
Console.WriteLine("Connecting to signalR" + _signalrConnection.State);
|
||||||
|
Thread.Sleep(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
_signalrConnection.Received += json => _signalRReceived.Add(Json.Deserialize<SignalRMessage>(json)); ;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,12 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\FluentAssertions.2.1.0.0\lib\net40\FluentAssertions.dll</HintPath>
|
<HintPath>..\packages\FluentAssertions.2.1.0.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="FluentValidation, Version=4.0.0.1, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="FluentValidation, Version=5.0.0.1, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\FluentValidation.4.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
|
<HintPath>..\packages\FluentValidation.5.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.AspNet.SignalR.Client">
|
<Reference Include="Microsoft.AspNet.SignalR.Client, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Microsoft.AspNet.SignalR.Client.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Client.dll</HintPath>
|
<HintPath>..\packages\Microsoft.AspNet.SignalR.Client.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Client.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.Owin">
|
<Reference Include="Microsoft.Owin">
|
||||||
|
@ -59,20 +60,21 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<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="Nancy, Version=0.20.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Nancy, Version=0.21.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Nancy.0.20.0\lib\net40\Nancy.dll</HintPath>
|
<HintPath>..\packages\Nancy.0.21.1\lib\net40\Nancy.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Nancy.Owin, Version=0.20.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Nancy.Owin, Version=0.21.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Nancy.Owin.0.20.0\lib\net40\Nancy.Owin.dll</HintPath>
|
<HintPath>..\packages\Nancy.Owin.0.21.1\lib\net40\Nancy.Owin.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework">
|
<Reference Include="nunit.framework">
|
||||||
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
|
||||||
|
@ -81,9 +83,9 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
|
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RestSharp, Version=104.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="RestSharp, Version=104.3.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\RestSharp.104.2.0\lib\net4\RestSharp.dll</HintPath>
|
<HintPath>..\packages\RestSharp.104.3.3\lib\net4\RestSharp.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
@ -105,7 +107,6 @@
|
||||||
<Compile Include="EpisodeIntegrationTests.cs" />
|
<Compile Include="EpisodeIntegrationTests.cs" />
|
||||||
<Compile Include="IndexerIntegrationFixture.cs" />
|
<Compile Include="IndexerIntegrationFixture.cs" />
|
||||||
<Compile Include="IntegrationTestDirectoryInfo.cs" />
|
<Compile Include="IntegrationTestDirectoryInfo.cs" />
|
||||||
<Compile Include="NzbDroneRunner.cs" />
|
|
||||||
<Compile Include="QualityProfileIntegrationTest.cs" />
|
<Compile Include="QualityProfileIntegrationTest.cs" />
|
||||||
<Compile Include="ReleaseIntegrationTest.cs" />
|
<Compile Include="ReleaseIntegrationTest.cs" />
|
||||||
<Compile Include="IntegrationTest.cs" />
|
<Compile Include="IntegrationTest.cs" />
|
||||||
|
@ -136,6 +137,10 @@
|
||||||
<Project>{95C11A9E-56ED-456A-8447-2C89C1139266}</Project>
|
<Project>{95C11A9E-56ED-456A-8447-2C89C1139266}</Project>
|
||||||
<Name>NzbDrone.Host</Name>
|
<Name>NzbDrone.Host</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\NzbDrone.SignalR\NzbDrone.SignalR.csproj">
|
||||||
|
<Project>{7C2CC69F-5CA0-4E5C-85CB-983F9F6C3B36}</Project>
|
||||||
|
<Name>NzbDrone.SignalR</Name>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
|
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
|
||||||
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
|
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
|
||||||
<Name>NzbDrone.Test.Common</Name>
|
<Name>NzbDrone.Test.Common</Name>
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Microsoft.AspNet.SignalR.Client;
|
|
||||||
using Microsoft.AspNet.SignalR.Client.Transports;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Api.RootFolders;
|
using NzbDrone.Api.RootFolders;
|
||||||
|
|
||||||
|
@ -11,39 +8,25 @@ namespace NzbDrone.Integration.Test
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class RootFolderIntegrationTest : IntegrationTest
|
public class RootFolderIntegrationTest : IntegrationTest
|
||||||
{
|
{
|
||||||
private Connection _connection;
|
|
||||||
private List<object> _signalRReceived;
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
_signalRReceived = new List<object>();
|
|
||||||
_connection = new Connection("http://localhost:8989/signalr/rootfolder");
|
|
||||||
_connection.Start(new LongPollingTransport()).ContinueWith(task =>
|
|
||||||
{
|
|
||||||
if (task.IsFaulted)
|
|
||||||
{
|
|
||||||
Assert.Fail("SignalrConnection failed. {0}", task.Exception.GetBaseException());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_connection.Received += _connection_Received;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _connection_Received(string obj)
|
|
||||||
{
|
|
||||||
_signalRReceived.Add(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_have_no_root_folder_initially()
|
public void should_have_no_root_folder_initially()
|
||||||
{
|
{
|
||||||
RootFolders.All().Should().BeEmpty();
|
RootFolders.All().Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_add_and_delete_root_folders()
|
||||||
|
{
|
||||||
|
|
||||||
|
ConnectSignalR();
|
||||||
|
|
||||||
var rootFolder = new RootFolderResource
|
var rootFolder = new RootFolderResource
|
||||||
{
|
{
|
||||||
Path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
|
Path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
|
||||||
};
|
};
|
||||||
|
|
||||||
var postResponse = RootFolders.Post(rootFolder);
|
var postResponse = RootFolders.Post(rootFolder);
|
||||||
|
|
||||||
|
@ -56,6 +39,11 @@ namespace NzbDrone.Integration.Test
|
||||||
RootFolders.Delete(postResponse.Id);
|
RootFolders.Delete(postResponse.Id);
|
||||||
|
|
||||||
RootFolders.All().Should().BeEmpty();
|
RootFolders.All().Should().BeEmpty();
|
||||||
|
|
||||||
|
|
||||||
|
SignalRMessages.Should().Contain(c => c.Name == "rootfolder");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
||||||
<package id="FluentValidation" version="4.0.0.1" targetFramework="net40" />
|
<package id="FluentValidation" version="5.0.0.1" targetFramework="net40" />
|
||||||
<package id="Microsoft.AspNet.SignalR.Client" version="1.1.3" targetFramework="net40" />
|
<package id="Microsoft.AspNet.SignalR.Client" version="1.1.3" targetFramework="net40" />
|
||||||
<package id="Microsoft.Owin" version="1.1.0-beta2" targetFramework="net40" />
|
<package id="Microsoft.Owin" version="1.1.0-beta2" targetFramework="net40" />
|
||||||
<package id="Microsoft.Owin.Host.HttpListener" version="1.1.0-beta2" targetFramework="net40" />
|
<package id="Microsoft.Owin.Host.HttpListener" version="1.1.0-beta2" targetFramework="net40" />
|
||||||
<package id="Microsoft.Owin.Hosting" version="1.1.0-beta2" targetFramework="net40" />
|
<package id="Microsoft.Owin.Hosting" version="1.1.0-beta2" targetFramework="net40" />
|
||||||
<package id="Moq" version="4.0.10827" targetFramework="net40" />
|
<package id="Moq" version="4.0.10827" targetFramework="net40" />
|
||||||
<package id="Nancy" version="0.20.0" targetFramework="net40" />
|
<package id="Nancy" version="0.21.1" targetFramework="net40" />
|
||||||
<package id="Nancy.Owin" version="0.20.0" targetFramework="net40" />
|
<package id="Nancy.Owin" version="0.21.1" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
||||||
<package id="Owin" version="1.0" targetFramework="net40" />
|
<package id="Owin" version="1.0" targetFramework="net40" />
|
||||||
<package id="RestSharp" version="104.2.0" targetFramework="net40" />
|
<package id="RestSharp" version="104.3.3" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -39,7 +39,7 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework">
|
<Reference Include="nunit.framework">
|
||||||
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -36,8 +36,9 @@
|
||||||
<Reference Include="Microsoft.AspNet.SignalR.Core">
|
<Reference Include="Microsoft.AspNet.SignalR.Core">
|
||||||
<HintPath>..\packages\Microsoft.AspNet.SignalR.Core.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Core.dll</HintPath>
|
<HintPath>..\packages\Microsoft.AspNet.SignalR.Core.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Core.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Microsoft.AspNet.SignalR.Core" version="1.1.3" targetFramework="net40" />
|
<package id="Microsoft.AspNet.SignalR.Core" version="1.1.3" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
|
@ -54,16 +54,20 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NLog.2.0.1.2\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="RestSharp, Version=104.3.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\RestSharp.104.3.3\lib\net4\RestSharp.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
@ -82,6 +86,7 @@
|
||||||
<Compile Include="Categories\IntegrationTestAttribute.cs" />
|
<Compile Include="Categories\IntegrationTestAttribute.cs" />
|
||||||
<Compile Include="LoggingTest.cs" />
|
<Compile Include="LoggingTest.cs" />
|
||||||
<Compile Include="MockerExtensions.cs" />
|
<Compile Include="MockerExtensions.cs" />
|
||||||
|
<Compile Include="NzbDroneRunner.cs" />
|
||||||
<Compile Include="ObjectExtentions.cs" />
|
<Compile Include="ObjectExtentions.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ReflectionExtensions.cs" />
|
<Compile Include="ReflectionExtensions.cs" />
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue