1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-18 21:35:51 -04:00

Compare commits

...

26 Commits

Author SHA1 Message Date
Leonardo Galli 97095733dd Sets Branch to develop. We need to change this later. 2017-01-08 11:28:23 +01:00
Mike d08b0ce47a Integrate AppVeyor and change assembly versioning (#50)
* Change tvsearch to movie.

* Start working on AppVeyor.

* Add builds.

* MSBuild clean

* Fix.

* Added submodules.

* Add NuGet and Build.

* Restore properly.

* Proper build.

* Disable appveyor tests.

* Ignore cakebuild tools and updated build task.

* Package mono finished.

* Added osx package task.

* Less output, added osx package.

* Shut up npm.

* Actually shut up.

* Added PackageTests task.

* Added task CleanupWindowsPackage.

* Add artifacts.

* AssemblyVersion patching.

* Fix appveyor path.

* Is this a valid pattern?

* Cache node modules.

* Put in subdirectory.

* Start from v0.2.0.x to have a clean start with versions.

* Add tests.

* Tests work but disabled for now.

* Disable for real.
2017-01-08 11:03:04 +01:00
Leonardo Galli caa5a7e6b7 Merge branch 'develop' of https://github.com/galli-leo/Radarr into develop 2017-01-08 10:58:54 +01:00
Leonardo Galli 9376c02158 Movies can now be edited, even from the detail view. Fixes #42 2017-01-08 10:58:51 +01:00
Tim Turner eff34725af Merge pull request #47 from mitchellcash/remove_DS_Store
Remove all .DS_Store files
2017-01-07 20:57:10 -05:00
Tim Turner 00d4bfd712 Merge pull request #48 from fedoranimus/develop
Harden parsing of imported movie titles
2017-01-07 20:56:33 -05:00
Tim Turner 5f9e285c70 Fix issues with ", the" not trimming properly 2017-01-07 20:55:14 -05:00
Tim Turner 902824cdbd Merge remote-tracking branch 'refs/remotes/galli-leo/develop' into develop 2017-01-07 20:54:52 -05:00
Mitchell Cash d3cbf9a8ff Remove all .DS_Store files
It is now part of .gitignore so hopefully we shouldn't see these again.
2017-01-08 11:20:50 +10:00
Mike c63704ba0d Change tvsearch to movie. (#46) 2017-01-07 20:48:45 +01:00
Tim Turner da404d6435 Merge pull request #45 from fedoranimus/develop
Enables the Import UI & parses movie titles which contain year
2017-01-07 14:31:24 -05:00
Tim Turner d9a6c4f211 Update import UI & parse titles which contain years 2017-01-07 14:29:23 -05:00
Tim Turner 7436997f9b Merge remote-tracking branch 'refs/remotes/galli-leo/develop' into develop 2017-01-07 12:38:58 -05:00
Tim Turner 4c2be68549 Merge pull request #38 from fedoranimus/develop
First pass at Media Management
2017-01-07 12:31:28 -05:00
Tim Turner 6d1766d81a Update default formats 2017-01-07 12:19:26 -05:00
Tim Turner 3e676d2073 Merge remote-tracking branch 'refs/remotes/galli-leo/develop' into develop 2017-01-07 11:58:47 -05:00
Leonardo Galli 6da73d73a5 Merge pull request #40 from AeonLucid/develop
Update services url to fix auto-updater.
2017-01-07 17:40:33 +01:00
Tim Turner b9c98205e0 Merge remote-tracking branch 'refs/remotes/galli-leo/develop' into develop 2017-01-07 11:12:26 -05:00
Leonardo Galli 07d2f5b6a0 Update package.sh to support OSX AutoUpdater 2017-01-07 12:49:10 +01:00
Leonardo Galli bfa479507c Update package.sh and PathExtensions in preparation for AutoUpdater 2017-01-07 12:40:19 +01:00
Leonardo Galli 4d795e13cd Fix for movie naming config. Still kinda hacky, but works ok now. 2017-01-07 10:42:21 +01:00
AeonLucid e3bc6de734 Update services url to fix auto-updater. 2017-01-07 05:48:24 +01:00
Tim Turner 23249de728 Merge remote-tracking branch 'refs/remotes/galli-leo/develop' into develop 2017-01-06 22:51:47 -05:00
Tim Turner 05e4af9ae7 1st pass at Movie Naming
Parser is failing on the sample
2017-01-06 22:51:15 -05:00
Tim Turner 721767331b Update naming management
Still need to write BuildFileName() and BuildFilePath()
2017-01-06 19:32:19 -05:00
Tim Turner 49c7c033d9 Merge remote-tracking branch 'refs/remotes/galli-leo/develop' into develop 2017-01-06 15:31:19 -05:00
43 changed files with 1216 additions and 169 deletions
Vendored
BIN
View File
Binary file not shown.
+4
View File
@@ -138,3 +138,7 @@ Radarr_*.gz
_start _start
_temp_*/**/* _temp_*/**/*
#AppVeyor
/tools-cake/
/_artifacts/
+38
View File
@@ -0,0 +1,38 @@
version: '0.2.0.{build}'
branches:
only:
- develop
assembly_info:
patch: true
file: 'src\NzbDrone.Common\Properties\SharedAssemblyInfo.cs'
assembly_version: '{version}'
assembly_file_version: '{version}'
assembly_informational_version: '{version}-rc1'
environment:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
install:
- git submodule update --init --recursive
build_script:
- ps: ./build-appveyor.ps1
test: off
# test:
# assemblies:
# - '_tests\*Test.dll'
# categories:
# except:
# - IntegrationTest
# - AutomationTest
artifacts:
- path: '_artifacts\*.zip'
- path: '_artifacts\*.tar.gz'
cache:
- '%USERPROFILE%\.nuget\packages'
- node_modules
+303
View File
@@ -0,0 +1,303 @@
#addin "Cake.Npm"
#addin "SharpZipLib"
#addin "Cake.Compression"
// Build variables
var outputFolder = "./_output";
var outputFolderMono = outputFolder + "_mono";
var outputFolderOsx = outputFolder + "_osx";
var outputFolderOsxApp = outputFolderOsx + "_app";
var testPackageFolder = "./_tests";
var testSearchPattern = "*.Test/bin/x86/Release";
var sourceFolder = "./src";
var solutionFile = sourceFolder + "/NzbDrone.sln";
var updateFolder = outputFolder + "/NzbDrone.Update";
var updateFolderMono = outputFolderMono + "/NzbDrone.Update";
// Artifact variables
var artifactsFolder = "./_artifacts";
var artifactsFolderWindows = artifactsFolder + "/windows";
var artifactsFolderLinux = artifactsFolder + "/linux";
var artifactsFolderOsx = artifactsFolder + "/osx";
var artifactsFolderOsxApp = artifactsFolder + "/osx-app";
// Utility methods
public void RemoveEmptyFolders(string startLocation) {
foreach (var directory in System.IO.Directory.GetDirectories(startLocation))
{
RemoveEmptyFolders(directory);
if (System.IO.Directory.GetFiles(directory).Length == 0 &&
System.IO.Directory.GetDirectories(directory).Length == 0)
{
DeleteDirectory(directory, false);
}
}
}
public void CleanFolder(string path, bool keepConfigFiles) {
DeleteFiles(path + "/**/*.transform");
if (!keepConfigFiles) {
DeleteFiles(path + "/**/*.dll.config");
}
DeleteFiles(path + "/**/FluentValidation.resources.dll");
DeleteFiles(path + "/**/App.config");
DeleteFiles(path + "/**/*.less");
DeleteFiles(path + "/**/*.vshost.exe");
DeleteFiles(path + "/**/*.dylib");
RemoveEmptyFolders(path);
}
public void CreateMdbs(string path) {
foreach (var file in System.IO.Directory.EnumerateFiles(path, "*.pdb", System.IO.SearchOption.AllDirectories)) {
var actualFile = file.Substring(0, file.Length - 4);
if (FileExists(actualFile + ".exe")) {
StartProcess("./tools/pdb2mdb/pdb2mdb.exe", new ProcessSettings()
.WithArguments(args => args.Append(actualFile + ".exe")));
}
if (FileExists(actualFile + ".dll")) {
StartProcess("./tools/pdb2mdb/pdb2mdb.exe", new ProcessSettings()
.WithArguments(args => args.Append(actualFile + ".dll")));
}
}
}
// Build Tasks
Task("Compile").Does(() => {
// Build
if (DirectoryExists(outputFolder)) {
DeleteDirectory(outputFolder, true);
}
MSBuild(solutionFile, config =>
config.UseToolVersion(MSBuildToolVersion.VS2015)
.WithTarget("Clean")
.SetVerbosity(Verbosity.Minimal));
NuGetRestore(solutionFile);
MSBuild(solutionFile, config =>
config.UseToolVersion(MSBuildToolVersion.VS2015)
.SetPlatformTarget(PlatformTarget.x86)
.SetConfiguration("Release")
.WithProperty("AllowedReferenceRelatedFileExtensions", new string[] { ".pdb" })
.WithTarget("Build")
.SetVerbosity(Verbosity.Minimal));
CleanFolder(outputFolder, false);
// Add JsonNet
DeleteFiles(outputFolder + "/Newtonsoft.Json.*");
CopyFiles(sourceFolder + "/packages/Newtonsoft.Json.*/lib/net35/*.dll", outputFolder);
CopyFiles(sourceFolder + "/packages/Newtonsoft.Json.*/lib/net35/*.dll", updateFolder);
// Remove Mono stuff
DeleteFile(outputFolder + "/Mono.Posix.dll");
});
Task("Gulp").Does(() => {
Npm
.WithLogLevel(NpmLogLevel.Silent)
.FromPath(".")
.Install()
.RunScript("build");
});
Task("PackageMono").Does(() => {
// Start mono package
if (DirectoryExists(outputFolderMono)) {
DeleteDirectory(outputFolderMono, true);
}
CopyDirectory(outputFolder, outputFolderMono);
// Create MDBs
CreateMdbs(outputFolderMono);
// Remove PDBs
DeleteFiles(outputFolderMono + "/**/*.pdb");
// Remove service helpers
DeleteFiles(outputFolderMono + "/ServiceUninstall.*");
DeleteFiles(outputFolderMono + "/ServiceInstall.*");
// Remove native windows binaries
DeleteFiles(outputFolderMono + "/sqlite3.*");
DeleteFiles(outputFolderMono + "/MediaInfo.*");
// Adding NzbDrone.Core.dll.config (for dllmap)
CopyFile(sourceFolder + "/NzbDrone.Core/NzbDrone.Core.dll.config", outputFolderMono + "/NzbDrone.Core.dll.config");
// Adding CurlSharp.dll.config (for dllmap)
CopyFile(sourceFolder + "/NzbDrone.Common/CurlSharp.dll.config", outputFolderMono + "/CurlSharp.dll.config");
// Renaming Radarr.Console.exe to Radarr.exe
DeleteFiles(outputFolderMono + "/Radarr.exe*");
MoveFile(outputFolderMono + "/Radarr.Console.exe", outputFolderMono + "/Radarr.exe");
MoveFile(outputFolderMono + "/Radarr.Console.exe.config", outputFolderMono + "/Radarr.exe.config");
MoveFile(outputFolderMono + "/Radarr.Console.exe.mdb", outputFolderMono + "/Radarr.exe.mdb");
// Remove NzbDrone.Windows.*
DeleteFiles(outputFolderMono + "/NzbDrone.Windows.*");
// Adding NzbDrone.Mono to updatePackage
CopyFiles(outputFolderMono + "/NzbDrone.Mono.*", updateFolderMono);
});
Task("PackageOsx").Does(() => {
// Start osx package
if (DirectoryExists(outputFolderOsx)) {
DeleteDirectory(outputFolderOsx, true);
}
CopyDirectory(outputFolderMono, outputFolderOsx);
// Adding sqlite dylibs
CopyFiles(sourceFolder + "/Libraries/Sqlite/*.dylib", outputFolderOsx);
// Adding MediaInfo dylib
CopyFiles(sourceFolder + "/Libraries/MediaInfo/*.dylib", outputFolderOsx);
// Adding Startup script
CopyFile("./osx/Sonarr", outputFolderOsx + "/Sonarr");
});
Task("PackageOsxApp").Does(() => {
// Start osx app package
if (DirectoryExists(outputFolderOsxApp)) {
DeleteDirectory(outputFolderOsxApp, true);
}
CreateDirectory(outputFolderOsxApp);
// Copy osx package files
CopyDirectory("./osx/Radarr.app", outputFolderOsxApp + "/Radarr.app");
CopyDirectory(outputFolderOsx, outputFolderOsxApp + "/Radarr.app/Contents/MacOS");
});
Task("PackageTests").Does(() => {
// Start tests package
if (DirectoryExists(testPackageFolder)) {
DeleteDirectory(testPackageFolder, true);
}
CreateDirectory(testPackageFolder);
// Copy tests
CopyFiles(sourceFolder + "/" + testSearchPattern + "/*", testPackageFolder);
foreach (var directory in System.IO.Directory.GetDirectories(sourceFolder, "*.Test")) {
var releaseDirectory = directory + "/bin/x86/Release";
if (DirectoryExists(releaseDirectory)) {
foreach (var releaseSubDirectory in System.IO.Directory.GetDirectories(releaseDirectory)) {
Information(System.IO.Path.GetDirectoryName(releaseSubDirectory));
CopyDirectory(releaseSubDirectory, testPackageFolder + "/" + System.IO.Path.GetFileName(releaseSubDirectory));
}
}
}
// Install NUnit.ConsoleRunner
NuGetInstall("NUnit.ConsoleRunner", new NuGetInstallSettings {
Version = "3.2.0",
OutputDirectory = testPackageFolder
});
// Copy dlls
CopyFiles(outputFolder + "/*.dll", testPackageFolder);
// Copy scripts
CopyFiles("./*.sh", testPackageFolder);
// Create MDBs for tests
CreateMdbs(testPackageFolder);
// Remove config
DeleteFiles(testPackageFolder + "/*.log.config");
// Clean
CleanFolder(testPackageFolder, true);
// Adding NzbDrone.Core.dll.config (for dllmap)
CopyFile(sourceFolder + "/NzbDrone.Core/NzbDrone.Core.dll.config", testPackageFolder + "/NzbDrone.Core.dll.config");
// Adding CurlSharp.dll.config (for dllmap)
CopyFile(sourceFolder + "/NzbDrone.Common/CurlSharp.dll.config", testPackageFolder + "/CurlSharp.dll.config");
// Adding CurlSharp libraries
CopyFiles(sourceFolder + "/ExternalModules/CurlSharp/libs/i386/*", testPackageFolder);
});
Task("CleanupWindowsPackage").Does(() => {
// Remove mono
DeleteFiles(outputFolder + "/NzbDrone.Mono.*");
// Adding NzbDrone.Windows to updatePackage
CopyFiles(outputFolder + "/NzbDrone.Windows.*", updateFolder);
});
Task("Build")
.IsDependentOn("Compile")
.IsDependentOn("Gulp")
.IsDependentOn("PackageMono")
.IsDependentOn("PackageOsx")
.IsDependentOn("PackageOsxApp")
.IsDependentOn("PackageTests")
.IsDependentOn("CleanupWindowsPackage");
// Build Artifacts
Task("CleanArtifacts").Does(() => {
if (DirectoryExists(artifactsFolder)) {
DeleteDirectory(artifactsFolder, true);
}
CreateDirectory(artifactsFolder);
});
Task("ArtifactsWindows").Does(() => {
CopyDirectory(outputFolder, artifactsFolderWindows + "/Radarr");
});
Task("ArtifactsLinux").Does(() => {
CopyDirectory(outputFolderMono, artifactsFolderLinux + "/Radarr");
});
Task("ArtifactsOsx").Does(() => {
CopyDirectory(outputFolderOsx, artifactsFolderOsx + "/Radarr");
});
Task("ArtifactsOsxApp").Does(() => {
CopyDirectory(outputFolderOsxApp, artifactsFolderOsxApp);
});
Task("CompressArtifacts").Does(() => {
var prefix = "";
if (AppVeyor.IsRunningOnAppVeyor) {
prefix += AppVeyor.Environment.Repository.Branch + ".";
prefix += AppVeyor.Environment.Build.Version + ".";
}
Zip(artifactsFolderWindows, artifactsFolder + "/Radarr." + prefix + "windows.zip");
GZipCompress(artifactsFolderLinux, artifactsFolder + "/Radarr." + prefix + "linux.tar.gz");
GZipCompress(artifactsFolderOsx, artifactsFolder + "/Radarr." + prefix + "osx.tar.gz");
Zip(artifactsFolderOsxApp, artifactsFolder + "/Radarr." + prefix + "osx-app.zip");
});
Task("Artifacts")
.IsDependentOn("CleanArtifacts")
.IsDependentOn("ArtifactsWindows")
.IsDependentOn("ArtifactsLinux")
.IsDependentOn("ArtifactsOsx")
.IsDependentOn("ArtifactsOsxApp")
.IsDependentOn("CompressArtifacts");
// Run
RunTarget("Build");
RunTarget("Artifacts");
+184
View File
@@ -0,0 +1,184 @@
##########################################################################
# This is the Cake bootstrapper script for PowerShell.
# This file was downloaded from https://github.com/cake-build/resources
# Feel free to change this file to fit your needs.
##########################################################################
<#
.SYNOPSIS
This is a Powershell script to bootstrap a Cake build.
.DESCRIPTION
This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
and execute your Cake build script with the parameters you provide.
.PARAMETER Script
The build script to execute.
.PARAMETER Target
The build script target to run.
.PARAMETER Configuration
The build configuration to use.
.PARAMETER Verbosity
Specifies the amount of information to be displayed.
.PARAMETER Experimental
Tells Cake to use the latest Roslyn release.
.PARAMETER WhatIf
Performs a dry run of the build script.
No tasks will be executed.
.PARAMETER Mono
Tells Cake to use the Mono scripting engine.
.PARAMETER SkipToolPackageRestore
Skips restoring of packages.
.PARAMETER ScriptArgs
Remaining arguments are added here.
.LINK
http://cakebuild.net
#>
[CmdletBinding()]
Param(
[string]$Script = "build-appveyor.cake",
[string]$Target = "Default",
[ValidateSet("Release", "Debug")]
[string]$Configuration = "Release",
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
[string]$Verbosity = "Verbose",
[switch]$Experimental,
[Alias("DryRun","Noop")]
[switch]$WhatIf,
[switch]$Mono,
[switch]$SkipToolPackageRestore,
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
[string[]]$ScriptArgs
)
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
function MD5HashFile([string] $filePath)
{
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
{
return $null
}
[System.IO.Stream] $file = $null;
[System.Security.Cryptography.MD5] $md5 = $null;
try
{
$md5 = [System.Security.Cryptography.MD5]::Create()
$file = [System.IO.File]::OpenRead($filePath)
return [System.BitConverter]::ToString($md5.ComputeHash($file))
}
finally
{
if ($file -ne $null)
{
$file.Dispose()
}
}
}
Write-Host "Preparing to run build script..."
if(!$PSScriptRoot){
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
}
$TOOLS_DIR = Join-Path $PSScriptRoot "tools-cake"
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
# Should we use mono?
$UseMono = "";
if($Mono.IsPresent) {
Write-Verbose -Message "Using the Mono based scripting engine."
$UseMono = "-mono"
}
# Should we use the new Roslyn?
$UseExperimental = "";
if($Experimental.IsPresent -and !($Mono.IsPresent)) {
Write-Verbose -Message "Using experimental version of Roslyn."
$UseExperimental = "-experimental"
}
# Is this a dry run?
$UseDryRun = "";
if($WhatIf.IsPresent) {
$UseDryRun = "-dryrun"
}
# Make sure tools folder exists
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
Write-Verbose -Message "Creating tools directory..."
New-Item -Path $TOOLS_DIR -Type directory | out-null
}
# Make sure that packages.config exist.
if (!(Test-Path $PACKAGES_CONFIG)) {
Write-Verbose -Message "Downloading packages.config..."
try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
Throw "Could not download packages.config."
}
}
# Try find NuGet.exe in path if not exists
if (!(Test-Path $NUGET_EXE)) {
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) }
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
$NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
}
}
# Try download NuGet.exe if not exists
if (!(Test-Path $NUGET_EXE)) {
Write-Verbose -Message "Downloading NuGet.exe..."
try {
(New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
} catch {
Throw "Could not download NuGet.exe."
}
}
# Save nuget.exe path to environment to be available to child processed
$ENV:NUGET_EXE = $NUGET_EXE
# Restore tools from NuGet?
if(-Not $SkipToolPackageRestore.IsPresent) {
Push-Location
Set-Location $TOOLS_DIR
# Check for changes in packages.config and remove installed tools if true.
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
Write-Verbose -Message "Missing or changed package.config hash..."
Remove-Item * -Recurse -Exclude packages.config,nuget.exe
}
Write-Verbose -Message "Restoring tools from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
if ($LASTEXITCODE -ne 0) {
Throw "An error occured while restoring NuGet tools."
}
else
{
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
}
Write-Verbose -Message ($NuGetOutput | out-string)
Pop-Location
}
# Make sure that Cake has been installed.
if (!(Test-Path $CAKE_EXE)) {
Throw "Could not find Cake.exe at $CAKE_EXE"
}
# Start Cake
Write-Host "Running build script..."
Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs"
exit $LASTEXITCODE
+7 -6
View File
@@ -39,13 +39,14 @@ cp -r $outputFolderMono/ Radarr_Mono_$VERSION
cp -r $outputFolderOsxApp/ Radarr_OSX_$VERSION cp -r $outputFolderOsxApp/ Radarr_OSX_$VERSION
if [ $runtime = "dotnet" ] ; then if [ $runtime = "dotnet" ] ; then
./7za.exe a Radarr_Windows_$VERSION.zip Radarr_Windows_$VERSION ./7za.exe a Radarr_Windows_$VERSION.zip ./Radarr_Windows_$VERSION/*
./7za.exe a -ttar -so Radarr_Mono_$VERSION.tar Radarr_Mono_$VERSION | ./7za.exe a -si Radarr_Mono_$VERSION.tar.gz ./7za.exe a -ttar -so Radarr_Mono_$VERSION.tar ./Radarr_Mono_$VERSION/* | ./7za.exe a -si Radarr_Mono_$VERSION.tar.gz
./7za.exe a -ttar -so Radarr_OSX_$VERSION.tar Radarr_OSX_$VERSION | ./7za.exe a -si Radarr_OSX_$VERSION.tar.gz ./7za.exe a -ttar -so Radarr_OSX_$VERSION.tar ./_output_osx/* | ./7za.exe a -si Radarr_OSX_$VERSION.tar.gz
./7za.exe a -ttar -so Radarr_OSX_App_$VERSION.tar ./_output_osx_app/* | ./7za.exe a -si Radarr_OSX_App_$VERSION.tar.gz
else else
zip -r Radarr_Windows_$VERSION.zip Radarr_Windows_$VERSION >& /dev/null zip -r Radarr_Windows_$VERSION.zip Radarr_Windows_$VERSION/* >& /dev/null
zip -r Radarr_Mono_$VERSION.zip Radarr_Mono_$VERSION >& /dev/null zip -r Radarr_Mono_$VERSION.zip Radarr_Mono_$VERSION/* >& /dev/null #TODO update for tar.gz
zip -r Radarr_OSX_$VERSION.zip Radarr_OSX_$VERSION >& /dev/null zip -r Radarr_OSX_$VERSION_App.zip Radarr_OSX_$VERSION/* >& /dev/null
fi fi
ftp -n ftp.leonardogalli.ch << END_SCRIPT ftp -n ftp.leonardogalli.ch << END_SCRIPT
passive passive
BIN
View File
Binary file not shown.
+57 -32
View File
@@ -39,6 +39,8 @@ namespace NzbDrone.Api.Config
SharedValidator.RuleFor(c => c.AnimeEpisodeFormat).ValidAnimeEpisodeFormat(); SharedValidator.RuleFor(c => c.AnimeEpisodeFormat).ValidAnimeEpisodeFormat();
SharedValidator.RuleFor(c => c.SeriesFolderFormat).ValidSeriesFolderFormat(); SharedValidator.RuleFor(c => c.SeriesFolderFormat).ValidSeriesFolderFormat();
SharedValidator.RuleFor(c => c.SeasonFolderFormat).ValidSeasonFolderFormat(); SharedValidator.RuleFor(c => c.SeasonFolderFormat).ValidSeasonFolderFormat();
SharedValidator.RuleFor(c => c.StandardMovieFormat).ValidMovieFormat();
SharedValidator.RuleFor(c => c.MovieFolderFormat).ValidMovieFolderFormat();
} }
private void UpdateNamingConfig(NamingConfigResource resource) private void UpdateNamingConfig(NamingConfigResource resource)
@@ -54,7 +56,13 @@ namespace NzbDrone.Api.Config
var nameSpec = _namingConfigService.GetConfig(); var nameSpec = _namingConfigService.GetConfig();
var resource = nameSpec.ToResource(); var resource = nameSpec.ToResource();
if (resource.StandardEpisodeFormat.IsNotNullOrWhiteSpace()) //if (resource.StandardEpisodeFormat.IsNotNullOrWhiteSpace())
//{
// var basicConfig = _filenameBuilder.GetBasicNamingConfig(nameSpec);
// basicConfig.AddToResource(resource);
//}
if (resource.StandardMovieFormat.IsNotNullOrWhiteSpace())
{ {
var basicConfig = _filenameBuilder.GetBasicNamingConfig(nameSpec); var basicConfig = _filenameBuilder.GetBasicNamingConfig(nameSpec);
basicConfig.AddToResource(resource); basicConfig.AddToResource(resource);
@@ -73,39 +81,50 @@ namespace NzbDrone.Api.Config
var nameSpec = config.ToModel(); var nameSpec = config.ToModel();
var sampleResource = new NamingSampleResource(); var sampleResource = new NamingSampleResource();
var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec); //var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec);
var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec); //var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec);
var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec); //var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec);
var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec); //var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec); //var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
sampleResource.SingleEpisodeExample = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult) != null var movieSampleResult = _filenameSampleService.GetMovieSample(nameSpec);
? "Invalid format"
: singleEpisodeSampleResult.FileName;
sampleResource.MultiEpisodeExample = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult) != null //sampleResource.SingleEpisodeExample = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult) != null
? "Invalid format" // ? "Invalid format"
: multiEpisodeSampleResult.FileName; // : singleEpisodeSampleResult.FileName;
sampleResource.DailyEpisodeExample = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult) != null //sampleResource.MultiEpisodeExample = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult) != null
? "Invalid format" // ? "Invalid format"
: dailyEpisodeSampleResult.FileName; // : multiEpisodeSampleResult.FileName;
sampleResource.AnimeEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult) != null //sampleResource.DailyEpisodeExample = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult) != null
? "Invalid format" // ? "Invalid format"
: animeEpisodeSampleResult.FileName; // : dailyEpisodeSampleResult.FileName;
sampleResource.AnimeMultiEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult) != null //sampleResource.AnimeEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult) != null
? "Invalid format" // ? "Invalid format"
: animeMultiEpisodeSampleResult.FileName; // : animeEpisodeSampleResult.FileName;
sampleResource.SeriesFolderExample = nameSpec.SeriesFolderFormat.IsNullOrWhiteSpace() //sampleResource.AnimeMultiEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult) != null
// ? "Invalid format"
// : animeMultiEpisodeSampleResult.FileName;
sampleResource.MovieExample = nameSpec.StandardMovieFormat.IsNullOrWhiteSpace()
? "Invalid Format"
: movieSampleResult.FileName;
//sampleResource.SeriesFolderExample = nameSpec.SeriesFolderFormat.IsNullOrWhiteSpace()
// ? "Invalid format"
// : _filenameSampleService.GetSeriesFolderSample(nameSpec);
//sampleResource.SeasonFolderExample = nameSpec.SeasonFolderFormat.IsNullOrWhiteSpace()
// ? "Invalid format"
// : _filenameSampleService.GetSeasonFolderSample(nameSpec);
sampleResource.MovieFolderExample = nameSpec.MovieFolderFormat.IsNullOrWhiteSpace()
? "Invalid format" ? "Invalid format"
: _filenameSampleService.GetSeriesFolderSample(nameSpec); : _filenameSampleService.GetMovieFolderSample(nameSpec);
sampleResource.SeasonFolderExample = nameSpec.SeasonFolderFormat.IsNullOrWhiteSpace()
? "Invalid format"
: _filenameSampleService.GetSeasonFolderSample(nameSpec);
return sampleResource.AsResponse(); return sampleResource.AsResponse();
} }
@@ -118,19 +137,25 @@ namespace NzbDrone.Api.Config
var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec); var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec); var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
var movieSampleResult = _filenameSampleService.GetMovieSample(nameSpec);
var singleEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult); var singleEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult);
var multiEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult); var multiEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult);
var dailyEpisodeValidationResult = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult); var dailyEpisodeValidationResult = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult);
var animeEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult); var animeEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult);
var animeMultiEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult); var animeMultiEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult);
//var standardMovieValidationResult = _filenameValidationService.ValidateMovieFilename(movieSampleResult); For now, let's hope the user is not stupid enough :/
var validationFailures = new List<ValidationFailure>(); var validationFailures = new List<ValidationFailure>();
validationFailures.AddIfNotNull(singleEpisodeValidationResult); //validationFailures.AddIfNotNull(singleEpisodeValidationResult);
validationFailures.AddIfNotNull(multiEpisodeValidationResult); //validationFailures.AddIfNotNull(multiEpisodeValidationResult);
validationFailures.AddIfNotNull(dailyEpisodeValidationResult); //validationFailures.AddIfNotNull(dailyEpisodeValidationResult);
validationFailures.AddIfNotNull(animeEpisodeValidationResult); //validationFailures.AddIfNotNull(animeEpisodeValidationResult);
validationFailures.AddIfNotNull(animeMultiEpisodeValidationResult); //validationFailures.AddIfNotNull(animeMultiEpisodeValidationResult);
//validationFailures.AddIfNotNull(standardMovieValidationResult);
if (validationFailures.Any()) if (validationFailures.Any())
{ {
@@ -7,6 +7,8 @@ namespace NzbDrone.Api.Config
{ {
public bool RenameEpisodes { get; set; } public bool RenameEpisodes { get; set; }
public bool ReplaceIllegalCharacters { get; set; } public bool ReplaceIllegalCharacters { get; set; }
public string StandardMovieFormat { get; set; }
public string MovieFolderFormat { get; set; }
public int MultiEpisodeStyle { get; set; } public int MultiEpisodeStyle { get; set; }
public string StandardEpisodeFormat { get; set; } public string StandardEpisodeFormat { get; set; }
public string DailyEpisodeFormat { get; set; } public string DailyEpisodeFormat { get; set; }
@@ -36,7 +38,9 @@ namespace NzbDrone.Api.Config
DailyEpisodeFormat = model.DailyEpisodeFormat, DailyEpisodeFormat = model.DailyEpisodeFormat,
AnimeEpisodeFormat = model.AnimeEpisodeFormat, AnimeEpisodeFormat = model.AnimeEpisodeFormat,
SeriesFolderFormat = model.SeriesFolderFormat, SeriesFolderFormat = model.SeriesFolderFormat,
SeasonFolderFormat = model.SeasonFolderFormat SeasonFolderFormat = model.SeasonFolderFormat,
StandardMovieFormat = model.StandardMovieFormat,
MovieFolderFormat = model.MovieFolderFormat
//IncludeSeriesTitle //IncludeSeriesTitle
//IncludeEpisodeTitle //IncludeEpisodeTitle
//IncludeQuality //IncludeQuality
@@ -64,12 +68,14 @@ namespace NzbDrone.Api.Config
RenameEpisodes = resource.RenameEpisodes, RenameEpisodes = resource.RenameEpisodes,
ReplaceIllegalCharacters = resource.ReplaceIllegalCharacters, ReplaceIllegalCharacters = resource.ReplaceIllegalCharacters,
MultiEpisodeStyle = resource.MultiEpisodeStyle, //MultiEpisodeStyle = resource.MultiEpisodeStyle,
StandardEpisodeFormat = resource.StandardEpisodeFormat, //StandardEpisodeFormat = resource.StandardEpisodeFormat,
DailyEpisodeFormat = resource.DailyEpisodeFormat, //DailyEpisodeFormat = resource.DailyEpisodeFormat,
AnimeEpisodeFormat = resource.AnimeEpisodeFormat, //AnimeEpisodeFormat = resource.AnimeEpisodeFormat,
SeriesFolderFormat = resource.SeriesFolderFormat, //SeriesFolderFormat = resource.SeriesFolderFormat,
SeasonFolderFormat = resource.SeasonFolderFormat //SeasonFolderFormat = resource.SeasonFolderFormat,
StandardMovieFormat = resource.StandardMovieFormat,
MovieFolderFormat = resource.MovieFolderFormat
}; };
} }
} }
@@ -9,5 +9,8 @@
public string AnimeMultiEpisodeExample { get; set; } public string AnimeMultiEpisodeExample { get; set; }
public string SeriesFolderExample { get; set; } public string SeriesFolderExample { get; set; }
public string SeasonFolderExample { get; set; } public string SeasonFolderExample { get; set; }
public string MovieExample { get; set; }
public string MovieFolderExample { get; set; }
} }
} }
@@ -14,7 +14,7 @@ namespace NzbDrone.Common.Cloud
{ {
public SonarrCloudRequestBuilder() public SonarrCloudRequestBuilder()
{ {
Services = new HttpRequestBuilder("http://services.sonarr.tv/v1/") Services = new HttpRequestBuilder("https://radarr.aeonlucid.com/v1/")
.CreateFactory(); .CreateFactory();
SkyHookTvdb = new HttpRequestBuilder("http://skyhook.sonarr.tv/v1/tvdb/{route}/{language}/") SkyHookTvdb = new HttpRequestBuilder("http://skyhook.sonarr.tv/v1/tvdb/{route}/{language}/")
@@ -26,12 +26,11 @@ namespace NzbDrone.Common.Cloud
.CreateFactory(); .CreateFactory();
TMDBSingle = new HttpRequestBuilder("https://api.themoviedb.org/3/{route}") TMDBSingle = new HttpRequestBuilder("https://api.themoviedb.org/3/{route}")
.AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212") .AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212")
.CreateFactory(); .CreateFactory();
} }
public IHttpRequestBuilderFactory Services { get; private set; } public IHttpRequestBuilderFactory Services { get; private set; }
public IHttpRequestBuilderFactory SkyHookTvdb { get; private set; } public IHttpRequestBuilderFactory SkyHookTvdb { get; private set; }
public IHttpRequestBuilderFactory TMDB { get; private set; } public IHttpRequestBuilderFactory TMDB { get; private set; }
public IHttpRequestBuilderFactory TMDBSingle { get; private set; } public IHttpRequestBuilderFactory TMDBSingle { get; private set; }
@@ -17,7 +17,7 @@ namespace NzbDrone.Common.Extensions
private const string BACKUP_FOLDER = "Backups"; private const string BACKUP_FOLDER = "Backups";
private static readonly string UPDATE_SANDBOX_FOLDER_NAME = "nzbdrone_update" + Path.DirectorySeparatorChar; private static readonly string UPDATE_SANDBOX_FOLDER_NAME = "nzbdrone_update" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "NzbDrone" + Path.DirectorySeparatorChar; private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "";
private static readonly string UPDATE_BACKUP_FOLDER_NAME = "nzbdrone_backup" + Path.DirectorySeparatorChar; private static readonly string UPDATE_BACKUP_FOLDER_NAME = "nzbdrone_backup" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_BACKUP_APPDATA_FOLDER_NAME = "nzbdrone_appdata_backup" + Path.DirectorySeparatorChar; private static readonly string UPDATE_BACKUP_APPDATA_FOLDER_NAME = "nzbdrone_appdata_backup" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_CLIENT_FOLDER_NAME = "NzbDrone.Update" + Path.DirectorySeparatorChar; private static readonly string UPDATE_CLIENT_FOLDER_NAME = "NzbDrone.Update" + Path.DirectorySeparatorChar;
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
using System.Data;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(109)]
public class add_movie_formats_to_naming_config : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("NamingConfig").AddColumn("StandardMovieFormat").AsString().Nullable();
Alter.Table("NamingConfig").AddColumn("MovieFolderFormat").AsString().Nullable();
Execute.WithConnection(ConvertConfig);
}
private void ConvertConfig(IDbConnection conn, IDbTransaction tran)
{
using (IDbCommand namingConfigCmd = conn.CreateCommand())
{
namingConfigCmd.Transaction = tran;
namingConfigCmd.CommandText = @"SELECT * FROM NamingConfig LIMIT 1";
using (IDataReader namingConfigReader = namingConfigCmd.ExecuteReader())
{
while (namingConfigReader.Read())
{
// Output Settings
var movieTitlePattern = "";
var movieYearPattern = "({Release Year})";
var qualityFormat = "[{Quality Title}]";
movieTitlePattern = "{Movie Title}";
var standardMovieFormat = string.Format("{0} {1} {2}", movieTitlePattern,
movieYearPattern,
qualityFormat);
var movieFolderFormat = string.Format("{0} {1}", movieTitlePattern, movieYearPattern);
using (IDbCommand updateCmd = conn.CreateCommand())
{
var text = string.Format("UPDATE NamingConfig " +
"SET StandardMovieFormat = '{0}', " +
"MovieFolderFormat = '{1}'",
standardMovieFormat,
movieFolderFormat);
updateCmd.Transaction = tran;
updateCmd.CommandText = text;
updateCmd.ExecuteNonQuery();
}
}
}
}
}
}
}
@@ -112,9 +112,9 @@ namespace NzbDrone.Core.Indexers.Newznab
var capabilities = _capabilitiesProvider.GetCapabilities(Settings); var capabilities = _capabilitiesProvider.GetCapabilities(Settings);
if (capabilities.SupportedTvSearchParameters != null) if (capabilities.SupportedMovieSearchParamters != null)
{ {
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories.Concat(Settings.AnimeCategories), "tvsearch", "")); pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories.Concat(Settings.AnimeCategories), "movie", ""));
} }
return pageableRequests; return pageableRequests;
@@ -12,6 +12,7 @@ using NzbDrone.Core.MetadataSource.SkyHook.Resource;
using NzbDrone.Core.MetadataSource; using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Text.RegularExpressions;
namespace NzbDrone.Core.MetadataSource.SkyHook namespace NzbDrone.Core.MetadataSource.SkyHook
{ {
@@ -175,9 +176,41 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
return movie; return movie;
} }
private string[] SeparateYearFromTitle(string title)
{
var yearPattern = @"((?:19|20)\d{2})";
var newTitle = title;
var substrings = Regex.Split(title, yearPattern);
var year = "";
if (substrings.Length > 1) {
newTitle = substrings[0].TrimEnd("(");
year = substrings[1];
}
return new[] { newTitle.Trim(), year.Trim() };
}
private string StripTrailingTheFromTitle(string title)
{
if(title.EndsWith(",the"))
{
title = title.Substring(title.Length - 4);
} else if(title.EndsWith(", the"))
{
title = title.Substring(title.Length - 5);
}
return title;
}
public List<Movie> SearchForNewMovie(string title) public List<Movie> SearchForNewMovie(string title)
{ {
var lowerTitle = title.ToLower(); var lowerTitle = title.ToLower();
var yearCheck = SeparateYearFromTitle(lowerTitle); // TODO: Make this much less hacky!
lowerTitle = yearCheck[0];
var yearTerm = yearCheck[1];
lowerTitle = StripTrailingTheFromTitle(lowerTitle);
if (lowerTitle.StartsWith("imdb:") || lowerTitle.StartsWith("imdbid:")) if (lowerTitle.StartsWith("imdb:") || lowerTitle.StartsWith("imdbid:"))
{ {
@@ -209,6 +242,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
.SetSegment("id", "movie") .SetSegment("id", "movie")
.SetSegment("secondaryRoute", "") .SetSegment("secondaryRoute", "")
.AddQueryParam("query", searchTerm) .AddQueryParam("query", searchTerm)
.AddQueryParam("year", yearTerm)
.AddQueryParam("include_adult", false) .AddQueryParam("include_adult", false)
.Build(); .Build();
+1
View File
@@ -286,6 +286,7 @@
<Compile Include="Datastore\Migration\098_remove_titans_of_tv.cs"> <Compile Include="Datastore\Migration\098_remove_titans_of_tv.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Datastore\Migration\109_add_movie_formats_to_naming_config.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationDbFactory.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationDbFactory.cs" />
+175 -44
View File
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@@ -24,7 +24,7 @@ namespace NzbDrone.Core.Organizer
BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec); BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec);
string GetSeriesFolder(Series series, NamingConfig namingConfig = null); string GetSeriesFolder(Series series, NamingConfig namingConfig = null);
string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null); string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null);
string GetMovieFolder(Movie movie); string GetMovieFolder(Movie movie, NamingConfig namingConfig = null);
} }
public class FileNameBuilder : IBuildFileNames public class FileNameBuilder : IBuildFileNames
@@ -58,6 +58,9 @@ namespace NzbDrone.Core.Organizer
public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})", public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{(?:Movie)(?<separator>[- ._])(Clean)?Title\})",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled); private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled);
private static readonly Regex TrimSeparatorsRegex = new Regex(@"[- ._]$", RegexOptions.Compiled); private static readonly Regex TrimSeparatorsRegex = new Regex(@"[- ._]$", RegexOptions.Compiled);
@@ -76,6 +79,7 @@ namespace NzbDrone.Core.Organizer
{ {
_namingConfigService = namingConfigService; _namingConfigService = namingConfigService;
_qualityDefinitionService = qualityDefinitionService; _qualityDefinitionService = qualityDefinitionService;
//_movieFormatCache = cacheManager.GetCache<MovieFormat>(GetType(), "movieFormat");
_episodeFormatCache = cacheManager.GetCache<EpisodeFormat[]>(GetType(), "episodeFormat"); _episodeFormatCache = cacheManager.GetCache<EpisodeFormat[]>(GetType(), "episodeFormat");
_absoluteEpisodeFormatCache = cacheManager.GetCache<AbsoluteEpisodeFormat[]>(GetType(), "absoluteEpisodeFormat"); _absoluteEpisodeFormatCache = cacheManager.GetCache<AbsoluteEpisodeFormat[]>(GetType(), "absoluteEpisodeFormat");
_logger = logger; _logger = logger;
@@ -151,52 +155,20 @@ namespace NzbDrone.Core.Organizer
return GetOriginalTitle(movieFile); return GetOriginalTitle(movieFile);
} }
/*if (namingConfig.StandardEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Standard) //TODO: Update namingConfig for Movies!
{ var pattern = namingConfig.StandardMovieFormat;
throw new NamingFormatException("Standard episode format cannot be empty");
}
if (namingConfig.DailyEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Daily)
{
throw new NamingFormatException("Daily episode format cannot be empty");
}
if (namingConfig.AnimeEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Anime)
{
throw new NamingFormatException("Anime episode format cannot be empty");
}*/
/*var pattern = namingConfig.StandardEpisodeFormat;
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance); var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
episodes = episodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber).ToList(); AddMovieTokens(tokenHandlers, movie);
AddReleaseDateTokens(tokenHandlers, movie.Year); //In case we want to separate the year
if (series.SeriesType == SeriesTypes.Daily) AddQualityTokens(tokenHandlers, movie, movieFile);
{ AddMediaInfoTokens(tokenHandlers, movieFile);
pattern = namingConfig.DailyEpisodeFormat;
}
if (series.SeriesType == SeriesTypes.Anime && episodes.All(e => e.AbsoluteEpisodeNumber.HasValue))
{
pattern = namingConfig.AnimeEpisodeFormat;
}
pattern = AddSeasonEpisodeNumberingTokens(pattern, tokenHandlers, episodes, namingConfig);
pattern = AddAbsoluteNumberingTokens(pattern, tokenHandlers, series, episodes, namingConfig);
AddSeriesTokens(tokenHandlers, series);
AddEpisodeTokens(tokenHandlers, episodes);
AddEpisodeFileTokens(tokenHandlers, episodeFile);
AddQualityTokens(tokenHandlers, series, episodeFile);
AddMediaInfoTokens(tokenHandlers, episodeFile);
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim(); var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString()); fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString());
fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty);*/ fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty);
//TODO: Update namingConfig for Movies! return fileName;
return GetOriginalTitle(movieFile);
} }
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension) public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension)
@@ -242,6 +214,8 @@ namespace NzbDrone.Core.Organizer
public BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec) public BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec)
{ {
return new BasicNamingConfig(); //For now let's be lazy
var episodeFormat = GetEpisodeFormat(nameSpec.StandardEpisodeFormat).LastOrDefault(); var episodeFormat = GetEpisodeFormat(nameSpec.StandardEpisodeFormat).LastOrDefault();
if (episodeFormat == null) if (episodeFormat == null)
@@ -315,9 +289,19 @@ namespace NzbDrone.Core.Organizer
return CleanFolderName(ReplaceTokens(namingConfig.SeasonFolderFormat, tokenHandlers, namingConfig)); return CleanFolderName(ReplaceTokens(namingConfig.SeasonFolderFormat, tokenHandlers, namingConfig));
} }
public string GetMovieFolder(Movie movie) public string GetMovieFolder(Movie movie, NamingConfig namingConfig = null)
{ {
return CleanFolderName(movie.Title); if(namingConfig == null)
{
namingConfig = _namingConfigService.GetConfig();
}
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
AddMovieTokens(tokenHandlers, movie);
AddReleaseDateTokens(tokenHandlers, movie.Year);
return CleanFolderName(ReplaceTokens(namingConfig.MovieFolderFormat, tokenHandlers, namingConfig));
} }
public static string CleanTitle(string title) public static string CleanTitle(string title)
@@ -481,6 +465,17 @@ namespace NzbDrone.Core.Organizer
return pattern; return pattern;
} }
private void AddMovieTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Movie movie)
{
tokenHandlers["{Movie Title}"] = m => movie.Title;
tokenHandlers["{Movie CleanTitle}"] = m => CleanTitle(movie.Title);
}
private void AddReleaseDateTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int releaseYear)
{
tokenHandlers["{Release Year}"] = m => string.Format("{0}", releaseYear.ToString()); //Do I need m.CustomFormat?
}
private void AddSeasonTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int seasonNumber) private void AddSeasonTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int seasonNumber)
{ {
tokenHandlers["{Season}"] = m => seasonNumber.ToString(m.CustomFormat); tokenHandlers["{Season}"] = m => seasonNumber.ToString(m.CustomFormat);
@@ -520,6 +515,18 @@ namespace NzbDrone.Core.Organizer
tokenHandlers["{Quality Real}"] = m => qualityReal; tokenHandlers["{Quality Real}"] = m => qualityReal;
} }
private void AddQualityTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Movie movie, MovieFile movieFile)
{
var qualityTitle = _qualityDefinitionService.Get(movieFile.Quality.Quality).Title;
var qualityProper = GetQualityProper(movie, movieFile.Quality);
var qualityReal = GetQualityReal(movie, movieFile.Quality);
tokenHandlers["{Quality Full}"] = m => String.Format("{0} {1} {2}", qualityTitle, qualityProper, qualityReal);
tokenHandlers["{Quality Title}"] = m => qualityTitle;
tokenHandlers["{Quality Proper}"] = m => qualityProper;
tokenHandlers["{Quality Real}"] = m => qualityReal;
}
private void AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, EpisodeFile episodeFile) private void AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, EpisodeFile episodeFile)
{ {
if (episodeFile.MediaInfo == null) return; if (episodeFile.MediaInfo == null) return;
@@ -624,6 +631,110 @@ namespace NzbDrone.Core.Organizer
tokenHandlers["{MediaInfo Full}"] = m => string.Format("{0} {1}{2} {3}", videoCodec, audioCodec, mediaInfoAudioLanguages, mediaInfoSubtitleLanguages); tokenHandlers["{MediaInfo Full}"] = m => string.Format("{0} {1}{2} {3}", videoCodec, audioCodec, mediaInfoAudioLanguages, mediaInfoSubtitleLanguages);
} }
private void AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, MovieFile movieFile)
{
if (movieFile.MediaInfo == null) return;
string videoCodec;
switch (movieFile.MediaInfo.VideoCodec)
{
case "AVC":
if (movieFile.SceneName.IsNotNullOrWhiteSpace() && Path.GetFileNameWithoutExtension(movieFile.SceneName).Contains("h264"))
{
videoCodec = "h264";
}
else
{
videoCodec = "x264";
}
break;
case "V_MPEGH/ISO/HEVC":
if (movieFile.SceneName.IsNotNullOrWhiteSpace() && Path.GetFileNameWithoutExtension(movieFile.SceneName).Contains("h265"))
{
videoCodec = "h265";
}
else
{
videoCodec = "x265";
}
break;
case "MPEG-2 Video":
videoCodec = "MPEG2";
break;
default:
videoCodec = movieFile.MediaInfo.VideoCodec;
break;
}
string audioCodec;
switch (movieFile.MediaInfo.AudioFormat)
{
case "AC-3":
audioCodec = "AC3";
break;
case "E-AC-3":
audioCodec = "EAC3";
break;
case "MPEG Audio":
if (movieFile.MediaInfo.AudioProfile == "Layer 3")
{
audioCodec = "MP3";
}
else
{
audioCodec = movieFile.MediaInfo.AudioFormat;
}
break;
case "DTS":
audioCodec = movieFile.MediaInfo.AudioFormat;
break;
default:
audioCodec = movieFile.MediaInfo.AudioFormat;
break;
}
var mediaInfoAudioLanguages = GetLanguagesToken(movieFile.MediaInfo.AudioLanguages);
if (!mediaInfoAudioLanguages.IsNullOrWhiteSpace())
{
mediaInfoAudioLanguages = string.Format("[{0}]", mediaInfoAudioLanguages);
}
if (mediaInfoAudioLanguages == "[EN]")
{
mediaInfoAudioLanguages = string.Empty;
}
var mediaInfoSubtitleLanguages = GetLanguagesToken(movieFile.MediaInfo.Subtitles);
if (!mediaInfoSubtitleLanguages.IsNullOrWhiteSpace())
{
mediaInfoSubtitleLanguages = string.Format("[{0}]", mediaInfoSubtitleLanguages);
}
var videoBitDepth = movieFile.MediaInfo.VideoBitDepth > 0 ? movieFile.MediaInfo.VideoBitDepth.ToString() : string.Empty;
var audioChannels = movieFile.MediaInfo.FormattedAudioChannels > 0 ?
movieFile.MediaInfo.FormattedAudioChannels.ToString("F1", CultureInfo.InvariantCulture) :
string.Empty;
tokenHandlers["{MediaInfo Video}"] = m => videoCodec;
tokenHandlers["{MediaInfo VideoCodec}"] = m => videoCodec;
tokenHandlers["{MediaInfo VideoBitDepth}"] = m => videoBitDepth;
tokenHandlers["{MediaInfo Audio}"] = m => audioCodec;
tokenHandlers["{MediaInfo AudioCodec}"] = m => audioCodec;
tokenHandlers["{MediaInfo AudioChannels}"] = m => audioChannels;
tokenHandlers["{MediaInfo Simple}"] = m => string.Format("{0} {1}", videoCodec, audioCodec);
tokenHandlers["{MediaInfo Full}"] = m => string.Format("{0} {1}{2} {3}", videoCodec, audioCodec, mediaInfoAudioLanguages, mediaInfoSubtitleLanguages);
}
private string GetLanguagesToken(string mediaInfoLanguages) private string GetLanguagesToken(string mediaInfoLanguages)
{ {
List<string> tokens = new List<string>(); List<string> tokens = new List<string>();
@@ -803,6 +914,16 @@ namespace NzbDrone.Core.Organizer
return MultiPartCleanupRegex.Replace(title, string.Empty).Trim(); return MultiPartCleanupRegex.Replace(title, string.Empty).Trim();
} }
private string GetQualityProper(Movie movie, QualityModel quality)
{
if (quality.Revision.Version > 1)
{
return "Proper";
}
return String.Empty;
}
private string GetQualityProper(Series series, QualityModel quality) private string GetQualityProper(Series series, QualityModel quality)
{ {
if (quality.Revision.Version > 1) if (quality.Revision.Version > 1)
@@ -828,6 +949,16 @@ namespace NzbDrone.Core.Organizer
return string.Empty; return string.Empty;
} }
private string GetQualityReal(Movie movie, QualityModel quality)
{
if (quality.Revision.Real > 0)
{
return "REAL";
}
return string.Empty;
}
private string GetOriginalTitle(EpisodeFile episodeFile) private string GetOriginalTitle(EpisodeFile episodeFile)
{ {
if (episodeFile.SceneName.IsNullOrWhiteSpace()) if (episodeFile.SceneName.IsNullOrWhiteSpace())
@@ -3,6 +3,7 @@ using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.MediaFiles.MediaInfo;
using System;
namespace NzbDrone.Core.Organizer namespace NzbDrone.Core.Organizer
{ {
@@ -13,8 +14,10 @@ namespace NzbDrone.Core.Organizer
SampleResult GetDailySample(NamingConfig nameSpec); SampleResult GetDailySample(NamingConfig nameSpec);
SampleResult GetAnimeSample(NamingConfig nameSpec); SampleResult GetAnimeSample(NamingConfig nameSpec);
SampleResult GetAnimeMultiEpisodeSample(NamingConfig nameSpec); SampleResult GetAnimeMultiEpisodeSample(NamingConfig nameSpec);
SampleResult GetMovieSample(NamingConfig nameSpec);
string GetSeriesFolderSample(NamingConfig nameSpec); string GetSeriesFolderSample(NamingConfig nameSpec);
string GetSeasonFolderSample(NamingConfig nameSpec); string GetSeasonFolderSample(NamingConfig nameSpec);
string GetMovieFolderSample(NamingConfig nameSpec);
} }
public class FileNameSampleService : IFilenameSampleService public class FileNameSampleService : IFilenameSampleService
@@ -34,10 +37,19 @@ namespace NzbDrone.Core.Organizer
private static EpisodeFile _animeEpisodeFile; private static EpisodeFile _animeEpisodeFile;
private static EpisodeFile _animeMultiEpisodeFile; private static EpisodeFile _animeMultiEpisodeFile;
private static MovieFile _movieFile;
private static Movie _movie;
public FileNameSampleService(IBuildFileNames buildFileNames) public FileNameSampleService(IBuildFileNames buildFileNames)
{ {
_buildFileNames = buildFileNames; _buildFileNames = buildFileNames;
_movie = new Movie
{
Title = "Movie Title",
Year = 2010
};
_standardSeries = new Series _standardSeries = new Series
{ {
SeriesType = SeriesTypes.Standard, SeriesType = SeriesTypes.Standard,
@@ -106,6 +118,15 @@ namespace NzbDrone.Core.Organizer
Subtitles = "Japanese/English" Subtitles = "Japanese/English"
}; };
_movieFile = new MovieFile
{
Quality = new QualityModel(Quality.Bluray1080p, new Revision(2)),
RelativePath = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE.mkv",
SceneName = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE",
ReleaseGroup = "RlsGrp",
MediaInfo = mediaInfo
};
_singleEpisodeFile = new EpisodeFile _singleEpisodeFile = new EpisodeFile
{ {
Quality = new QualityModel(Quality.HDTV720p, new Revision(2)), Quality = new QualityModel(Quality.HDTV720p, new Revision(2)),
@@ -217,6 +238,16 @@ namespace NzbDrone.Core.Organizer
return result; return result;
} }
public SampleResult GetMovieSample(NamingConfig nameSpec)
{
var result = new SampleResult
{
FileName = BuildSample(_movie, _movieFile, nameSpec),
};
return result;
}
public string GetSeriesFolderSample(NamingConfig nameSpec) public string GetSeriesFolderSample(NamingConfig nameSpec)
{ {
return _buildFileNames.GetSeriesFolder(_standardSeries, nameSpec); return _buildFileNames.GetSeriesFolder(_standardSeries, nameSpec);
@@ -227,6 +258,11 @@ namespace NzbDrone.Core.Organizer
return _buildFileNames.GetSeasonFolder(_standardSeries, _episode1.SeasonNumber, nameSpec); return _buildFileNames.GetSeasonFolder(_standardSeries, _episode1.SeasonNumber, nameSpec);
} }
public string GetMovieFolderSample(NamingConfig nameSpec)
{
return _buildFileNames.GetMovieFolder(_movie, nameSpec);
}
private string BuildSample(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig nameSpec) private string BuildSample(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig nameSpec)
{ {
try try
@@ -238,5 +274,17 @@ namespace NzbDrone.Core.Organizer
return string.Empty; return string.Empty;
} }
} }
private string BuildSample(Movie movie, MovieFile movieFile, NamingConfig nameSpec)
{
try
{
return _buildFileNames.BuildFileName(movie, movieFile, nameSpec);
}
catch (NamingFormatException)
{
return string.Empty;
}
}
} }
} }
@@ -41,6 +41,18 @@ namespace NzbDrone.Core.Organizer
ruleBuilder.SetValidator(new NotEmptyValidator(null)); ruleBuilder.SetValidator(new NotEmptyValidator(null));
return ruleBuilder.SetValidator(new RegularExpressionValidator(SeasonFolderRegex)).WithMessage("Must contain season number"); return ruleBuilder.SetValidator(new RegularExpressionValidator(SeasonFolderRegex)).WithMessage("Must contain season number");
} }
public static IRuleBuilderOptions<T, string> ValidMovieFolderFormat<T>(this IRuleBuilder<T, string> ruleBuilder)
{
ruleBuilder.SetValidator(new NotEmptyValidator(null));
return ruleBuilder.SetValidator(new RegularExpressionValidator(FileNameBuilder.MovieTitleRegex)).WithMessage("Must contain movie title");
}
public static IRuleBuilderOptions<T, string> ValidMovieFormat<T>(this IRuleBuilder<T, string> ruleBuilder)
{
ruleBuilder.SetValidator(new NotEmptyValidator(null));
return ruleBuilder.SetValidator(new RegularExpressionValidator(FileNameBuilder.MovieTitleRegex)).WithMessage("Must contain movie title");
}
} }
public class ValidStandardEpisodeFormatValidator : PropertyValidator public class ValidStandardEpisodeFormatValidator : PropertyValidator
@@ -11,12 +11,26 @@ namespace NzbDrone.Core.Organizer
ValidationFailure ValidateStandardFilename(SampleResult sampleResult); ValidationFailure ValidateStandardFilename(SampleResult sampleResult);
ValidationFailure ValidateDailyFilename(SampleResult sampleResult); ValidationFailure ValidateDailyFilename(SampleResult sampleResult);
ValidationFailure ValidateAnimeFilename(SampleResult sampleResult); ValidationFailure ValidateAnimeFilename(SampleResult sampleResult);
ValidationFailure ValidateMovieFilename(SampleResult sampleResult);
} }
public class FileNameValidationService : IFilenameValidationService public class FileNameValidationService : IFilenameValidationService
{ {
private const string ERROR_MESSAGE = "Produces invalid file names"; private const string ERROR_MESSAGE = "Produces invalid file names";
public ValidationFailure ValidateMovieFilename(SampleResult sampleResult)
{
var validationFailure = new ValidationFailure("MovieFormat", ERROR_MESSAGE);
var parsedMovieInfo = Parser.Parser.ParseMovieTitle(sampleResult.FileName);
if(parsedMovieInfo == null)
{
return validationFailure;
}
return null;
}
public ValidationFailure ValidateStandardFilename(SampleResult sampleResult) public ValidationFailure ValidateStandardFilename(SampleResult sampleResult)
{ {
var validationFailure = new ValidationFailure("StandardEpisodeFormat", ERROR_MESSAGE); var validationFailure = new ValidationFailure("StandardEpisodeFormat", ERROR_MESSAGE);
+6 -2
View File
@@ -1,4 +1,4 @@
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Organizer namespace NzbDrone.Core.Organizer
{ {
@@ -13,7 +13,9 @@ namespace NzbDrone.Core.Organizer
DailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title} {Quality Full}", DailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title} {Quality Full}",
AnimeEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}", AnimeEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}",
SeriesFolderFormat = "{Series Title}", SeriesFolderFormat = "{Series Title}",
SeasonFolderFormat = "Season {season}" SeasonFolderFormat = "Season {season}",
MovieFolderFormat = "{Movie Title} ({Release Year})",
StandardMovieFormat = "{Movie Title} ({Release Year}) {Quality Full}",
}; };
public bool RenameEpisodes { get; set; } public bool RenameEpisodes { get; set; }
@@ -24,5 +26,7 @@ namespace NzbDrone.Core.Organizer
public string AnimeEpisodeFormat { get; set; } public string AnimeEpisodeFormat { get; set; }
public string SeriesFolderFormat { get; set; } public string SeriesFolderFormat { get; set; }
public string SeasonFolderFormat { get; set; } public string SeasonFolderFormat { get; set; }
public string StandardMovieFormat { get; set; }
public string MovieFolderFormat { get; set; }
} }
} }
@@ -28,7 +28,8 @@ namespace NzbDrone.Core.Update
public UpdatePackage AvailableUpdate() public UpdatePackage AvailableUpdate()
{ {
return _updatePackageProvider.GetLatestUpdate(_configFileProvider.Branch, BuildInfo.Version); //For new let's just use develop, afterwards we can change it back to the config: _configFileProvider.Branch
return _updatePackageProvider.GetLatestUpdate("develop", BuildInfo.Version);
} }
} }
} }
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -2,7 +2,7 @@ var vent = require('vent');
var AppLayout = require('../AppLayout'); var AppLayout = require('../AppLayout');
var Marionette = require('marionette'); var Marionette = require('marionette');
var RootFolderLayout = require('./RootFolders/RootFolderLayout'); var RootFolderLayout = require('./RootFolders/RootFolderLayout');
//var ExistingMoviesCollectionView = require('./Existing/AddExistingSeriesCollectionView'); var ExistingMoviesCollectionView = require('./Existing/AddExistingMovieCollectionView');
var AddMoviesView = require('./AddMoviesView'); var AddMoviesView = require('./AddMoviesView');
var ProfileCollection = require('../Profile/ProfileCollection'); var ProfileCollection = require('../Profile/ProfileCollection');
var RootFolderCollection = require('./RootFolders/RootFolderCollection'); var RootFolderCollection = require('./RootFolders/RootFolderCollection');
@@ -36,9 +36,9 @@ module.exports = Marionette.Layout.extend({
}, },
_folderSelected : function(options) { _folderSelected : function(options) {
//vent.trigger(vent.Commands.CloseModalCommand); vent.trigger(vent.Commands.CloseModalCommand);
//TODO: Fix this shit. //TODO: Fix this shit.
//this.workspace.show(new ExistingMoviesCollectionView({ model : options.model })); this.workspace.show(new ExistingMoviesCollectionView({ model : options.model }));
}, },
_importMovies : function() { _importMovies : function() {
+2 -2
View File
@@ -26,7 +26,7 @@ module.exports = Marionette.Layout.extend({
}, },
initialize : function(options) { initialize : function(options) {
console.log(options) console.log(options);
this.isExisting = options.isExisting; this.isExisting = options.isExisting;
this.collection = new AddMoviesCollection(); this.collection = new AddMoviesCollection();
@@ -125,7 +125,7 @@ module.exports = Marionette.Layout.extend({
} }
else if (!this.isExisting) { else if (!this.isExisting) {
this.resultCollectionView.setExisting(options.movie.get('tmdbId')) this.resultCollectionView.setExisting(options.movie.get('tmdbId'));
/*this.collection.term = ''; /*this.collection.term = '';
this.collection.reset(); this.collection.reset();
this._clearResults(); this._clearResults();
@@ -1,11 +1,11 @@
var Marionette = require('marionette'); var Marionette = require('marionette');
var AddSeriesView = require('../AddSeriesView'); var AddMoviesView = require('../AddMoviesView');
var UnmappedFolderCollection = require('./UnmappedFolderCollection'); var UnmappedFolderCollection = require('./UnmappedFolderCollection');
module.exports = Marionette.CompositeView.extend({ module.exports = Marionette.CompositeView.extend({
itemView : AddSeriesView, itemView : AddMoviesView,
itemViewContainer : '.x-loading-folders', itemViewContainer : '.x-loading-folders',
template : 'AddSeries/Existing/AddExistingSeriesCollectionViewTemplate', template : 'AddMovies/Existing/AddExistingMovieCollectionViewTemplate',
ui : { ui : {
loadingFolders : '.x-loading-folders' loadingFolders : '.x-loading-folders'
@@ -23,7 +23,7 @@ module.exports = Marionette.CollectionView.extend({
setExisting : function(tmdbid) { setExisting : function(tmdbid) {
var movies = this.collection.where({ tmdbId : tmdbid }); var movies = this.collection.where({ tmdbId : tmdbid });
console.warn(movies) console.warn(movies);
//debugger; //debugger;
if (movies.length > 0) { if (movies.length > 0) {
this.children.findByModel(movies[0])._configureTemplateHelpers(); this.children.findByModel(movies[0])._configureTemplateHelpers();
+13 -13
View File
@@ -92,14 +92,14 @@ var view = Marionette.ItemView.extend({
_configureTemplateHelpers : function() { _configureTemplateHelpers : function() {
var existingMovies = MoviesCollection.where({ tmdbId : this.model.get('tmdbId') }); var existingMovies = MoviesCollection.where({ tmdbId : this.model.get('tmdbId') });
console.log(existingMovies) console.log(existingMovies);
if (existingMovies.length > 0) { if (existingMovies.length > 0) {
this.templateHelpers.existing = existingMovies[0].toJSON(); this.templateHelpers.existing = existingMovies[0].toJSON();
} }
this.templateHelpers.profiles = Profiles.toJSON(); this.templateHelpers.profiles = Profiles.toJSON();
console.log(this.model) console.log(this.model);
console.log(this.templateHelpers.existing) console.log(this.templateHelpers.existing);
if (!this.model.get('isExisting')) { if (!this.model.get('isExisting')) {
this.templateHelpers.rootFolders = RootFolders.toJSON(); this.templateHelpers.rootFolders = RootFolders.toJSON();
} }
@@ -245,14 +245,14 @@ var view = Marionette.ItemView.extend({
options.ignoreEpisodesWithoutFiles = true; options.ignoreEpisodesWithoutFiles = true;
} }
else if (monitor === 'latest') { // else if (monitor === 'latest') {
this.model.setSeasonPass(lastSeason.seasonNumber); // this.model.setSeasonPass(lastSeason.seasonNumber);
} // }
else if (monitor === 'first') { // else if (monitor === 'first') {
this.model.setSeasonPass(lastSeason.seasonNumber + 1); // this.model.setSeasonPass(lastSeason.seasonNumber + 1);
this.model.setSeasonMonitored(firstSeason.seasonNumber); // this.model.setSeasonMonitored(firstSeason.seasonNumber);
} // }
else if (monitor === 'missing') { else if (monitor === 'missing') {
options.ignoreEpisodesWithFiles = true; options.ignoreEpisodesWithFiles = true;
@@ -262,9 +262,9 @@ var view = Marionette.ItemView.extend({
options.ignoreEpisodesWithoutFiles = true; options.ignoreEpisodesWithoutFiles = true;
} }
else if (monitor === 'none') { // else if (monitor === 'none') {
this.model.setSeasonPass(lastSeason.seasonNumber + 1); // this.model.setSeasonPass(lastSeason.seasonNumber + 1);
} // }
return options; return options;
} }
+3 -3
View File
@@ -42,7 +42,7 @@ module.exports = Marionette.Layout.extend({
events : { events : {
'click .x-episode-file-editor' : '_openEpisodeFileEditor', 'click .x-episode-file-editor' : '_openEpisodeFileEditor',
'click .x-monitored' : '_toggleMonitored', 'click .x-monitored' : '_toggleMonitored',
'click .x-edit' : '_editMovies', 'click .x-edit' : '_editMovie',
'click .x-refresh' : '_refreshMovies', 'click .x-refresh' : '_refreshMovies',
'click .x-rename' : '_renameMovies', 'click .x-rename' : '_renameMovies',
'click .x-search' : '_moviesSearch', 'click .x-search' : '_moviesSearch',
@@ -167,8 +167,8 @@ module.exports = Marionette.Layout.extend({
} }
}, },
_editMovies : function() { _editMovie : function() {
vent.trigger(vent.Commands.EditMoviesCommand, { movie : this.model }); vent.trigger(vent.Commands.EditMovieCommand, { movie : this.model });
}, },
_refreshMovies : function() { _refreshMovies : function() {
+97
View File
@@ -0,0 +1,97 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>{{title}}</h3>
</div>
<div class="modal-body edit-series-modal">
<div class="row">
<div class="col-sm-3 hidden-xs">
{{poster}}
</div>
<div class="col-sm-9">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-4 control-label">Monitored</label>
<div class="col-sm-8">
<div class="input-group">
<label class="checkbox toggle well">
<input type="checkbox" name="monitored"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-primary slide-button"/>
</label>
<span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Should Radarr download the movie?"/>
</span>
</div>
</div>
</div>
<!--<div class="form-group">
<label class="col-sm-4 control-label">Use Season Folder</label>
<div class="col-sm-8">
<div class="input-group">
<label class="checkbox toggle well">
<input type="checkbox" name="seasonFolder"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-primary slide-button"/>
</label>
<span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Should downloaded episodes be stored in season folders?"/>
</span>
</div>
</div>
</div>-->
<div class="form-group">
<label class="col-sm-4 control-label">Profile</label>
<div class="col-sm-4">
<select class="form-control x-profile" id="inputProfile" name="profileId">
{{#each profiles.models}}
<option value="{{id}}">{{attributes.name}}</option>
{{/each}}
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Path</label>
<div class="col-sm-6">
<input type="text" class="form-control x-path" placeholder="Path" name="path">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Tags</label>
<div class="col-sm-6">
<input type="text" class="form-control x-tags">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-danger pull-left x-remove">Delete</button>
<span class="indicator x-indicator"><i class="icon-sonarr-spinner fa-spin"></i></span>
<button class="btn" data-dismiss="modal">Cancel</button>
<button class="btn btn-primary x-save">Save</button>
</div>
</div>
+54
View File
@@ -0,0 +1,54 @@
var vent = require('vent');
var Marionette = require('marionette');
var Profiles = require('../../Profile/ProfileCollection');
var AsModelBoundView = require('../../Mixins/AsModelBoundView');
var AsValidatedView = require('../../Mixins/AsValidatedView');
var AsEditModalView = require('../../Mixins/AsEditModalView');
require('../../Mixins/TagInput');
require('../../Mixins/FileBrowser');
var view = Marionette.ItemView.extend({
template : 'Movies/Edit/EditMovieTemplate',
ui : {
profile : '.x-profile',
path : '.x-path',
tags : '.x-tags'
},
events : {
'click .x-remove' : '_removeSeries'
},
initialize : function() {
this.model.set('profiles', Profiles);
},
onRender : function() {
this.ui.path.fileBrowser();
this.ui.tags.tagInput({
model : this.model,
property : 'tags'
});
},
_onBeforeSave : function() {
var profileId = this.ui.profile.val();
this.model.set({ profileId : profileId });
},
_onAfterSave : function() {
this.trigger('saved');
vent.trigger(vent.Commands.CloseModalCommand);
},
_removeSeries : function() {
vent.trigger(vent.Commands.DeleteSeriesCommand, { series : this.model });
}
});
AsModelBoundView.call(view);
AsValidatedView.call(view);
AsEditModalView.call(view);
module.exports = view;
+1 -1
View File
@@ -23,7 +23,7 @@ module.exports = Marionette.ItemView.extend({
}, },
_editSeries : function() { _editSeries : function() {
vent.trigger(vent.Commands.EditSeriesCommand, { series : this.model }); vent.trigger(vent.Commands.EditMovieCommand, { movie : this.model });
}, },
_refreshSeries : function() { _refreshSeries : function() {
@@ -14,8 +14,8 @@
</div> </div>
<div class="col-md-2 col-xs-2"> <div class="col-md-2 col-xs-2">
<div class="pull-right series-overview-list-actions"> <div class="pull-right series-overview-list-actions">
<i class="icon-sonarr-refresh x-refresh" title="Update series info and scan disk"/> <i class="icon-sonarr-refresh x-refresh" title="Update movie info and scan disk"/>
<i class="icon-sonarr-edit x-edit" title="Edit Series"/> <i class="icon-sonarr-edit x-edit" title="Edit Movie"/>
</div> </div>
</div> </div>
</div> </div>
@@ -2,7 +2,7 @@
<legend>File Management</legend> <legend>File Management</legend>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Ignore Deleted Episodes</label> <label class="col-sm-3 control-label">Ignore Deleted Movies</label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group"> <div class="input-group">
@@ -17,7 +17,7 @@
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Episodes deleted from disk are automatically unmonitored in Sonarr"/> <i class="icon-sonarr-form-info" title="Movies deleted from disk are automatically unmonitored in Radarr"/>
</span> </span>
</div> </div>
</div> </div>
@@ -39,7 +39,7 @@
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Should Sonarr automatically upgrade to propers when available?"/> <i class="icon-sonarr-form-info" title="Should Radarr automatically upgrade to propers when available?"/>
</span> </span>
</div> </div>
</div> </div>
@@ -26,10 +26,10 @@ var view = Marionette.ItemView.extend({
}, },
_parseNamingModel : function() { _parseNamingModel : function() {
var standardFormat = this.namingModel.get('standardEpisodeFormat'); var standardFormat = this.namingModel.get('standardMovieFormat');
var includeSeriesTitle = standardFormat.match(/\{Series[-_. ]Title\}/i); var includeSeriesTitle = false;//standardFormat.match(/\{Series[-_. ]Title\}/i);
var includeEpisodeTitle = standardFormat.match(/\{Episode[-_. ]Title\}/i); var includeEpisodeTitle = false;//standardFormat.match(/\{Episode[-_. ]Title\}/i);
var includeQuality = standardFormat.match(/\{Quality[-_. ]Title\}/i); var includeQuality = standardFormat.match(/\{Quality[-_. ]Title\}/i);
var numberStyle = standardFormat.match(/s?\{season(?:\:0+)?\}[ex]\{episode(?:\:0+)?\}/i); var numberStyle = standardFormat.match(/s?\{season(?:\:0+)?\}[ex]\{episode(?:\:0+)?\}/i);
var replaceSpaces = standardFormat.indexOf(' ') === -1; var replaceSpaces = standardFormat.indexOf(' ') === -1;
@@ -115,4 +115,4 @@ var view = Marionette.ItemView.extend({
} }
}); });
module.exports = AsModelBoundView.call(view); module.exports = AsModelBoundView.call(view);
@@ -19,7 +19,9 @@ module.exports = (function() {
namingTokenHelper : '.x-naming-token-helper', namingTokenHelper : '.x-naming-token-helper',
multiEpisodeStyle : '.x-multi-episode-style', multiEpisodeStyle : '.x-multi-episode-style',
seriesFolderExample : '.x-series-folder-example', seriesFolderExample : '.x-series-folder-example',
seasonFolderExample : '.x-season-folder-example' seasonFolderExample : '.x-season-folder-example',
movieExample : '.x-movie-example',
movieFolderExample : '.x-movie-folder-example'
}, },
events : { events : {
"change .x-rename-episodes" : '_setFailedDownloadOptionsVisibility', "change .x-rename-episodes" : '_setFailedDownloadOptionsVisibility',
@@ -58,6 +60,8 @@ module.exports = (function() {
this.ui.animeMultiEpisodeExample.html(this.namingSampleModel.get('animeMultiEpisodeExample')); this.ui.animeMultiEpisodeExample.html(this.namingSampleModel.get('animeMultiEpisodeExample'));
this.ui.seriesFolderExample.html(this.namingSampleModel.get('seriesFolderExample')); this.ui.seriesFolderExample.html(this.namingSampleModel.get('seriesFolderExample'));
this.ui.seasonFolderExample.html(this.namingSampleModel.get('seasonFolderExample')); this.ui.seasonFolderExample.html(this.namingSampleModel.get('seasonFolderExample'));
this.ui.movieExample.html(this.namingSampleModel.get('movieExample'));
this.ui.movieFolderExample.html(this.namingSampleModel.get('movieFolderExample'));
}, },
_addToken : function(e) { _addToken : function(e) {
e.preventDefault(); e.preventDefault();
@@ -1,8 +1,8 @@
<fieldset> <fieldset>
<legend>Episode Naming</legend> <legend>Movie Naming</legend>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Rename Episodes</label> <label class="col-sm-3 control-label">Rename Movies</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="input-group"> <div class="input-group">
@@ -18,7 +18,7 @@
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-warning" title="Sonarr will use the existing file name if set to no"/> <i class="icon-sonarr-form-warning" title="Radarr will use the existing file name if set to no"/>
</span> </span>
</div> </div>
</div> </div>
@@ -51,25 +51,23 @@
<div class="basic-setting x-basic-naming"></div> <div class="basic-setting x-basic-naming"></div>
<div class="form-group advanced-setting"> <div class="form-group advanced-setting">
<label class="col-sm-3 control-label">Standard Episode Format</label> <label class="col-sm-3 control-label">Standard Movie Format</label>
<div class="col-sm-1 col-sm-push-8 help-inline"> <div class="col-sm-1 col-sm-push-8 help-inline">
<i class="icon-sonarr-form-info" title="" data-original-title="All caps or all lower-case can also be used"></i> <i class="icon-sonarr-form-info" title="" data-original-title="All caps or all lower-case can also be used"></i>
<a href="https://github.com/NzbDrone/NzbDrone/wiki/Sorting-and-Renaming" class="help-link" title="More information"><i class="icon-sonarr-form-info-link"/></a> <a href="https://github.com/NzbDrone/NzbDrone/wiki/Sorting-and-Renaming" class="help-link" title="More information"><i class="icon-sonarr-form-info-link"/></a> <!-- TODO: Update wiki link -->
</div> </div>
<div class="col-sm-8 col-sm-pull-1"> <div class="col-sm-8 col-sm-pull-1">
<div class="input-group x-helper-input"> <div class="input-group x-helper-input">
<input type="text" class="form-control naming-format" name="standardEpisodeFormat" data-onkeyup="true" /> <input type="text" class="form-control naming-format" name="standardMovieFormat" data-onkeyup="true" />
<div class="input-group-btn btn-group x-naming-token-helper"> <div class="input-group-btn btn-group x-naming-token-helper">
<button class="btn btn-icon-only dropdown-toggle" data-toggle="dropdown"> <button class="btn btn-icon-only dropdown-toggle" data-toggle="dropdown">
<i class="icon-sonarr-add"></i> <i class="icon-sonarr-add"></i>
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{{> SeriesTitleNamingPartial}} {{> MovieTitleNamingPartial}}
{{> SeasonNamingPartial}} {{> ReleaseYearNamingPartial}}
{{> EpisodeNamingPartial}}
{{> EpisodeTitleNamingPartial}}
{{> QualityNamingPartial}} {{> QualityNamingPartial}}
{{> MediaInfoNamingPartial}} {{> MediaInfoNamingPartial}}
{{> ReleaseGroupNamingPartial}} {{> ReleaseGroupNamingPartial}}
@@ -81,7 +79,7 @@
</div> </div>
</div> </div>
<div class="form-group advanced-setting"> {{!--<div class="form-group advanced-setting">
<label class="col-sm-3 control-label">Daily Episode Format</label> <label class="col-sm-3 control-label">Daily Episode Format</label>
<div class="col-sm-1 col-sm-push-8 help-inline"> <div class="col-sm-1 col-sm-push-8 help-inline">
@@ -111,9 +109,9 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>--}}
<div class="form-group advanced-setting"> {{!--<div class="form-group advanced-setting">
<label class="col-sm-3 control-label">Anime Episode Format</label> <label class="col-sm-3 control-label">Anime Episode Format</label>
<div class="col-sm-1 col-sm-push-8 help-inline"> <div class="col-sm-1 col-sm-push-8 help-inline">
@@ -144,31 +142,32 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>--}}
<div class="form-group advanced-setting"> <div class="form-group advanced-setting">
<label class="col-sm-3 control-label">Series Folder Format</label> <label class="col-sm-3 control-label">Movie Folder Format</label>
<div class="col-sm-1 col-sm-push-8 help-inline"> <div class="col-sm-1 col-sm-push-8 help-inline">
<i class="icon-sonarr-form-info" title="" data-original-title="All caps or all lower-case can also be used. Only used when adding a new series."></i> <i class="icon-sonarr-form-info" title="" data-original-title="All caps or all lower-case can also be used. Only used when adding a new movie."></i>
</div> </div>
<div class="col-sm-8 col-sm-pull-1"> <div class="col-sm-8 col-sm-pull-1">
<div class="input-group x-helper-input"> <div class="input-group x-helper-input">
<input type="text" class="form-control naming-format" name="seriesFolderFormat" data-onkeyup="true"/> <input type="text" class="form-control naming-format" name="movieFolderFormat" data-onkeyup="true"/>
<div class="input-group-btn btn-group x-naming-token-helper"> <div class="input-group-btn btn-group x-naming-token-helper">
<button class="btn btn-icon-only dropdown-toggle" data-toggle="dropdown"> <button class="btn btn-icon-only dropdown-toggle" data-toggle="dropdown">
<i class="icon-sonarr-add"></i> <i class="icon-sonarr-add"></i>
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{{> SeriesTitleNamingPartial}} {{> MovieTitleNamingPartial}}
{{> ReleaseYearNamingPartial}}
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> {{!--<div class="form-group">
<label class="col-sm-3 control-label">Season Folder Format</label> <label class="col-sm-3 control-label">Season Folder Format</label>
<div class="col-sm-8"> <div class="col-sm-8">
@@ -186,9 +185,9 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>--}}
<div class="x-naming-options"> {{!--<div class="x-naming-options">
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Multi-Episode Style</label> <label class="col-sm-3 control-label">Multi-Episode Style</label>
@@ -203,17 +202,17 @@
</select> </select>
</div> </div>
</div> </div>
</div> </div>--}}
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Single Episode Example</label> <label class="col-sm-3 control-label">Movie Example</label>
<div class="col-sm-8"> <div class="col-sm-8">
<p class="form-control-static x-single-episode-example naming-example"></p> <p class="form-control-static x-movie-example naming-example"></p>
</div> </div>
</div> </div>
<div class="form-group"> {{!--<div class="form-group">
<label class="col-sm-3 control-label">Multi-Episode Example</label> <label class="col-sm-3 control-label">Multi-Episode Example</label>
<div class="col-sm-8"> <div class="col-sm-8">
@@ -242,21 +241,21 @@
<div class="col-sm-8"> <div class="col-sm-8">
<p class="form-control-static x-anime-multi-episode-example naming-example"></p> <p class="form-control-static x-anime-multi-episode-example naming-example"></p>
</div> </div>
</div> </div>--}}
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Series Folder Example</label> <label class="col-sm-3 control-label">Movie Folder Example</label>
<div class="col-sm-8"> <div class="col-sm-8">
<p class="form-control-static x-series-folder-example naming-example"></p> <p class="form-control-static x-movie-folder-example naming-example"></p>
</div> </div>
</div> </div>
<div class="form-group"> {{!--<div class="form-group">
<label class="col-sm-3 control-label">Season Folder Example</label> <label class="col-sm-3 control-label">Season Folder Example</label>
<div class="col-sm-8"> <div class="col-sm-8">
<p class="form-control-static x-season-folder-example naming-example"></p> <p class="form-control-static x-season-folder-example naming-example"></p>
</div> </div>
</div> </div>--}}
</fieldset> </fieldset>
@@ -0,0 +1,11 @@
<li class="dropdown-submenu">
<a href="#" tabindex="-1" data-token="Movie Title">Movie Title</a>
<ul class="dropdown-menu">
<li><a href="#" data-token="Movie Title">Movie Title</a></li>
<li><a href="#" data-token="Movie.Title">Movie.Title</a></li>
<li><a href="#" data-token="Movie_Title">Movie_Title</a></li>
<li><a href="#" data-token="Movie CleanTitle">Movie CleanTitle</a></li>
<li><a href="#" data-token="Movie.CleanTitle">Movie.CleanTitle</a></li>
<li><a href="#" data-token="Movie_CleanTitle">Movie_CleanTitle</a></li>
</ul>
</li>
@@ -0,0 +1 @@
<li><a href="#" data-token="Release Year">Release Year</a></li>
@@ -2,7 +2,7 @@
<legend>Folders</legend> <legend>Folders</legend>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Create empty series folders</label> <label class="col-sm-3 control-label">Create empty movie folders</label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group"> <div class="input-group">
@@ -18,7 +18,7 @@
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Create missing series folders during disk scan"/> <i class="icon-sonarr-form-info" title="Create missing movie folders during disk scan"/>
</span> </span>
</div> </div>
</div> </div>
@@ -46,7 +46,7 @@
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Use when drone is unable to detect free space from your series root folder"/> <i class="icon-sonarr-form-info" title="Use when drone is unable to detect free space from your movies root folder"/>
</span> </span>
</div> </div>
</div> </div>
@@ -71,7 +71,7 @@
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Use Hardlinks when trying to copy files from torrents that are still being seeded"/> <i class="icon-sonarr-form-info" title="Use Hardlinks when trying to copy files from torrents that are still being seeded"/>
<i class="icon-sonarr-form-warning" title="Occasionally, file locks may prevent renaming files that are being seeded. You may temporarily disable seeding and use Sonarr's rename function as a work around."/> <i class="icon-sonarr-form-warning" title="Occasionally, file locks may prevent renaming files that are being seeded. You may temporarily disable seeding and use Radarr's rename function as a work around."/>
</span> </span>
</div> </div>
</div> </div>
+7
View File
@@ -2,6 +2,7 @@ var vent = require('vent');
var AppLayout = require('../../AppLayout'); var AppLayout = require('../../AppLayout');
var Marionette = require('marionette'); var Marionette = require('marionette');
var EditSeriesView = require('../../Series/Edit/EditSeriesView'); var EditSeriesView = require('../../Series/Edit/EditSeriesView');
var EditMovieView = require('../../Movies/Edit/EditMovieView');
var DeleteSeriesView = require('../../Series/Delete/DeleteSeriesView'); var DeleteSeriesView = require('../../Series/Delete/DeleteSeriesView');
var EpisodeDetailsLayout = require('../../Episode/EpisodeDetailsLayout'); var EpisodeDetailsLayout = require('../../Episode/EpisodeDetailsLayout');
var HistoryDetailsLayout = require('../../Activity/History/Details/HistoryDetailsLayout'); var HistoryDetailsLayout = require('../../Activity/History/Details/HistoryDetailsLayout');
@@ -17,6 +18,7 @@ module.exports = Marionette.AppRouter.extend({
vent.on(vent.Commands.OpenModal2Command, this._openModal2, this); vent.on(vent.Commands.OpenModal2Command, this._openModal2, this);
vent.on(vent.Commands.CloseModal2Command, this._closeModal2, this); vent.on(vent.Commands.CloseModal2Command, this._closeModal2, this);
vent.on(vent.Commands.EditSeriesCommand, this._editSeries, this); vent.on(vent.Commands.EditSeriesCommand, this._editSeries, this);
vent.on(vent.Commands.EditMovieCommand, this._editMovie, this);
vent.on(vent.Commands.DeleteSeriesCommand, this._deleteSeries, this); vent.on(vent.Commands.DeleteSeriesCommand, this._deleteSeries, this);
vent.on(vent.Commands.ShowEpisodeDetails, this._showEpisode, this); vent.on(vent.Commands.ShowEpisodeDetails, this._showEpisode, this);
vent.on(vent.Commands.ShowMovieDetails, this._showMovie, this); vent.on(vent.Commands.ShowMovieDetails, this._showMovie, this);
@@ -49,6 +51,11 @@ module.exports = Marionette.AppRouter.extend({
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
}, },
_editMovie : function(options) {
var view = new EditMovieView({ model : options.movie });
AppLayout.modalRegion.show(view);
},
_deleteSeries : function(options) { _deleteSeries : function(options) {
var view = new DeleteSeriesView({ model : options.series }); var view = new DeleteSeriesView({ model : options.series });
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
+1
View File
@@ -12,6 +12,7 @@ vent.Events = {
vent.Commands = { vent.Commands = {
EditSeriesCommand : 'EditSeriesCommand', EditSeriesCommand : 'EditSeriesCommand',
EditMovieCommand : 'EditMovieCommand',
DeleteSeriesCommand : 'DeleteSeriesCommand', DeleteSeriesCommand : 'DeleteSeriesCommand',
OpenModalCommand : 'OpenModalCommand', OpenModalCommand : 'OpenModalCommand',
CloseModalCommand : 'CloseModalCommand', CloseModalCommand : 'CloseModalCommand',