1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-24 17:25:22 -04:00

Compare commits

...

42 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
4182728901 Updated all AssemblyInfos so version info only needs to be changed once 2017-01-07 12:03:56 +01:00
Leonardo Galli
5be5709043 Update package.sh, fixes #35 2017-01-07 11:24:53 +01:00
Leonardo Galli
ee5a2ec289 Merge branch 'develop' of https://github.com/galli-leo/Radarr into develop 2017-01-07 11:03:59 +01:00
Leonardo Galli
cdfb95f425 Hopefully icon is now finally fixed. 2017-01-07 11:02:56 +01:00
Leonardo Galli
451060cb65 Merge pull request #37 from aaearon/rtorrent
dirty fix for rtorrent
2017-01-07 10:47:10 +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
Leonardo Galli
ff6bf235aa Merge branch 'develop' of https://github.com/galli-leo/Radarr into develop 2017-01-07 09:47:14 +01:00
Leonardo Galli
a272127a00 Should finally fix exe icon and resulting build error. 2017-01-07 09:47:08 +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
1864a79f99 Merge pull request #36 from aaearon/nzbs.org
changed nzbs.org category for movies
2017-01-06 22:24:35 -05:00
Tim Schindler
5843a881e6 changed nzbs.org category for movies 2017-01-06 21:58:46 -05:00
Tim Schindler
d898fbb4b0 dirty fix for rtorrent 2017-01-06 21:54:24 -05:00
Tim Turner
721767331b Update naming management
Still need to write BuildFileName() and BuildFilePath()
2017-01-06 19:32:19 -05:00
Leonardo Galli
abd4c1a1ad Merge branch 'develop' of https://github.com/galli-leo/Radarr into develop 2017-01-06 23:16:39 +01:00
Leonardo Galli
df971b1289 Fix exe icon. 2017-01-06 23:16:35 +01:00
Leonardo Galli
e5c81eefd2 Merge pull request #34 from onedr0p/develop
Instead of searching for imdbid (which jackett may or may not have depending on the tracker) search for a word instead.
2017-01-06 21:56:02 +01:00
Tim Turner
49c7c033d9 Merge remote-tracking branch 'refs/remotes/galli-leo/develop' into develop 2017-01-06 15:31:19 -05:00
Devin Buhl
f7fb238fb4 Merge pull request #1 from onedr0p/onedr0p-patch-1
Update TorrentPotatoRequestGenerator.cs
2017-01-06 15:27:33 -05:00
Devin Buhl
52dbd8d708 Update TorrentPotatoRequestGenerator.cs
Instead of searching for imdbid (which jackett may or may not have depending on the tracker) search for a word instead.
2017-01-06 15:26:16 -05:00
Leonardo Galli
427babf34e Update readme.md 2017-01-06 19:24:40 +01:00
87 changed files with 1332 additions and 232 deletions

BIN
.DS_Store vendored

Binary file not shown.

5
.gitignore vendored
View File

@@ -130,6 +130,7 @@ output/*
#Packages
Radarr_*/
Radarr_*.zip
Radarr_*.gz
#OS X metadata files
._*
@@ -137,3 +138,7 @@ Radarr_*.zip
_start
_temp_*/**/*
#AppVeyor
/tools-cake/
/_artifacts/

BIN
7za.dll Normal file

Binary file not shown.

BIN
7za.exe Normal file

Binary file not shown.

BIN
7zxa.dll Normal file

Binary file not shown.

BIN
Logo/Thumbs.db Normal file

Binary file not shown.

38
appveyor.yml Normal file
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
build-appveyor.cake Normal file
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
build-appveyor.ps1 Normal file
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

View File

@@ -4,6 +4,18 @@ if [ $# -eq 0 ]; then
fi
fi
# Use mono or .net depending on OS
case "$(uname -s)" in
CYGWIN*|MINGW32*|MINGW64*|MSYS*)
# on windows, use dotnet
runtime="dotnet"
;;
*)
# otherwise use mono
runtime="mono"
;;
esac
if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
VERSION="`date +%H:%M:%S`"
YEAR="`date +%Y`"
@@ -26,10 +38,16 @@ cp -r $outputFolder/ Radarr_Windows_$VERSION
cp -r $outputFolderMono/ Radarr_Mono_$VERSION
cp -r $outputFolderOsxApp/ Radarr_OSX_$VERSION
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_OSX_$VERSION.zip Radarr_OSX_$VERSION >& /dev/null
if [ $runtime = "dotnet" ] ; then
./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_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
zip -r Radarr_Windows_$VERSION.zip Radarr_Windows_$VERSION/* >& /dev/null
zip -r Radarr_Mono_$VERSION.zip Radarr_Mono_$VERSION/* >& /dev/null #TODO update for tar.gz
zip -r Radarr_OSX_$VERSION_App.zip Radarr_OSX_$VERSION/* >& /dev/null
fi
ftp -n ftp.leonardogalli.ch << END_SCRIPT
passive
quote USER $FTP_USER

View File

@@ -6,16 +6,17 @@ This fork of Sonarr aims to turn it into something like Couchpotato.
* Adding new movies
* Manually searching for releases of movies.
* Automatically searching for releases.
* Rarbg.to indexer (Other indexers are coming, I just need to find the right categories)
* QBittorrent download client (Other clients are coming)
* Automatically importing downloaded movies.
* Recognizing Special Editions, Director's Cut, etc.
* Identifying releases with hardcoded subs.
* Rarbg.to, Torznab and Newznab Indexer.
* QBittorrent and Deluge download client (Other clients are coming)
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
## Planned Features:
* Scanning PreDB to know when a new release is available.
* Fixing the other Indexers and download clients.
* Fixing how movies are parsed.
* Fixing movie import.
* Importing of Sonarr config.
* New TorrentPotato Indexer.
## Download
The latest precompiled binary versions can be found here: https://github.com/galli-leo/Radarr/releases.
@@ -28,15 +29,11 @@ For more up to date versions (but also sometimes broken), daily builds can be fo
## Major Features Include: ##
* Support for major platforms: Windows, Linux, OSX, Raspberry Pi, etc.
* Automatically detects new episodes
* Can scan your existing library and download any missing episodes
* Can watch for better quality of the episodes you already have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
* Can watch for better quality of the movies you have and do an upgrade.
* Automatic failed download handling will try another release if one fails
* Manual search so you can pick any release or to see why a release was not downloaded automatically
* Fully configurable episode renaming
* Full integration with SABNzbd and NzbGet
* Full integration with XBMC, Plex (notification, library update, metadata)
* Full support for specials and multi-episode releases
* Manual search so you can pick any release or to see why a release was not downloaded automatically.
* Full integration with SABNzbd and NzbGet.
* Full integration with XBMC, Plex (notification, library update, metadata).
* And a beautiful UI
## Configuring Development Environment: ##

BIN
src/.DS_Store vendored

Binary file not shown.

View File

@@ -21,4 +21,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("260b2ff9-d3b7-4d8a-b720-a12c93d045e5")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -39,6 +39,8 @@ namespace NzbDrone.Api.Config
SharedValidator.RuleFor(c => c.AnimeEpisodeFormat).ValidAnimeEpisodeFormat();
SharedValidator.RuleFor(c => c.SeriesFolderFormat).ValidSeriesFolderFormat();
SharedValidator.RuleFor(c => c.SeasonFolderFormat).ValidSeasonFolderFormat();
SharedValidator.RuleFor(c => c.StandardMovieFormat).ValidMovieFormat();
SharedValidator.RuleFor(c => c.MovieFolderFormat).ValidMovieFolderFormat();
}
private void UpdateNamingConfig(NamingConfigResource resource)
@@ -54,7 +56,13 @@ namespace NzbDrone.Api.Config
var nameSpec = _namingConfigService.GetConfig();
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);
basicConfig.AddToResource(resource);
@@ -73,39 +81,50 @@ namespace NzbDrone.Api.Config
var nameSpec = config.ToModel();
var sampleResource = new NamingSampleResource();
var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec);
var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec);
var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec);
var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
//var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec);
//var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec);
//var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec);
//var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
//var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
sampleResource.SingleEpisodeExample = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult) != null
? "Invalid format"
: singleEpisodeSampleResult.FileName;
var movieSampleResult = _filenameSampleService.GetMovieSample(nameSpec);
sampleResource.MultiEpisodeExample = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult) != null
? "Invalid format"
: multiEpisodeSampleResult.FileName;
//sampleResource.SingleEpisodeExample = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult) != null
// ? "Invalid format"
// : singleEpisodeSampleResult.FileName;
sampleResource.DailyEpisodeExample = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult) != null
? "Invalid format"
: dailyEpisodeSampleResult.FileName;
//sampleResource.MultiEpisodeExample = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult) != null
// ? "Invalid format"
// : multiEpisodeSampleResult.FileName;
sampleResource.AnimeEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult) != null
? "Invalid format"
: animeEpisodeSampleResult.FileName;
//sampleResource.DailyEpisodeExample = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult) != null
// ? "Invalid format"
// : dailyEpisodeSampleResult.FileName;
sampleResource.AnimeMultiEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult) != null
? "Invalid format"
: animeMultiEpisodeSampleResult.FileName;
//sampleResource.AnimeEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult) != null
// ? "Invalid format"
// : 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"
: _filenameSampleService.GetSeriesFolderSample(nameSpec);
sampleResource.SeasonFolderExample = nameSpec.SeasonFolderFormat.IsNullOrWhiteSpace()
? "Invalid format"
: _filenameSampleService.GetSeasonFolderSample(nameSpec);
: _filenameSampleService.GetMovieFolderSample(nameSpec);
return sampleResource.AsResponse();
}
@@ -118,19 +137,25 @@ namespace NzbDrone.Api.Config
var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
var movieSampleResult = _filenameSampleService.GetMovieSample(nameSpec);
var singleEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult);
var multiEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult);
var dailyEpisodeValidationResult = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult);
var animeEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult);
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>();
validationFailures.AddIfNotNull(singleEpisodeValidationResult);
validationFailures.AddIfNotNull(multiEpisodeValidationResult);
validationFailures.AddIfNotNull(dailyEpisodeValidationResult);
validationFailures.AddIfNotNull(animeEpisodeValidationResult);
validationFailures.AddIfNotNull(animeMultiEpisodeValidationResult);
//validationFailures.AddIfNotNull(singleEpisodeValidationResult);
//validationFailures.AddIfNotNull(multiEpisodeValidationResult);
//validationFailures.AddIfNotNull(dailyEpisodeValidationResult);
//validationFailures.AddIfNotNull(animeEpisodeValidationResult);
//validationFailures.AddIfNotNull(animeMultiEpisodeValidationResult);
//validationFailures.AddIfNotNull(standardMovieValidationResult);
if (validationFailures.Any())
{

View File

@@ -7,6 +7,8 @@ namespace NzbDrone.Api.Config
{
public bool RenameEpisodes { get; set; }
public bool ReplaceIllegalCharacters { get; set; }
public string StandardMovieFormat { get; set; }
public string MovieFolderFormat { get; set; }
public int MultiEpisodeStyle { get; set; }
public string StandardEpisodeFormat { get; set; }
public string DailyEpisodeFormat { get; set; }
@@ -36,7 +38,9 @@ namespace NzbDrone.Api.Config
DailyEpisodeFormat = model.DailyEpisodeFormat,
AnimeEpisodeFormat = model.AnimeEpisodeFormat,
SeriesFolderFormat = model.SeriesFolderFormat,
SeasonFolderFormat = model.SeasonFolderFormat
SeasonFolderFormat = model.SeasonFolderFormat,
StandardMovieFormat = model.StandardMovieFormat,
MovieFolderFormat = model.MovieFolderFormat
//IncludeSeriesTitle
//IncludeEpisodeTitle
//IncludeQuality
@@ -64,12 +68,14 @@ namespace NzbDrone.Api.Config
RenameEpisodes = resource.RenameEpisodes,
ReplaceIllegalCharacters = resource.ReplaceIllegalCharacters,
MultiEpisodeStyle = resource.MultiEpisodeStyle,
StandardEpisodeFormat = resource.StandardEpisodeFormat,
DailyEpisodeFormat = resource.DailyEpisodeFormat,
AnimeEpisodeFormat = resource.AnimeEpisodeFormat,
SeriesFolderFormat = resource.SeriesFolderFormat,
SeasonFolderFormat = resource.SeasonFolderFormat
//MultiEpisodeStyle = resource.MultiEpisodeStyle,
//StandardEpisodeFormat = resource.StandardEpisodeFormat,
//DailyEpisodeFormat = resource.DailyEpisodeFormat,
//AnimeEpisodeFormat = resource.AnimeEpisodeFormat,
//SeriesFolderFormat = resource.SeriesFolderFormat,
//SeasonFolderFormat = resource.SeasonFolderFormat,
StandardMovieFormat = resource.StandardMovieFormat,
MovieFolderFormat = resource.MovieFolderFormat
};
}
}

View File

@@ -9,5 +9,8 @@
public string AnimeMultiEpisodeExample { get; set; }
public string SeriesFolderExample { get; set; }
public string SeasonFolderExample { get; set; }
public string MovieExample { get; set; }
public string MovieFolderExample { get; set; }
}
}

View File

@@ -6,6 +6,5 @@ using System.Runtime.InteropServices;
[assembly: Guid("4c0922d7-979e-4ff7-b44b-b8ac2100eeb5")]
[assembly: AssemblyVersion("0.1.0.*")]
[assembly: InternalsVisibleTo("NzbDrone.Core")]

View File

@@ -21,4 +21,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b47d34ef-05e8-4826-8a57-9dd05106c964")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -20,5 +20,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6b8945f5-f5b5-4729-865d-f958fbd673d9")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -14,7 +14,7 @@ namespace NzbDrone.Common.Cloud
{
public SonarrCloudRequestBuilder()
{
Services = new HttpRequestBuilder("http://services.sonarr.tv/v1/")
Services = new HttpRequestBuilder("https://radarr.aeonlucid.com/v1/")
.CreateFactory();
SkyHookTvdb = new HttpRequestBuilder("http://skyhook.sonarr.tv/v1/tvdb/{route}/{language}/")
@@ -26,12 +26,11 @@ namespace NzbDrone.Common.Cloud
.CreateFactory();
TMDBSingle = new HttpRequestBuilder("https://api.themoviedb.org/3/{route}")
.AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212")
.CreateFactory();
.AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212")
.CreateFactory();
}
public IHttpRequestBuilderFactory Services { get; private set; }
public IHttpRequestBuilderFactory SkyHookTvdb { get; private set; }
public IHttpRequestBuilderFactory TMDB { get; private set; }
public IHttpRequestBuilderFactory TMDBSingle { get; private set; }

View File

@@ -17,7 +17,7 @@ namespace NzbDrone.Common.Extensions
private const string BACKUP_FOLDER = "Backups";
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_APPDATA_FOLDER_NAME = "nzbdrone_appdata_backup" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_CLIENT_FOLDER_NAME = "NzbDrone.Update" + Path.DirectorySeparatorChar;

View File

@@ -9,4 +9,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b6eaa144-e13b-42e5-a738-c60d89c0f728")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -2,8 +2,9 @@
using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("sonarr.tv")]
[assembly: AssemblyCompany("radarr.tv")]
[assembly: AssemblyProduct("NzbDrone")]
[assembly: AssemblyVersion("0.1.0.*")]
[assembly: AssemblyCopyright("GNU General Public v3")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@@ -54,7 +54,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>..\NzbDrone.Host\NzbDrone.ico</ApplicationIcon>
<ApplicationIcon>Radarr.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>NzbDrone.Console.ConsoleApp</StartupObject>
@@ -139,6 +139,9 @@
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Radarr.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>

View File

@@ -7,5 +7,3 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("NzbDrone.Host")]
[assembly: Guid("67AADCD9-89AA-4D95-8281-3193740E70E5")]
[assembly: AssemblyVersion("0.1.0.*")]

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -25,6 +25,4 @@ using System.Runtime.InteropServices;
[assembly: Guid("699aed1b-015e-4f0d-9c81-d5557b05d260")]
[assembly: AssemblyVersion("0.1.0.*")]
[assembly: InternalsVisibleTo("NzbDrone.Core")]

View File

@@ -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();
}
}
}
}
}
}
}

View File

@@ -37,6 +37,37 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
_rTorrentDirectoryValidator = rTorrentDirectoryValidator;
}
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
{
_proxy.AddTorrentFromUrl(magnetLink, Settings);
// Download the magnet to the appropriate directory.
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
//SetPriority(remoteEpisode, hash);
SetDownloadDirectory(hash);
// Once the magnet meta download finishes, rTorrent replaces it with the actual torrent download with default settings.
// Schedule an event to apply the appropriate settings when that happens.
// var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority);
//_proxy.SetDeferredMagnetProperties(hash, Settings.TvCategory, Settings.TvDirectory, priority, Settings);
_proxy.StartTorrent(hash, Settings);
// Wait for the magnet to be resolved.
var tries = 10;
var retryDelay = 500;
if (WaitForTorrent(hash, tries, retryDelay))
{
return hash;
}
else
{
_logger.Warn("rTorrent could not resolve magnet within {0} seconds, download may remain stuck: {1}.", tries * retryDelay / 1000, magnetLink);
return hash;
}
}
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
{
_proxy.AddTorrentFromUrl(magnetLink, Settings);
@@ -68,6 +99,32 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
}
}
protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent)
{
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
var tries = 2;
var retryDelay = 100;
if (WaitForTorrent(hash, tries, retryDelay))
{
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
//SetPriority(remoteEpisode, hash);
SetDownloadDirectory(hash);
_proxy.StartTorrent(hash, Settings);
return hash;
}
else
{
_logger.Debug("rTorrent could not add file");
RemoveItem(hash, true);
throw new ReleaseDownloadException(remoteMovie.Release, "Downloading torrent failed");
}
}
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
{
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
@@ -96,7 +153,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
public override string Name => "rTorrent";
public override ProviderMessage Message => new ProviderMessage("Sonarr is unable to remove torrents that have finished seeding when using rTorrent", ProviderMessageType.Warning);
public override ProviderMessage Message => new ProviderMessage("Radarr is unable to remove torrents that have finished seeding when using rTorrent", ProviderMessageType.Warning);
public override IEnumerable<DownloadClientItem> GetItems()
{

View File

@@ -26,7 +26,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
Host = "localhost";
Port = 8080;
UrlBase = "RPC2";
TvCategory = "tv-sonarr";
TvCategory = "movies-radarr";
OlderTvPriority = (int)RTorrentPriority.Normal;
RecentTvPriority = (int)RTorrentPriority.Normal;
}

View File

@@ -46,7 +46,7 @@ namespace NzbDrone.Core.Indexers.Newznab
yield return GetDefinition("NZBFinder.ws", GetSettings("https://nzbfinder.ws", 5010, 5030, 5040, 5045));
yield return GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info"));
yield return GetDefinition("nzbplanet.net", GetSettings("https://api.nzbplanet.net"));
yield return GetDefinition("Nzbs.org", GetSettings("http://nzbs.org", 5000));
yield return GetDefinition("Nzbs.org", GetSettings("http://nzbs.org", 2000));
yield return GetDefinition("OZnzb.com", GetSettings("https://api.oznzb.com"));
yield return GetDefinition("PFmonkey", GetSettings("https://www.pfmonkey.com"));
yield return GetDefinition("SimplyNZBs", GetSettings("https://simplynzbs.com"));

View File

@@ -112,9 +112,9 @@ namespace NzbDrone.Core.Indexers.Newznab
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;

View File

@@ -79,9 +79,8 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
requestBuilder.AddQueryParam("passkey", Settings.Passkey);
requestBuilder.AddQueryParam("user", Settings.User);
requestBuilder.AddQueryParam("imdbid", "tt0076759"); //For now just search for Star Wars.
// requestBuilder.AddQueryParam("imdbid", "tt0076759"); //For now just search for Star Wars.
requestBuilder.AddQueryParam("search", "the"); // there has to be movies with 'the' in the title on any indexer
yield return new IndexerRequest(requestBuilder.Build());
}

View File

@@ -12,6 +12,7 @@ using NzbDrone.Core.MetadataSource.SkyHook.Resource;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Tv;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
namespace NzbDrone.Core.MetadataSource.SkyHook
{
@@ -175,9 +176,41 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
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)
{
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:"))
{
@@ -209,6 +242,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
.SetSegment("id", "movie")
.SetSegment("secondaryRoute", "")
.AddQueryParam("query", searchTerm)
.AddQueryParam("year", yearTerm)
.AddQueryParam("include_adult", false)
.Build();

View File

@@ -286,6 +286,7 @@
<Compile Include="Datastore\Migration\098_remove_titans_of_tv.cs">
<SubType>Code</SubType>
</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\MigrationController.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationDbFactory.cs" />

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
@@ -24,7 +24,7 @@ namespace NzbDrone.Core.Organizer
BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec);
string GetSeriesFolder(Series series, 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
@@ -58,6 +58,9 @@ namespace NzbDrone.Core.Organizer
public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})",
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 TrimSeparatorsRegex = new Regex(@"[- ._]$", RegexOptions.Compiled);
@@ -76,6 +79,7 @@ namespace NzbDrone.Core.Organizer
{
_namingConfigService = namingConfigService;
_qualityDefinitionService = qualityDefinitionService;
//_movieFormatCache = cacheManager.GetCache<MovieFormat>(GetType(), "movieFormat");
_episodeFormatCache = cacheManager.GetCache<EpisodeFormat[]>(GetType(), "episodeFormat");
_absoluteEpisodeFormatCache = cacheManager.GetCache<AbsoluteEpisodeFormat[]>(GetType(), "absoluteEpisodeFormat");
_logger = logger;
@@ -151,52 +155,20 @@ namespace NzbDrone.Core.Organizer
return GetOriginalTitle(movieFile);
}
/*if (namingConfig.StandardEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Standard)
{
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;
//TODO: Update namingConfig for Movies!
var pattern = namingConfig.StandardMovieFormat;
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
episodes = episodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber).ToList();
if (series.SeriesType == SeriesTypes.Daily)
{
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);
AddMovieTokens(tokenHandlers, movie);
AddReleaseDateTokens(tokenHandlers, movie.Year); //In case we want to separate the year
AddQualityTokens(tokenHandlers, movie, movieFile);
AddMediaInfoTokens(tokenHandlers, movieFile);
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
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 GetOriginalTitle(movieFile);
return fileName;
}
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension)
@@ -242,6 +214,8 @@ namespace NzbDrone.Core.Organizer
public BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec)
{
return new BasicNamingConfig(); //For now let's be lazy
var episodeFormat = GetEpisodeFormat(nameSpec.StandardEpisodeFormat).LastOrDefault();
if (episodeFormat == null)
@@ -315,9 +289,19 @@ namespace NzbDrone.Core.Organizer
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)
@@ -481,6 +465,17 @@ namespace NzbDrone.Core.Organizer
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)
{
tokenHandlers["{Season}"] = m => seasonNumber.ToString(m.CustomFormat);
@@ -520,6 +515,18 @@ namespace NzbDrone.Core.Organizer
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)
{
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);
}
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)
{
List<string> tokens = new List<string>();
@@ -803,6 +914,16 @@ namespace NzbDrone.Core.Organizer
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)
{
if (quality.Revision.Version > 1)
@@ -828,6 +949,16 @@ namespace NzbDrone.Core.Organizer
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)
{
if (episodeFile.SceneName.IsNullOrWhiteSpace())

View File

@@ -3,6 +3,7 @@ using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using NzbDrone.Core.MediaFiles.MediaInfo;
using System;
namespace NzbDrone.Core.Organizer
{
@@ -13,8 +14,10 @@ namespace NzbDrone.Core.Organizer
SampleResult GetDailySample(NamingConfig nameSpec);
SampleResult GetAnimeSample(NamingConfig nameSpec);
SampleResult GetAnimeMultiEpisodeSample(NamingConfig nameSpec);
SampleResult GetMovieSample(NamingConfig nameSpec);
string GetSeriesFolderSample(NamingConfig nameSpec);
string GetSeasonFolderSample(NamingConfig nameSpec);
string GetMovieFolderSample(NamingConfig nameSpec);
}
public class FileNameSampleService : IFilenameSampleService
@@ -34,10 +37,19 @@ namespace NzbDrone.Core.Organizer
private static EpisodeFile _animeEpisodeFile;
private static EpisodeFile _animeMultiEpisodeFile;
private static MovieFile _movieFile;
private static Movie _movie;
public FileNameSampleService(IBuildFileNames buildFileNames)
{
_buildFileNames = buildFileNames;
_movie = new Movie
{
Title = "Movie Title",
Year = 2010
};
_standardSeries = new Series
{
SeriesType = SeriesTypes.Standard,
@@ -106,6 +118,15 @@ namespace NzbDrone.Core.Organizer
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
{
Quality = new QualityModel(Quality.HDTV720p, new Revision(2)),
@@ -217,6 +238,16 @@ namespace NzbDrone.Core.Organizer
return result;
}
public SampleResult GetMovieSample(NamingConfig nameSpec)
{
var result = new SampleResult
{
FileName = BuildSample(_movie, _movieFile, nameSpec),
};
return result;
}
public string GetSeriesFolderSample(NamingConfig nameSpec)
{
return _buildFileNames.GetSeriesFolder(_standardSeries, nameSpec);
@@ -227,6 +258,11 @@ namespace NzbDrone.Core.Organizer
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)
{
try
@@ -238,5 +274,17 @@ namespace NzbDrone.Core.Organizer
return string.Empty;
}
}
private string BuildSample(Movie movie, MovieFile movieFile, NamingConfig nameSpec)
{
try
{
return _buildFileNames.BuildFileName(movie, movieFile, nameSpec);
}
catch (NamingFormatException)
{
return string.Empty;
}
}
}
}

View File

@@ -41,6 +41,18 @@ namespace NzbDrone.Core.Organizer
ruleBuilder.SetValidator(new NotEmptyValidator(null));
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

View File

@@ -11,12 +11,26 @@ namespace NzbDrone.Core.Organizer
ValidationFailure ValidateStandardFilename(SampleResult sampleResult);
ValidationFailure ValidateDailyFilename(SampleResult sampleResult);
ValidationFailure ValidateAnimeFilename(SampleResult sampleResult);
ValidationFailure ValidateMovieFilename(SampleResult sampleResult);
}
public class FileNameValidationService : IFilenameValidationService
{
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)
{
var validationFailure = new ValidationFailure("StandardEpisodeFormat", ERROR_MESSAGE);

View File

@@ -1,4 +1,4 @@
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Organizer
{
@@ -13,7 +13,9 @@ namespace NzbDrone.Core.Organizer
DailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title} {Quality Full}",
AnimeEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}",
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; }
@@ -24,5 +26,7 @@ namespace NzbDrone.Core.Organizer
public string AnimeEpisodeFormat { get; set; }
public string SeriesFolderFormat { get; set; }
public string SeasonFolderFormat { get; set; }
public string StandardMovieFormat { get; set; }
public string MovieFolderFormat { get; set; }
}
}

View File

@@ -11,6 +11,4 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3C29FEF7-4B07-49ED-822E-1C29DC49BFAB")]
[assembly: AssemblyVersion("0.1.0.*")]
[assembly: InternalsVisibleTo("NzbDrone.Core.Test")]

View File

@@ -28,7 +28,8 @@ namespace NzbDrone.Core.Update
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);
}
}
}

View File

@@ -56,6 +56,9 @@
<PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Radarr.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Owin, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -134,9 +137,6 @@
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="NzbDrone.ico" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
<Visible>False</Visible>
@@ -185,7 +185,9 @@
<Name>NzbDrone.SignalR</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Content Include="Radarr.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -8,4 +8,3 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Radarr.exe")]
[assembly: Guid("C2172AF4-F9A6-4D91-BAEE-C2E4EE680613")]
[assembly: AssemblyVersion("0.1.0.*")]

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -20,5 +20,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("8a49cb1d-87ac-42f9-a582-607365a6bd79")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -21,4 +21,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("32ec29e2-40ba-4050-917d-e295d85d4969")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -20,5 +20,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("01493ea5-494f-43bf-be18-8ae4d0708fc6")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -6,5 +6,3 @@ using System.Runtime.InteropServices;
// associated with an assembly.
[assembly: AssemblyTitle("NzbDrone.SignalR")]
[assembly: Guid("98bd985a-4f23-4201-8ed3-f6f3d7f2a5fe")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -21,4 +21,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f3e91f6e-d01d-4f20-8255-147cc10f04e3")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -20,5 +20,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7b773a86-574d-48c3-9e89-6f2e0dff714b")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -20,5 +20,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b323e212-2d04-4c7f-9097-c356749ace4d")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -8,5 +8,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e4560a3d-8053-4d57-a260-bfe52f4cc357")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -54,7 +54,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>..\NzbDrone.Host\NzbDrone.ico</ApplicationIcon>
<ApplicationIcon>Resources\Radarr.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>NzbDrone.WindowsApp</StartupObject>
@@ -147,6 +147,7 @@
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
@@ -155,6 +156,10 @@
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Radarr.ico" />
<None Include="Resources\Radarr.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>

View File

@@ -8,4 +8,3 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Radarr.exe")]
[assembly: Guid("67AADCD9-89AA-4D95-8281-3193740E70E5")]
[assembly: AssemblyVersion("0.1.0.*")]

View File

@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.32559
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -9,6 +9,9 @@
//------------------------------------------------------------------------------
namespace NzbDrone.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@@ -60,9 +63,9 @@ namespace NzbDrone.Properties {
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon NzbDroneIcon {
internal static System.Drawing.Icon Radarr {
get {
object obj = ResourceManager.GetObject("NzbDroneIcon", resourceCulture);
object obj = ResourceManager.GetObject("Radarr", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}

View File

@@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="NzbDroneIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\NzbDrone.Host\NzbDrone.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="Radarr" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Radarr.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

BIN
src/NzbDrone/Radarr.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

View File

@@ -39,7 +39,7 @@ namespace NzbDrone.SysTray
_trayMenu.MenuItems.Add("Exit", OnExit);
_trayIcon.Text = string.Format("Radarr - {0}", BuildInfo.Version);
_trayIcon.Icon = Properties.Resources.NzbDroneIcon;
_trayIcon.Icon = Properties.Resources.Radarr;
_trayIcon.ContextMenu = _trayMenu;
_trayIcon.Visible = true;

BIN
src/Radarr.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -5,6 +5,4 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("13976baa-e5ba-42b2-8ad7-8d568b68a53b")]
[assembly: AssemblyVersion("0.1.0.*")]
[assembly: Guid("13976baa-e5ba-42b2-8ad7-8d568b68a53b")]

View File

@@ -3,5 +3,3 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("UninstallService")]
[assembly: Guid("0a964b21-9de9-40b3-9378-0474fd5f21a8")]
[assembly: AssemblyVersion("0.1.0.*")]

BIN
src/Thumbs.db Normal file

Binary file not shown.

BIN
src/UI/.DS_Store vendored

Binary file not shown.

View File

@@ -2,7 +2,7 @@ var vent = require('vent');
var AppLayout = require('../AppLayout');
var Marionette = require('marionette');
var RootFolderLayout = require('./RootFolders/RootFolderLayout');
//var ExistingMoviesCollectionView = require('./Existing/AddExistingSeriesCollectionView');
var ExistingMoviesCollectionView = require('./Existing/AddExistingMovieCollectionView');
var AddMoviesView = require('./AddMoviesView');
var ProfileCollection = require('../Profile/ProfileCollection');
var RootFolderCollection = require('./RootFolders/RootFolderCollection');
@@ -36,9 +36,9 @@ module.exports = Marionette.Layout.extend({
},
_folderSelected : function(options) {
//vent.trigger(vent.Commands.CloseModalCommand);
vent.trigger(vent.Commands.CloseModalCommand);
//TODO: Fix this shit.
//this.workspace.show(new ExistingMoviesCollectionView({ model : options.model }));
this.workspace.show(new ExistingMoviesCollectionView({ model : options.model }));
},
_importMovies : function() {

View File

@@ -26,7 +26,7 @@ module.exports = Marionette.Layout.extend({
},
initialize : function(options) {
console.log(options)
console.log(options);
this.isExisting = options.isExisting;
this.collection = new AddMoviesCollection();
@@ -125,7 +125,7 @@ module.exports = Marionette.Layout.extend({
}
else if (!this.isExisting) {
this.resultCollectionView.setExisting(options.movie.get('tmdbId'))
this.resultCollectionView.setExisting(options.movie.get('tmdbId'));
/*this.collection.term = '';
this.collection.reset();
this._clearResults();

View File

@@ -1,11 +1,11 @@
var Marionette = require('marionette');
var AddSeriesView = require('../AddSeriesView');
var AddMoviesView = require('../AddMoviesView');
var UnmappedFolderCollection = require('./UnmappedFolderCollection');
module.exports = Marionette.CompositeView.extend({
itemView : AddSeriesView,
itemView : AddMoviesView,
itemViewContainer : '.x-loading-folders',
template : 'AddSeries/Existing/AddExistingSeriesCollectionViewTemplate',
template : 'AddMovies/Existing/AddExistingMovieCollectionViewTemplate',
ui : {
loadingFolders : '.x-loading-folders'

View File

@@ -23,7 +23,7 @@ module.exports = Marionette.CollectionView.extend({
setExisting : function(tmdbid) {
var movies = this.collection.where({ tmdbId : tmdbid });
console.warn(movies)
console.warn(movies);
//debugger;
if (movies.length > 0) {
this.children.findByModel(movies[0])._configureTemplateHelpers();

View File

@@ -92,14 +92,14 @@ var view = Marionette.ItemView.extend({
_configureTemplateHelpers : function() {
var existingMovies = MoviesCollection.where({ tmdbId : this.model.get('tmdbId') });
console.log(existingMovies)
console.log(existingMovies);
if (existingMovies.length > 0) {
this.templateHelpers.existing = existingMovies[0].toJSON();
}
this.templateHelpers.profiles = Profiles.toJSON();
console.log(this.model)
console.log(this.templateHelpers.existing)
console.log(this.model);
console.log(this.templateHelpers.existing);
if (!this.model.get('isExisting')) {
this.templateHelpers.rootFolders = RootFolders.toJSON();
}
@@ -245,14 +245,14 @@ var view = Marionette.ItemView.extend({
options.ignoreEpisodesWithoutFiles = true;
}
else if (monitor === 'latest') {
this.model.setSeasonPass(lastSeason.seasonNumber);
}
// else if (monitor === 'latest') {
// this.model.setSeasonPass(lastSeason.seasonNumber);
// }
else if (monitor === 'first') {
this.model.setSeasonPass(lastSeason.seasonNumber + 1);
this.model.setSeasonMonitored(firstSeason.seasonNumber);
}
// else if (monitor === 'first') {
// this.model.setSeasonPass(lastSeason.seasonNumber + 1);
// this.model.setSeasonMonitored(firstSeason.seasonNumber);
// }
else if (monitor === 'missing') {
options.ignoreEpisodesWithFiles = true;
@@ -262,9 +262,9 @@ var view = Marionette.ItemView.extend({
options.ignoreEpisodesWithoutFiles = true;
}
else if (monitor === 'none') {
this.model.setSeasonPass(lastSeason.seasonNumber + 1);
}
// else if (monitor === 'none') {
// this.model.setSeasonPass(lastSeason.seasonNumber + 1);
// }
return options;
}

View File

@@ -42,7 +42,7 @@ module.exports = Marionette.Layout.extend({
events : {
'click .x-episode-file-editor' : '_openEpisodeFileEditor',
'click .x-monitored' : '_toggleMonitored',
'click .x-edit' : '_editMovies',
'click .x-edit' : '_editMovie',
'click .x-refresh' : '_refreshMovies',
'click .x-rename' : '_renameMovies',
'click .x-search' : '_moviesSearch',
@@ -167,8 +167,8 @@ module.exports = Marionette.Layout.extend({
}
},
_editMovies : function() {
vent.trigger(vent.Commands.EditMoviesCommand, { movie : this.model });
_editMovie : function() {
vent.trigger(vent.Commands.EditMovieCommand, { movie : this.model });
},
_refreshMovies : function() {

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>

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;

View File

@@ -23,7 +23,7 @@ module.exports = Marionette.ItemView.extend({
},
_editSeries : function() {
vent.trigger(vent.Commands.EditSeriesCommand, { series : this.model });
vent.trigger(vent.Commands.EditMovieCommand, { movie : this.model });
},
_refreshSeries : function() {

View File

@@ -14,8 +14,8 @@
</div>
<div class="col-md-2 col-xs-2">
<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-edit x-edit" title="Edit Series"/>
<i class="icon-sonarr-refresh x-refresh" title="Update movie info and scan disk"/>
<i class="icon-sonarr-edit x-edit" title="Edit Movie"/>
</div>
</div>
</div>

View File

@@ -2,7 +2,7 @@
<legend>File Management</legend>
<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="input-group">
@@ -17,7 +17,7 @@
</label>
<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>
</div>
</div>
@@ -39,7 +39,7 @@
</label>
<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>
</div>
</div>

View File

@@ -26,10 +26,10 @@ var view = Marionette.ItemView.extend({
},
_parseNamingModel : function() {
var standardFormat = this.namingModel.get('standardEpisodeFormat');
var standardFormat = this.namingModel.get('standardMovieFormat');
var includeSeriesTitle = standardFormat.match(/\{Series[-_. ]Title\}/i);
var includeEpisodeTitle = standardFormat.match(/\{Episode[-_. ]Title\}/i);
var includeSeriesTitle = false;//standardFormat.match(/\{Series[-_. ]Title\}/i);
var includeEpisodeTitle = false;//standardFormat.match(/\{Episode[-_. ]Title\}/i);
var includeQuality = standardFormat.match(/\{Quality[-_. ]Title\}/i);
var numberStyle = standardFormat.match(/s?\{season(?:\:0+)?\}[ex]\{episode(?:\:0+)?\}/i);
var replaceSpaces = standardFormat.indexOf(' ') === -1;
@@ -115,4 +115,4 @@ var view = Marionette.ItemView.extend({
}
});
module.exports = AsModelBoundView.call(view);
module.exports = AsModelBoundView.call(view);

View File

@@ -19,7 +19,9 @@ module.exports = (function() {
namingTokenHelper : '.x-naming-token-helper',
multiEpisodeStyle : '.x-multi-episode-style',
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 : {
"change .x-rename-episodes" : '_setFailedDownloadOptionsVisibility',
@@ -58,6 +60,8 @@ module.exports = (function() {
this.ui.animeMultiEpisodeExample.html(this.namingSampleModel.get('animeMultiEpisodeExample'));
this.ui.seriesFolderExample.html(this.namingSampleModel.get('seriesFolderExample'));
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) {
e.preventDefault();

View File

@@ -1,8 +1,8 @@
<fieldset>
<legend>Episode Naming</legend>
<legend>Movie Naming</legend>
<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="input-group">
@@ -18,7 +18,7 @@
</label>
<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>
</div>
</div>
@@ -51,25 +51,23 @@
<div class="basic-setting x-basic-naming"></div>
<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">
<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 class="col-sm-8 col-sm-pull-1">
<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">
<button class="btn btn-icon-only dropdown-toggle" data-toggle="dropdown">
<i class="icon-sonarr-add"></i>
</button>
<ul class="dropdown-menu">
{{> SeriesTitleNamingPartial}}
{{> SeasonNamingPartial}}
{{> EpisodeNamingPartial}}
{{> EpisodeTitleNamingPartial}}
{{> MovieTitleNamingPartial}}
{{> ReleaseYearNamingPartial}}
{{> QualityNamingPartial}}
{{> MediaInfoNamingPartial}}
{{> ReleaseGroupNamingPartial}}
@@ -81,7 +79,7 @@
</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>
<div class="col-sm-1 col-sm-push-8 help-inline">
@@ -111,9 +109,9 @@
</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>
<div class="col-sm-1 col-sm-push-8 help-inline">
@@ -144,31 +142,32 @@
</div>
</div>
</div>
</div>
</div>--}}
<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">
<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 class="col-sm-8 col-sm-pull-1">
<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">
<button class="btn btn-icon-only dropdown-toggle" data-toggle="dropdown">
<i class="icon-sonarr-add"></i>
</button>
<ul class="dropdown-menu">
{{> SeriesTitleNamingPartial}}
{{> MovieTitleNamingPartial}}
{{> ReleaseYearNamingPartial}}
</ul>
</div>
</div>
</div>
</div>
<div class="form-group">
{{!--<div class="form-group">
<label class="col-sm-3 control-label">Season Folder Format</label>
<div class="col-sm-8">
@@ -186,9 +185,9 @@
</div>
</div>
</div>
</div>
</div>--}}
<div class="x-naming-options">
{{!--<div class="x-naming-options">
<div class="form-group">
<label class="col-sm-3 control-label">Multi-Episode Style</label>
@@ -203,17 +202,17 @@
</select>
</div>
</div>
</div>
</div>--}}
<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">
<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 class="form-group">
{{!--<div class="form-group">
<label class="col-sm-3 control-label">Multi-Episode Example</label>
<div class="col-sm-8">
@@ -242,21 +241,21 @@
<div class="col-sm-8">
<p class="form-control-static x-anime-multi-episode-example naming-example"></p>
</div>
</div>
</div>--}}
<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">
<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 class="form-group">
{{!--<div class="form-group">
<label class="col-sm-3 control-label">Season Folder Example</label>
<div class="col-sm-8">
<p class="form-control-static x-season-folder-example naming-example"></p>
</div>
</div>
</div>--}}
</fieldset>

View File

@@ -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>

View File

@@ -0,0 +1 @@
<li><a href="#" data-token="Release Year">Release Year</a></li>

View File

@@ -2,7 +2,7 @@
<legend>Folders</legend>
<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="input-group">
@@ -18,7 +18,7 @@
</label>
<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>
</div>
</div>
@@ -46,7 +46,7 @@
</label>
<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>
</div>
</div>
@@ -71,7 +71,7 @@
<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-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>
</div>
</div>

View File

@@ -2,6 +2,7 @@ var vent = require('vent');
var AppLayout = require('../../AppLayout');
var Marionette = require('marionette');
var EditSeriesView = require('../../Series/Edit/EditSeriesView');
var EditMovieView = require('../../Movies/Edit/EditMovieView');
var DeleteSeriesView = require('../../Series/Delete/DeleteSeriesView');
var EpisodeDetailsLayout = require('../../Episode/EpisodeDetailsLayout');
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.CloseModal2Command, this._closeModal2, 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.ShowEpisodeDetails, this._showEpisode, this);
vent.on(vent.Commands.ShowMovieDetails, this._showMovie, this);
@@ -49,6 +51,11 @@ module.exports = Marionette.AppRouter.extend({
AppLayout.modalRegion.show(view);
},
_editMovie : function(options) {
var view = new EditMovieView({ model : options.movie });
AppLayout.modalRegion.show(view);
},
_deleteSeries : function(options) {
var view = new DeleteSeriesView({ model : options.series });
AppLayout.modalRegion.show(view);

View File

@@ -12,6 +12,7 @@ vent.Events = {
vent.Commands = {
EditSeriesCommand : 'EditSeriesCommand',
EditMovieCommand : 'EditMovieCommand',
DeleteSeriesCommand : 'DeleteSeriesCommand',
OpenModalCommand : 'OpenModalCommand',
CloseModalCommand : 'CloseModalCommand',