mirror of
https://github.com/Radarr/Radarr.git
synced 2026-03-28 18:05:41 -04:00
Compare commits
252 Commits
v0.1.0.343
...
v0.2.0.166
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dea305e921 | ||
|
|
e2eab31548 | ||
|
|
fe62e18f0d | ||
|
|
f1fa1553cf | ||
|
|
b576ae813d | ||
|
|
99123be936 | ||
|
|
dd0a033b0f | ||
|
|
c64597c9f1 | ||
|
|
6d2f81e3ed | ||
|
|
4263808360 | ||
|
|
c5ca2babf7 | ||
|
|
08db74d6e6 | ||
|
|
b309a9b01f | ||
|
|
2730745607 | ||
|
|
ae0df2aef0 | ||
|
|
6d665aeb21 | ||
|
|
967d3fd5c0 | ||
|
|
199d9c93ed | ||
|
|
30d2b41fbb | ||
|
|
75bb2533a3 | ||
|
|
9b3b4eb55b | ||
|
|
42f84b830c | ||
|
|
eb0f825cfc | ||
|
|
56a5b6ec89 | ||
|
|
af478d3799 | ||
|
|
c2d40051d4 | ||
|
|
281e516495 | ||
|
|
f63c3091f4 | ||
|
|
50f49863b7 | ||
|
|
941b3bd701 | ||
|
|
f60b8cefca | ||
|
|
7c5f2ca54e | ||
|
|
401a650273 | ||
|
|
105af5cf11 | ||
|
|
637c2e43eb | ||
|
|
53373e6f4a | ||
|
|
ad147ed425 | ||
|
|
ed35e2f194 | ||
|
|
674919dbf5 | ||
|
|
15b77e303f | ||
|
|
757ca1d72c | ||
|
|
8c8c7a99e3 | ||
|
|
b3dfb960b5 | ||
|
|
98856e6747 | ||
|
|
8fb5049899 | ||
|
|
3f62911a4f | ||
|
|
170349c950 | ||
|
|
6c413d83eb | ||
|
|
3afd27cad3 | ||
|
|
149faf467d | ||
|
|
ce52bb8f68 | ||
|
|
4bb5857444 | ||
|
|
620f09ef8b | ||
|
|
16c1a2ee50 | ||
|
|
4b559cf29c | ||
|
|
ca03f21b03 | ||
|
|
f481fe9ea9 | ||
|
|
3a0278d0a1 | ||
|
|
d18b15d504 | ||
|
|
dc7e75187c | ||
|
|
68a0ef65df | ||
|
|
fe11928487 | ||
|
|
41dda3af48 | ||
|
|
8c3260c545 | ||
|
|
bd0ec5dfce | ||
|
|
ad38437b70 | ||
|
|
4447b7cd62 | ||
|
|
d33de0d158 | ||
|
|
dd5049b483 | ||
|
|
29586667cb | ||
|
|
5daece0ed4 | ||
|
|
5dc63e5607 | ||
|
|
7df283e57f | ||
|
|
e9b6c250f7 | ||
|
|
10515156d1 | ||
|
|
4260b58535 | ||
|
|
3a386f2e18 | ||
|
|
d3bd0c9b69 | ||
|
|
3180e648b4 | ||
|
|
d0c93759c6 | ||
|
|
f7471940c4 | ||
|
|
3a6873cc4d | ||
|
|
330ae38ec2 | ||
|
|
a0ecb19e32 | ||
|
|
38c966c07b | ||
|
|
ad824d4da5 | ||
|
|
e76c160afe | ||
|
|
6a62546a4d | ||
|
|
0efdc78f8d | ||
|
|
fdd06127fc | ||
|
|
317f8917b9 | ||
|
|
4038ce18c3 | ||
|
|
7f3ca85953 | ||
|
|
b93a9719fe | ||
|
|
2ef18edf08 | ||
|
|
d61b9ab207 | ||
|
|
abf4b137f1 | ||
|
|
774c85f06b | ||
|
|
a060335bbc | ||
|
|
5a8d944397 | ||
|
|
0b70a5c315 | ||
|
|
91cded3b71 | ||
|
|
84112dc85b | ||
|
|
b1b947ae7f | ||
|
|
1b035f8657 | ||
|
|
9d50f4d651 | ||
|
|
c06a6dc988 | ||
|
|
f198ca2b77 | ||
|
|
9cfc766889 | ||
|
|
5ef1e40403 | ||
|
|
c9e6835d7b | ||
|
|
604cea00f6 | ||
|
|
b4782da1d1 | ||
|
|
d5504043c5 | ||
|
|
81ebbcad70 | ||
|
|
92e9dc6ee1 | ||
|
|
5e8b617625 | ||
|
|
2cbe17151d | ||
|
|
95bd615718 | ||
|
|
8e8c4ff497 | ||
|
|
5eddcc1660 | ||
|
|
d42165a93a | ||
|
|
99012d8a40 | ||
|
|
8bc42c76e4 | ||
|
|
b7f72c6259 | ||
|
|
64ef8db037 | ||
|
|
3b5887bf09 | ||
|
|
40a75949ba | ||
|
|
6747267d19 | ||
|
|
13db03f97c | ||
|
|
cd68eea790 | ||
|
|
cfe55d00ae | ||
|
|
1d88313424 | ||
|
|
9513068467 | ||
|
|
9206258370 | ||
|
|
0fa1509ca6 | ||
|
|
c5eb772f7a | ||
|
|
04fec6d4d8 | ||
|
|
d0b5e380d7 | ||
|
|
df69c58d2b | ||
|
|
27114c9399 | ||
|
|
cfca07996b | ||
|
|
e97b80f630 | ||
|
|
792679fd81 | ||
|
|
ecf47d4b17 | ||
|
|
3b1d49a78f | ||
|
|
753f3eb863 | ||
|
|
9fc2d22d19 | ||
|
|
3cb42f06c2 | ||
|
|
a6c396a595 | ||
|
|
bac9076b1e | ||
|
|
b228273be0 | ||
|
|
e7fa4cba19 | ||
|
|
0506cc4185 | ||
|
|
cde8b4dd97 | ||
|
|
0a0a44162c | ||
|
|
125f46fbec | ||
|
|
f3222ca7c7 | ||
|
|
d252a8b232 | ||
|
|
48559cf964 | ||
|
|
c734e8bc7e | ||
|
|
3c7d7756e6 | ||
|
|
683bda49d8 | ||
|
|
52fb29ee18 | ||
|
|
236e16c9a5 | ||
|
|
0584038273 | ||
|
|
6685aea144 | ||
|
|
e4f7aa52df | ||
|
|
f61c4feb00 | ||
|
|
04e8c635e0 | ||
|
|
93ea5cfdee | ||
|
|
1b7288e7cb | ||
|
|
f1914082b8 | ||
|
|
6016948329 | ||
|
|
708db1a75c | ||
|
|
994e881ba6 | ||
|
|
893e20c27b | ||
|
|
23aace6149 | ||
|
|
e774e6a038 | ||
|
|
f19a1a5960 | ||
|
|
03156d62f6 | ||
|
|
04d01dc781 | ||
|
|
cfae8807aa | ||
|
|
f90e77987e | ||
|
|
2ed0738b30 | ||
|
|
74c5664a7f | ||
|
|
4c9abe3d84 | ||
|
|
7a45394820 | ||
|
|
588a48e65d | ||
|
|
83453e2464 | ||
|
|
e6809585c9 | ||
|
|
14bf63e21d | ||
|
|
b5d932866a | ||
|
|
0b8a84a57c | ||
|
|
3555b4ce20 | ||
|
|
8cad976e7f | ||
|
|
ad7b6a8ec2 | ||
|
|
906ecfb6a1 | ||
|
|
03cc3a1ad2 | ||
|
|
d62dbd48ae | ||
|
|
cb12945270 | ||
|
|
af74854b8e | ||
|
|
f35fae109b | ||
|
|
804b2130a8 | ||
|
|
49537a2efe | ||
|
|
1dfb4ddcd8 | ||
|
|
fb7969e046 | ||
|
|
cd4863b974 | ||
|
|
55f4a81dee | ||
|
|
d006df8d7c | ||
|
|
97095733dd | ||
|
|
d08b0ce47a | ||
|
|
caa5a7e6b7 | ||
|
|
9376c02158 | ||
|
|
1ebd639e36 | ||
|
|
eff34725af | ||
|
|
00d4bfd712 | ||
|
|
5f9e285c70 | ||
|
|
902824cdbd | ||
|
|
d3cbf9a8ff | ||
|
|
c63704ba0d | ||
|
|
da404d6435 | ||
|
|
d9a6c4f211 | ||
|
|
7436997f9b | ||
|
|
4c2be68549 | ||
|
|
6d1766d81a | ||
|
|
3e676d2073 | ||
|
|
6da73d73a5 | ||
|
|
b9c98205e0 | ||
|
|
07d2f5b6a0 | ||
|
|
bfa479507c | ||
|
|
4182728901 | ||
|
|
5be5709043 | ||
|
|
ee5a2ec289 | ||
|
|
cdfb95f425 | ||
|
|
451060cb65 | ||
|
|
4d795e13cd | ||
|
|
ff6bf235aa | ||
|
|
a272127a00 | ||
|
|
e3bc6de734 | ||
|
|
23249de728 | ||
|
|
05e4af9ae7 | ||
|
|
1864a79f99 | ||
|
|
5843a881e6 | ||
|
|
d898fbb4b0 | ||
|
|
721767331b | ||
|
|
abd4c1a1ad | ||
|
|
df971b1289 | ||
|
|
e5c81eefd2 | ||
|
|
49c7c033d9 | ||
|
|
f7fb238fb4 | ||
|
|
52dbd8d708 |
27
.gitignore
vendored
27
.gitignore
vendored
@@ -101,16 +101,21 @@ App_Data/*.ldf
|
||||
_NCrunch_*
|
||||
_TeamCity*
|
||||
|
||||
# Sonarr
|
||||
config.xml
|
||||
nzbdrone.log*txt
|
||||
# Radarr
|
||||
Backups/
|
||||
logs/
|
||||
MediaCover/
|
||||
UpdateLogs/
|
||||
xdg/
|
||||
config.xml
|
||||
logs.db*
|
||||
nzbdrone.db*
|
||||
nzbdrone.pid
|
||||
*workspace.xml
|
||||
*.test-cache
|
||||
*.userprefs
|
||||
*/test-results/*
|
||||
src/UI/.idea/*
|
||||
*log.txt
|
||||
node_modules/
|
||||
_output*
|
||||
_rawPackage/
|
||||
@@ -122,18 +127,26 @@ setup/Output/
|
||||
|
||||
UI.Phantom/
|
||||
|
||||
#VS outout folders
|
||||
# VS outout folders
|
||||
bin
|
||||
obj
|
||||
output/*
|
||||
|
||||
#Packages
|
||||
# Packages
|
||||
Radarr_*/
|
||||
Radarr_*.zip
|
||||
Radarr_*.gz
|
||||
|
||||
#OS X metadata files
|
||||
# macOS metadata files
|
||||
._*
|
||||
.DS_Store
|
||||
|
||||
_start
|
||||
_temp_*/**/*
|
||||
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
|
||||
# AppVeyor
|
||||
/tools-cake/
|
||||
/_artifacts/
|
||||
|
||||
10
.travis.yml
10
.travis.yml
@@ -1,12 +1,14 @@
|
||||
language: csharp
|
||||
solution: src/NzbDrone.sln
|
||||
script: # the following commands are just examples, use whatever your build process requires
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- nodejs
|
||||
- npm
|
||||
script:
|
||||
- ./build.sh
|
||||
- chmod +x test.sh
|
||||
# - ./test.sh Linux Unit Takes far too long, maybe even crashes travis :/
|
||||
install:
|
||||
- sudo apt-get install nodejs
|
||||
- sudo apt-get install npm
|
||||
after_success:
|
||||
- chmod +x package.sh
|
||||
- ./package.sh
|
||||
|
||||
4
CLA.md
4
CLA.md
@@ -1,6 +1,6 @@
|
||||
# Sonarr Individual Contributor License Agreement #
|
||||
# Radarr Individual Contributor License Agreement #
|
||||
|
||||
Thank you for your interest in contributing to Sonarr ("We" or "Us").
|
||||
Thank you for your interest in contributing to Radarr ("We" or "Us").
|
||||
This contributor agreement ("Agreement") documents the rights granted by contributors to Us. To make this document effective, please complete the form below. This is a legally binding document, so please read it carefully before agreeing to it. The Agreement may cover more than one software project managed by Us.
|
||||
|
||||
## 1. Definitions ##
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to Contribute #
|
||||
|
||||
We're always looking for people to help make Sonarr even better, there are a number of ways to contribute.
|
||||
We're always looking for people to help make Radarr even better, there are a number of ways to contribute.
|
||||
|
||||
## Documentation ##
|
||||
Setup guides, FAQ, the more information we have on the wiki the better.
|
||||
@@ -15,7 +15,7 @@ Setup guides, FAQ, the more information we have on the wiki the better.
|
||||
|
||||
### Getting started ###
|
||||
|
||||
1. Fork Sonarr
|
||||
1. Fork Radarr
|
||||
2. Clone (develop branch) *you may need pull in submodules separately if you client doesn't clone them automatically (CurlSharp)*
|
||||
3. Run `npm install`
|
||||
4. Run `npm start` - Used to compile the UI components and copy them.
|
||||
@@ -24,8 +24,8 @@ Setup guides, FAQ, the more information we have on the wiki the better.
|
||||
5. Compile in Visual Studio
|
||||
|
||||
### Contributing Code ###
|
||||
- If you're adding a new, already requested feature, please comment on [Github Issues](https://github.com/Sonarr/Sonarr/issues "Github Issues") so work is not duplicated (If you want to add something not already on there, please talk to us first)
|
||||
- Rebase from Sonarr's develop branch, don't merge
|
||||
- If you're adding a new, already requested feature, please comment on [Github Issues](https://github.com/Radarr/Radarr/issues "Github Issues") so work is not duplicated (If you want to add something not already on there, please talk to us first)
|
||||
- Rebase from Radarr's develop branch, don't merge
|
||||
- Make meaningful commits, or squash them
|
||||
- Feel free to make a pull request before work is complete, this will let us see where its at and make comments/suggest improvements
|
||||
- Reach out to us on the forums or on IRC if you have any questions
|
||||
|
||||
94
README.md
Normal file
94
README.md
Normal file
@@ -0,0 +1,94 @@
|
||||
## Status
|
||||
|
||||
[](https://github.com/Radarr/Radarr/issues)
|
||||
[](https://github.com/Radarr/Radarr/pulls)
|
||||
[](http://www.gnu.org/licenses/gpl.html)
|
||||
[](https://github.com/Radarr/Radarr)
|
||||
[](https://github.com/Radar/Radarr/releases/latest)
|
||||
[](https://hub.docker.com/r/linuxserver/radarr/)
|
||||
|
||||
| Service | Master | Develop |
|
||||
|----------|:---------------------------:|:----------------------------:|
|
||||
| AppVeyor | [](https://ci.appveyor.com/project/galli-leo/Radarr) | [](https://ci.appveyor.com/project/galli-leo/Radarr-usby1) |
|
||||
| Travis | [](https://travis-ci.org/Radarr/Radarr) | [](https://travis-ci.org/Radarr/Radarr) |
|
||||
|
||||
This fork of Sonarr aims to turn it into something like CouchPotato.
|
||||
|
||||
## Downloads
|
||||
|
||||
[](https://github.com/Radarr/Radarr/releases)
|
||||
|
||||
[](https://ci.appveyor.com/project/galli-leo/radarr-usby1/build/artifacts)
|
||||
|
||||
[](https://store.docker.com/community/images/linuxserver/radarr)
|
||||
[](https://store.docker.com/community/images/lsioarmhf/radarr)
|
||||
[](https://store.docker.com/community/images/lsioarmhf/radarr-aarch64)
|
||||
|
||||
To connect to the UI, fire up your browser and open <http://localhost:7878> or <http://your-ip:7878>.
|
||||
|
||||
## Support
|
||||
|
||||
[](https://discord.gg/AD3UP37)
|
||||
[](https://www.reddit.com/r/radarr)
|
||||
[](https://github.com/Radarr/Radarr/issues)
|
||||
|
||||
## Features
|
||||
|
||||
### Currently Working
|
||||
|
||||
* Adding new movies
|
||||
* Manually searching for releases of movies
|
||||
* Automatically searching for releases
|
||||
* 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
|
||||
* Importing of Sonarr config
|
||||
|
||||
### Major Features
|
||||
|
||||
* Support for major platforms: Windows, Linux, macOS, Raspberry Pi, etc.
|
||||
* Can watch for better quality of the movies you have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
|
||||
* 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
|
||||
* Full integration with SABnzbd and NZBGet
|
||||
* Full integration with Kodi, Plex (notification, library update, metadata)
|
||||
* And a beautiful UI
|
||||
|
||||
## Configuring Development Environment
|
||||
|
||||
### Requirements
|
||||
|
||||
* [Visual Studio Community](https://www.visualstudio.com/vs/community/) or [MonoDevelop](http://www.monodevelop.com)
|
||||
* [Git](https://git-scm.com/downloads)
|
||||
* [Node.js](https://nodejs.org/en/download/)
|
||||
|
||||
### Setup
|
||||
|
||||
* Make sure all the required software mentioned above are installed
|
||||
* Clone the repository into your development machine ([*info*](https://help.github.com/desktop/guides/contributing/working-with-your-remote-repository-on-github-or-github-enterprise))
|
||||
* Grab the submodules `git submodule init && git submodule update`
|
||||
* Install the required Node Packages `npm install`
|
||||
* Start gulp to monitor your dev environment for any changes that need post processing using `npm start` command.
|
||||
|
||||
> **Notice**
|
||||
> Gulp must be running at all times while you are working with Radarr client source files.
|
||||
|
||||
### Development
|
||||
|
||||
* Open `NzbDrone.sln` in Visual Studio or run the build.sh script, if Mono is installed
|
||||
* Make sure `NzbDrone.Console` is set as the startup project
|
||||
|
||||
## Sponsors
|
||||
|
||||
[JetBrains](http://www.jetbrains.com) for providing us with free licenses to their great tools:
|
||||
* [ReSharper](http://www.jetbrains.com/resharper)
|
||||
* [WebStorm](http://www.jetbrains.com/webstorm)
|
||||
* [TeamCity](http://www.jetbrains.com/teamcity)
|
||||
48
appveyor.yml
Normal file
48
appveyor.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
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
|
||||
|
||||
pull_requests:
|
||||
do_not_increment_build_number: true
|
||||
|
||||
only_commits:
|
||||
files:
|
||||
- src/
|
||||
- osx/
|
||||
- gulp/
|
||||
- logo/
|
||||
303
build-appveyor.cake
Normal file
303
build-appveyor.cake
Normal 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
184
build-appveyor.ps1
Normal 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
|
||||
26
package.sh
26
package.sh
@@ -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
|
||||
|
||||
71
readme.md
71
readme.md
@@ -1,71 +0,0 @@
|
||||
# Radarr [](https://travis-ci.org/galli-leo/Radarr)#
|
||||
|
||||
This fork of Sonarr aims to turn it into something like Couchpotato.
|
||||
|
||||
## Currently working:
|
||||
* Adding new movies
|
||||
* Manually searching for releases of movies.
|
||||
* Automatically searching for releases.
|
||||
* 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.
|
||||
* Importing of Sonarr config.
|
||||
|
||||
## Download
|
||||
The latest precompiled binary versions can be found here: https://github.com/galli-leo/Radarr/releases.
|
||||
|
||||
For more up to date versions (but also sometimes broken), daily builds can be found here:
|
||||
* [OSX](https://leonardogalli.ch/radarr/builds/latest.php?os=osx)
|
||||
* [Windows](https://leonardogalli.ch/radarr/builds/latest.php?os=windows)
|
||||
* [Linux](https://leonardogalli.ch/radarr/builds/latest.php?os=mono)
|
||||
|
||||
## Major Features Include: ##
|
||||
|
||||
* Support for major platforms: Windows, Linux, OSX, Raspberry Pi, etc.
|
||||
* 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.
|
||||
* Full integration with SABNzbd and NzbGet.
|
||||
* Full integration with XBMC, Plex (notification, library update, metadata).
|
||||
* And a beautiful UI
|
||||
|
||||
## Configuring Development Environment: ##
|
||||
|
||||
### Requirements ###
|
||||
- Visual Studio 2015 [Free Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx) or Mono
|
||||
- [Git](http://git-scm.com/downloads)
|
||||
- [NodeJS](http://nodejs.org/download/)
|
||||
|
||||
### Setup ###
|
||||
|
||||
- Make sure all the required software mentioned above are installed.
|
||||
- Clone the repository into your development machine. [*info*](https://help.github.com/articles/working-with-repositories)
|
||||
- Grab the submodules `git submodule init && git submodule update`
|
||||
- install the required Node Packages `npm install`
|
||||
- start gulp to monitor your dev environment for any changes that need post processing using `npm start` command.
|
||||
|
||||
*Please note gulp must be running at all times while you are working with Sonarr client source files.*
|
||||
|
||||
|
||||
### Development ###
|
||||
- Open `NzbDrone.sln` in Visual Studio or run the build.sh script, if Mono is installed.
|
||||
- Make sure `NzbDrone.Console` is set as the startup project
|
||||
|
||||
|
||||
### License ###
|
||||
* [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
|
||||
Copyright 2010-2016
|
||||
|
||||
|
||||
### Sponsors ###
|
||||
- [JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools
|
||||
- [ReSharper](http://www.jetbrains.com/resharper/)
|
||||
- [WebStorm](http://www.jetbrains.com/webstorm/)
|
||||
- [TeamCity](http://www.jetbrains.com/teamcity/)
|
||||
BIN
src/.DS_Store
vendored
BIN
src/.DS_Store
vendored
Binary file not shown.
@@ -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.*")]
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace NzbDrone.Api.Calendar
|
||||
|
||||
Get["/NzbDrone.ics"] = options => GetCalendarFeed();
|
||||
Get["/Sonarr.ics"] = options => GetCalendarFeed();
|
||||
Get["/Radarr.ics"] = options => GetCalendarFeed();
|
||||
}
|
||||
|
||||
private Response GetCalendarFeed()
|
||||
|
||||
@@ -2,24 +2,38 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Api.Episodes;
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.MovieStats;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
using NzbDrone.Core.Validation.Paths;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.SignalR;
|
||||
|
||||
namespace NzbDrone.Api.Calendar
|
||||
{
|
||||
public class CalendarModule : EpisodeModuleWithSignalR
|
||||
public class CalendarModule : MovieModule
|
||||
{
|
||||
public CalendarModule(IEpisodeService episodeService,
|
||||
ISeriesService seriesService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "calendar")
|
||||
public CalendarModule(IBroadcastSignalRMessage signalR,
|
||||
IMovieService moviesService,
|
||||
IMovieStatisticsService moviesStatisticsService,
|
||||
ISceneMappingService sceneMappingService,
|
||||
IMapCoversToLocal coverMapper)
|
||||
: base(signalR, moviesService, moviesStatisticsService, sceneMappingService, coverMapper, "calendar")
|
||||
{
|
||||
|
||||
GetResourceAll = GetCalendar;
|
||||
}
|
||||
|
||||
private List<EpisodeResource> GetCalendar()
|
||||
private List<MovieResource> GetCalendar()
|
||||
{
|
||||
var start = DateTime.Today;
|
||||
var end = DateTime.Today.AddDays(2);
|
||||
@@ -33,9 +47,9 @@ namespace NzbDrone.Api.Calendar
|
||||
if (queryEnd.HasValue) end = DateTime.Parse(queryEnd.Value);
|
||||
if (queryIncludeUnmonitored.HasValue) includeUnmonitored = Convert.ToBoolean(queryIncludeUnmonitored.Value);
|
||||
|
||||
var resources = MapToResource(_episodeService.EpisodesBetweenDates(start, end, includeUnmonitored), true, true);
|
||||
var resources = _moviesService.GetMoviesBetweenDates(start, end, includeUnmonitored).Select(MapToResource);
|
||||
|
||||
return resources.OrderBy(e => e.AirDateUtc).ToList();
|
||||
return resources.OrderBy(e => e.InCinemas).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,13 @@ namespace NzbDrone.Api.Config
|
||||
Get["/samples"] = x => GetExamples(this.Bind<NamingConfigResource>());
|
||||
|
||||
SharedValidator.RuleFor(c => c.MultiEpisodeStyle).InclusiveBetween(0, 5);
|
||||
SharedValidator.RuleFor(c => c.StandardEpisodeFormat).ValidEpisodeFormat();
|
||||
/*SharedValidator.RuleFor(c => c.StandardEpisodeFormat).ValidEpisodeFormat();
|
||||
SharedValidator.RuleFor(c => c.DailyEpisodeFormat).ValidDailyEpisodeFormat();
|
||||
SharedValidator.RuleFor(c => c.AnimeEpisodeFormat).ValidAnimeEpisodeFormat();
|
||||
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)
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace NzbDrone.Api.Frontend.Mappers
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
{
|
||||
return resourceUrl.StartsWith("/backup/") && resourceUrl.ContainsIgnoreCase("nzbdrone_backup_") && resourceUrl.EndsWith(".zip");
|
||||
return resourceUrl.StartsWith("/backup/") && resourceUrl.ContainsIgnoreCase("radarr_backup_") && resourceUrl.EndsWith(".zip");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ namespace NzbDrone.Api.Indexers
|
||||
{
|
||||
Guid = releaseInfo.Guid,
|
||||
Quality = parsedMovieInfo.Quality,
|
||||
//QualityWeight
|
||||
QualityWeight = parsedMovieInfo.Quality.Quality.Id, //Id kinda hacky for wheight, but what you gonna do? TODO: Fix this shit!
|
||||
Age = releaseInfo.Age,
|
||||
AgeHours = releaseInfo.AgeHours,
|
||||
AgeMinutes = releaseInfo.AgeMinutes,
|
||||
@@ -107,8 +107,8 @@ namespace NzbDrone.Api.Indexers
|
||||
ReleaseGroup = parsedMovieInfo.ReleaseGroup,
|
||||
ReleaseHash = parsedMovieInfo.ReleaseHash,
|
||||
Title = releaseInfo.Title,
|
||||
FullSeason = parsedMovieInfo.FullSeason,
|
||||
SeasonNumber = parsedMovieInfo.SeasonNumber,
|
||||
//FullSeason = parsedMovieInfo.FullSeason,
|
||||
//SeasonNumber = parsedMovieInfo.SeasonNumber,
|
||||
Language = parsedMovieInfo.Language,
|
||||
AirDate = "",
|
||||
SeriesTitle = parsedMovieInfo.MovieTitle,
|
||||
@@ -138,7 +138,7 @@ namespace NzbDrone.Api.Indexers
|
||||
IsDaily = false,
|
||||
IsAbsoluteNumbering = false,
|
||||
IsPossibleSpecialEpisode = false,
|
||||
Special = parsedMovieInfo.Special,
|
||||
//Special = parsedMovieInfo.Special,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
31
src/NzbDrone.Api/Movies/MovieEditorModule.cs
Normal file
31
src/NzbDrone.Api/Movies/MovieEditorModule.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.Movie
|
||||
{
|
||||
public class MovieEditorModule : NzbDroneApiModule
|
||||
{
|
||||
private readonly IMovieService _movieService;
|
||||
|
||||
public MovieEditorModule(IMovieService movieService)
|
||||
: base("/movie/editor")
|
||||
{
|
||||
_movieService = movieService;
|
||||
Put["/"] = Movie => SaveAll();
|
||||
}
|
||||
|
||||
private Response SaveAll()
|
||||
{
|
||||
var resources = Request.Body.FromJson<List<MovieResource>>();
|
||||
|
||||
var Movie = resources.Select(MovieResource => MovieResource.ToModel(_movieService.GetMovie(MovieResource.Id))).ToList();
|
||||
|
||||
return _movieService.UpdateMovie(Movie)
|
||||
.ToResource()
|
||||
.AsResponse(HttpStatusCode.Accepted);
|
||||
}
|
||||
}
|
||||
}
|
||||
89
src/NzbDrone.Api/Movies/MovieFileModule.cs
Normal file
89
src/NzbDrone.Api/Movies/MovieFileModule.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.SignalR;
|
||||
|
||||
namespace NzbDrone.Api.EpisodeFiles
|
||||
{
|
||||
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>
|
||||
//IHandle<EpisodeFileAddedEvent>
|
||||
{
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IRecycleBinProvider _recycleBinProvider;
|
||||
private readonly IMovieService _seriesService;
|
||||
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public MovieFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
IMediaFileService mediaFileService,
|
||||
IRecycleBinProvider recycleBinProvider,
|
||||
IMovieService seriesService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
Logger logger)
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_mediaFileService = mediaFileService;
|
||||
_recycleBinProvider = recycleBinProvider;
|
||||
_seriesService = seriesService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
_logger = logger;
|
||||
/*GetResourceById = GetEpisodeFile;
|
||||
GetResourceAll = GetEpisodeFiles;
|
||||
UpdateResource = SetQuality;*/
|
||||
DeleteResource = DeleteEpisodeFile;
|
||||
}
|
||||
|
||||
/*private EpisodeFileResource GetEpisodeFile(int id)
|
||||
{
|
||||
var episodeFile = _mediaFileService.Get(id);
|
||||
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||
|
||||
return episodeFile.ToResource(series, _qualityUpgradableSpecification);
|
||||
}
|
||||
|
||||
private List<EpisodeFileResource> GetEpisodeFiles()
|
||||
{
|
||||
if (!Request.Query.SeriesId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("seriesId is missing");
|
||||
}
|
||||
|
||||
var seriesId = (int)Request.Query.SeriesId;
|
||||
|
||||
var series = _seriesService.GetSeries(seriesId);
|
||||
|
||||
return _mediaFileService.GetFilesBySeries(seriesId).ConvertAll(f => f.ToResource(series, _qualityUpgradableSpecification));
|
||||
}
|
||||
|
||||
private void SetQuality(EpisodeFileResource episodeFileResource)
|
||||
{
|
||||
var episodeFile = _mediaFileService.Get(episodeFileResource.Id);
|
||||
episodeFile.Quality = episodeFileResource.Quality;
|
||||
_mediaFileService.Update(episodeFile);
|
||||
}*/
|
||||
|
||||
private void DeleteEpisodeFile(int id)
|
||||
{
|
||||
var episodeFile = _mediaFileService.GetMovie(id);
|
||||
var series = _seriesService.GetMovie(episodeFile.MovieId);
|
||||
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||
|
||||
_logger.Info("Deleting episode file: {0}", fullPath);
|
||||
_recycleBinProvider.DeleteFile(fullPath);
|
||||
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
||||
}
|
||||
|
||||
public void Handle(EpisodeFileAddedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/NzbDrone.Api/Movies/MovieModule.cs
Normal file
11
src/NzbDrone.Api/Movies/MovieModule.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Api.Movies
|
||||
{
|
||||
class MovieModule
|
||||
{
|
||||
}
|
||||
}
|
||||
35
src/NzbDrone.Api/Movies/RenameMovieModule.cs
Normal file
35
src/NzbDrone.Api/Movies/RenameMovieModule.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Api.Movies
|
||||
{
|
||||
public class RenameMovieModule : NzbDroneRestModule<RenameMovieResource>
|
||||
{
|
||||
private readonly IRenameMovieFileService _renameMovieFileService;
|
||||
|
||||
public RenameMovieModule(IRenameMovieFileService renameMovieFileService)
|
||||
: base("renameMovie")
|
||||
{
|
||||
_renameMovieFileService = renameMovieFileService;
|
||||
|
||||
GetResourceAll = GetMovies; //TODO: GetResourceSingle?
|
||||
}
|
||||
|
||||
private List<RenameMovieResource> GetMovies()
|
||||
{
|
||||
if(!Request.Query.MovieId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("movieId is missing");
|
||||
}
|
||||
|
||||
var movieId = (int)Request.Query.MovieId;
|
||||
|
||||
return _renameMovieFileService.GetRenamePreviews(movieId).ToResource();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
35
src/NzbDrone.Api/Movies/RenameMovieResource.cs
Normal file
35
src/NzbDrone.Api/Movies/RenameMovieResource.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using NzbDrone.Api.REST;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Api.Movies
|
||||
{
|
||||
public class RenameMovieResource : RestResource
|
||||
{
|
||||
public int MovieId { get; set; }
|
||||
public int MovieFileId { get; set; }
|
||||
public string ExistingPath { get; set; }
|
||||
public string NewPath { get; set; }
|
||||
}
|
||||
|
||||
public static class RenameMovieResourceMapper
|
||||
{
|
||||
public static RenameMovieResource ToResource(this Core.MediaFiles.RenameMovieFilePreview model)
|
||||
{
|
||||
if (model == null) return null;
|
||||
|
||||
return new RenameMovieResource
|
||||
{
|
||||
MovieId = model.MovieId,
|
||||
MovieFileId = model.MovieFileId,
|
||||
ExistingPath = model.ExistingPath,
|
||||
NewPath = model.NewPath
|
||||
};
|
||||
}
|
||||
|
||||
public static List<RenameMovieResource> ToResource(this IEnumerable<Core.MediaFiles.RenameMovieFilePreview> models)
|
||||
{
|
||||
return models.Select(ToResource).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,6 +116,11 @@
|
||||
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
||||
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
||||
<Compile Include="Indexers\ReleasePushModule.cs" />
|
||||
<Compile Include="Movies\MovieFileModule.cs" />
|
||||
<Compile Include="Movies\MovieModule.cs" />
|
||||
<Compile Include="Movies\RenameMovieModule.cs" />
|
||||
<Compile Include="Movies\RenameMovieResource.cs" />
|
||||
<Compile Include="Movies\MovieEditorModule.cs" />
|
||||
<Compile Include="Parse\ParseModule.cs" />
|
||||
<Compile Include="Parse\ParseResource.cs" />
|
||||
<Compile Include="ManualImport\ManualImportModule.cs" />
|
||||
@@ -228,6 +233,7 @@
|
||||
<Compile Include="RootFolders\RootFolderResource.cs" />
|
||||
<Compile Include="SeasonPass\SeasonPassResource.cs" />
|
||||
<Compile Include="Series\AlternateTitleResource.cs" />
|
||||
<Compile Include="Series\MovieFileResource.cs" />
|
||||
<Compile Include="Series\SeasonResource.cs" />
|
||||
<Compile Include="SeasonPass\SeasonPassModule.cs" />
|
||||
<Compile Include="Series\SeriesEditorModule.cs" />
|
||||
|
||||
@@ -6,6 +6,5 @@ using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: Guid("4c0922d7-979e-4ff7-b44b-b8ac2100eeb5")]
|
||||
|
||||
[assembly: AssemblyVersion("0.1.0.*")]
|
||||
|
||||
[assembly: InternalsVisibleTo("NzbDrone.Core")]
|
||||
|
||||
86
src/NzbDrone.Api/Series/MovieFileResource.cs
Normal file
86
src/NzbDrone.Api/Series/MovieFileResource.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Api.Series;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
|
||||
namespace NzbDrone.Api.Movie
|
||||
{
|
||||
public class MovieFileResource : RestResource
|
||||
{
|
||||
public MovieFileResource()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//Todo: Sorters should be done completely on the client
|
||||
//Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing?
|
||||
//Todo: We should get the entire Profile instead of ID and Name separately
|
||||
|
||||
public int MovieId { get; set; }
|
||||
public string RelativePath { get; set; }
|
||||
public string Path { get; set; }
|
||||
public long Size { get; set; }
|
||||
public DateTime DateAdded { get; set; }
|
||||
public string SceneName { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public MovieResource Movie { get; set; }
|
||||
public string Edition { get; set; }
|
||||
public Core.MediaFiles.MediaInfo.MediaInfoModel MediaInfo { get; set; }
|
||||
|
||||
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
||||
}
|
||||
|
||||
public static class MovieFileResourceMapper
|
||||
{
|
||||
public static MovieFileResource ToResource(this MovieFile model)
|
||||
{
|
||||
if (model == null) return null;
|
||||
|
||||
MovieResource movie = null;
|
||||
|
||||
if (model.Movie != null)
|
||||
{
|
||||
model.Movie.LazyLoad();
|
||||
if (model.Movie.Value != null)
|
||||
{
|
||||
//movie = model.Movie.Value.ToResource();
|
||||
}
|
||||
}
|
||||
|
||||
return new MovieFileResource
|
||||
{
|
||||
Id = model.Id,
|
||||
RelativePath = model.RelativePath,
|
||||
Path = model.Path,
|
||||
Size = model.Size,
|
||||
DateAdded = model.DateAdded,
|
||||
ReleaseGroup = model.ReleaseGroup,
|
||||
Quality = model.Quality,
|
||||
Movie = movie,
|
||||
MediaInfo = model.MediaInfo,
|
||||
Edition = model.Edition
|
||||
};
|
||||
}
|
||||
|
||||
public static MovieFile ToModel(this MovieFileResource resource)
|
||||
{
|
||||
if (resource == null) return null;
|
||||
|
||||
return new MovieFile
|
||||
{
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static List<MovieFileResource> ToResource(this IEnumerable<MovieFile> movies)
|
||||
{
|
||||
return movies.Select(ToResource).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ namespace NzbDrone.Api.Movie
|
||||
IHandle<MediaCoversUpdatedEvent>
|
||||
|
||||
{
|
||||
private readonly IMovieService _moviesService;
|
||||
protected readonly IMovieService _moviesService;
|
||||
private readonly IMovieStatisticsService _moviesStatisticsService;
|
||||
private readonly IMapCoversToLocal _coverMapper;
|
||||
|
||||
@@ -78,13 +78,33 @@ namespace NzbDrone.Api.Movie
|
||||
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
||||
}
|
||||
|
||||
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
IMovieService moviesService,
|
||||
IMovieStatisticsService moviesStatisticsService,
|
||||
ISceneMappingService sceneMappingService,
|
||||
IMapCoversToLocal coverMapper,
|
||||
string resource)
|
||||
: base(signalRBroadcaster, resource)
|
||||
{
|
||||
_moviesService = moviesService;
|
||||
_moviesStatisticsService = moviesStatisticsService;
|
||||
|
||||
_coverMapper = coverMapper;
|
||||
|
||||
GetResourceAll = AllMovie;
|
||||
GetResourceById = GetMovie;
|
||||
CreateResource = AddMovie;
|
||||
UpdateResource = UpdateMovie;
|
||||
DeleteResource = DeleteMovie;
|
||||
}
|
||||
|
||||
private MovieResource GetMovie(int id)
|
||||
{
|
||||
var movies = _moviesService.GetMovie(id);
|
||||
return MapToResource(movies);
|
||||
}
|
||||
|
||||
private MovieResource MapToResource(Core.Tv.Movie movies)
|
||||
protected MovieResource MapToResource(Core.Tv.Movie movies)
|
||||
{
|
||||
if (movies == null) return null;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace NzbDrone.Api.Movie
|
||||
//Todo: Sorters should be done completely on the client
|
||||
//Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing?
|
||||
//Todo: We should get the entire Profile instead of ID and Name separately
|
||||
|
||||
|
||||
//View Only
|
||||
public string Title { get; set; }
|
||||
public List<AlternateTitleResource> AlternateTitles { get; set; }
|
||||
@@ -27,11 +27,15 @@ namespace NzbDrone.Api.Movie
|
||||
public MovieStatusType Status { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public DateTime? InCinemas { get; set; }
|
||||
public DateTime? PhysicalRelease { get; set; }
|
||||
public List<MediaCover> Images { get; set; }
|
||||
public string Website { get; set; }
|
||||
|
||||
public bool Downloaded { get; set; }
|
||||
public string RemotePoster { get; set; }
|
||||
public int Year { get; set; }
|
||||
public bool HasFile { get; set; }
|
||||
public string YouTubeTrailerId { get; set; }
|
||||
public string Studio { get; set; }
|
||||
|
||||
//View & Edit
|
||||
public string Path { get; set; }
|
||||
@@ -53,6 +57,7 @@ namespace NzbDrone.Api.Movie
|
||||
public AddMovieOptions AddOptions { get; set; }
|
||||
public Ratings Ratings { get; set; }
|
||||
public List<string> AlternativeTitles { get; set; }
|
||||
public MovieFileResource MovieFile { get; set; }
|
||||
|
||||
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
||||
|
||||
@@ -79,6 +84,24 @@ namespace NzbDrone.Api.Movie
|
||||
{
|
||||
if (model == null) return null;
|
||||
|
||||
|
||||
long size = 0;
|
||||
bool downloaded = false;
|
||||
MovieFileResource movieFile = null;
|
||||
|
||||
|
||||
if(model.MovieFile != null)
|
||||
{
|
||||
model.MovieFile.LazyLoad();
|
||||
}
|
||||
|
||||
if (model.MovieFile != null && model.MovieFile.IsLoaded && model.MovieFile.Value != null)
|
||||
{
|
||||
size = model.MovieFile.Value.Size;
|
||||
downloaded = true;
|
||||
movieFile = model.MovieFile.Value.ToResource();
|
||||
}
|
||||
|
||||
return new MovieResource
|
||||
{
|
||||
Id = model.Id,
|
||||
@@ -87,6 +110,9 @@ namespace NzbDrone.Api.Movie
|
||||
//AlternateTitles
|
||||
SortTitle = model.SortTitle,
|
||||
InCinemas = model.InCinemas,
|
||||
PhysicalRelease = model.PhysicalRelease,
|
||||
HasFile = model.HasFile,
|
||||
Downloaded = downloaded,
|
||||
//TotalEpisodeCount
|
||||
//EpisodeCount
|
||||
//EpisodeFileCount
|
||||
@@ -104,6 +130,8 @@ namespace NzbDrone.Api.Movie
|
||||
|
||||
Monitored = model.Monitored,
|
||||
|
||||
SizeOnDisk = size,
|
||||
|
||||
Runtime = model.Runtime,
|
||||
LastInfoSync = model.LastInfoSync,
|
||||
CleanTitle = model.CleanTitle,
|
||||
@@ -117,7 +145,10 @@ namespace NzbDrone.Api.Movie
|
||||
Added = model.Added,
|
||||
AddOptions = model.AddOptions,
|
||||
AlternativeTitles = model.AlternativeTitles,
|
||||
Ratings = model.Ratings
|
||||
Ratings = model.Ratings,
|
||||
MovieFile = movieFile,
|
||||
YouTubeTrailerId = model.YouTubeTrailerId,
|
||||
Studio = model.Studio
|
||||
};
|
||||
}
|
||||
|
||||
@@ -134,6 +165,7 @@ namespace NzbDrone.Api.Movie
|
||||
//AlternateTitles
|
||||
SortTitle = resource.SortTitle,
|
||||
InCinemas = resource.InCinemas,
|
||||
PhysicalRelease = resource.PhysicalRelease,
|
||||
//TotalEpisodeCount
|
||||
//EpisodeCount
|
||||
//EpisodeFileCount
|
||||
@@ -163,7 +195,9 @@ namespace NzbDrone.Api.Movie
|
||||
Added = resource.Added,
|
||||
AddOptions = resource.AddOptions,
|
||||
AlternativeTitles = resource.AlternativeTitles,
|
||||
Ratings = resource.Ratings
|
||||
Ratings = resource.Ratings,
|
||||
YouTubeTrailerId = resource.YouTubeTrailerId,
|
||||
Studio = resource.Studio
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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.*")]
|
||||
|
||||
@@ -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.*")]
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace NzbDrone.Common.Cloud
|
||||
{
|
||||
public SonarrCloudRequestBuilder()
|
||||
{
|
||||
Services = new HttpRequestBuilder("http://services.sonarr.tv/v1/")
|
||||
Services = new HttpRequestBuilder("http://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; }
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace NzbDrone.Common
|
||||
Console.WriteLine(" Commands:");
|
||||
Console.WriteLine(" /{0} Install the application as a Windows Service ({1}).", StartupContext.INSTALL_SERVICE, ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||
Console.WriteLine(" /{0} Uninstall already installed Windows Service ({1}).", StartupContext.UNINSTALL_SERVICE, ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||
Console.WriteLine(" /{0} Don't open Sonarr in a browser", StartupContext.NO_BROWSER);
|
||||
Console.WriteLine(" /{0} Don't open Radarr in a browser", StartupContext.NO_BROWSER);
|
||||
Console.WriteLine(" <No Arguments> Run application in console mode.");
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@ namespace NzbDrone.Common.Extensions
|
||||
private const string UPDATE_CLIENT_EXE = "Radarr.Update.exe";
|
||||
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_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_SANDBOX_FOLDER_NAME = "radarr_update" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "Radarr" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_BACKUP_FOLDER_NAME = "radarr_backup" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_BACKUP_APPDATA_FOLDER_NAME = "radarr_appdata_backup" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_CLIENT_FOLDER_NAME = "NzbDrone.Update" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_LOG_FOLDER_NAME = "UpdateLogs" + Path.DirectorySeparatorChar;
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
static UserAgentBuilder()
|
||||
{
|
||||
UserAgent = string.Format("Sonarr/{0} ({1} {2})",
|
||||
UserAgent = string.Format("Radarr/{0} ({1} {2})",
|
||||
BuildInfo.Version,
|
||||
OsInfo.Os, OsInfo.Version.ToString(2));
|
||||
|
||||
UserAgentSimplified = string.Format("Sonarr/{0}",
|
||||
UserAgentSimplified = string.Format("Radarr/{0}",
|
||||
BuildInfo.Version.ToString(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,9 +103,9 @@ namespace NzbDrone.Common.Instrumentation
|
||||
|
||||
private static void RegisterAppFile(IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
RegisterAppFile(appFolderInfo, "appFileInfo", "sonarr.txt", 5, LogLevel.Info);
|
||||
RegisterAppFile(appFolderInfo, "appFileDebug", "sonarr.debug.txt", 50, LogLevel.Off);
|
||||
RegisterAppFile(appFolderInfo, "appFileTrace", "sonarr.trace.txt", 50, LogLevel.Off);
|
||||
RegisterAppFile(appFolderInfo, "appFileInfo", "radarr.txt", 5, LogLevel.Info);
|
||||
RegisterAppFile(appFolderInfo, "appFileDebug", "radarr.debug.txt", 50, LogLevel.Off);
|
||||
RegisterAppFile(appFolderInfo, "appFileTrace", "radarr.trace.txt", 50, LogLevel.Off);
|
||||
}
|
||||
|
||||
private static LoggingRule RegisterAppFile(IAppFolderInfo appFolderInfo, string name, string fileName, int maxArchiveFiles, LogLevel minLogLevel)
|
||||
|
||||
@@ -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.*")]
|
||||
|
||||
@@ -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("")]
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace NzbDrone.Common
|
||||
|
||||
public class ServiceProvider : IServiceProvider
|
||||
{
|
||||
public const string NZBDRONE_SERVICE_NAME = "NzbDrone";
|
||||
public const string NZBDRONE_SERVICE_NAME = "Radarr";
|
||||
|
||||
private readonly IProcessProvider _processProvider;
|
||||
private readonly Logger _logger;
|
||||
@@ -78,7 +78,7 @@ namespace NzbDrone.Common
|
||||
serviceInstaller.Context = context;
|
||||
serviceInstaller.DisplayName = serviceName;
|
||||
serviceInstaller.ServiceName = serviceName;
|
||||
serviceInstaller.Description = "NzbDrone Application Server";
|
||||
serviceInstaller.Description = "Radarr Application Server";
|
||||
serviceInstaller.StartType = ServiceStartMode.Automatic;
|
||||
serviceInstaller.ServicesDependedOn = new[] { "EventLog", "Tcpip", "http" };
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -7,5 +7,3 @@ using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("NzbDrone.Host")]
|
||||
[assembly: Guid("67AADCD9-89AA-4D95-8281-3193740E70E5")]
|
||||
|
||||
[assembly: AssemblyVersion("0.1.0.*")]
|
||||
BIN
src/NzbDrone.Console/Radarr.ico
Normal file
BIN
src/NzbDrone.Console/Radarr.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
@@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
Subject.Definition = new DownloadClientDefinition();
|
||||
Subject.Definition.Settings = new DelugeSettings()
|
||||
{
|
||||
TvCategory = null
|
||||
MovieCategory = null
|
||||
};
|
||||
|
||||
_queued = new DelugeTorrent
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
Port = 2222,
|
||||
Username = "admin",
|
||||
Password = "pass",
|
||||
TvCategory = "tv"
|
||||
MovieCategory = "movies-radarr"
|
||||
};
|
||||
|
||||
Mocker.GetMock<ITorrentFileInfoReader>()
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests
|
||||
Subject.Definition = new DownloadClientDefinition();
|
||||
Subject.Definition.Settings = new RTorrentSettings()
|
||||
{
|
||||
TvCategory = null
|
||||
MovieCategory = null
|
||||
};
|
||||
|
||||
_downloading = new RTorrentTorrent
|
||||
|
||||
@@ -112,12 +112,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
|
||||
protected void GivenTvCategory()
|
||||
{
|
||||
_settings.TvCategory = "sonarr";
|
||||
_settings.MovieCategory = "radarr";
|
||||
}
|
||||
|
||||
protected void GivenTvDirectory()
|
||||
{
|
||||
_settings.TvDirectory = @"C:/Downloads/Finished/sonarr";
|
||||
_settings.MovieDirectory = @"C:/Downloads/Finished/radarr";
|
||||
}
|
||||
|
||||
protected void GivenFailedDownload()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,57 +0,0 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.BitMeTv;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests.BitMeTvTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class BitMeTvFixture : CoreTest<BitMeTv>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Subject.Definition = new IndexerDefinition()
|
||||
{
|
||||
Name = "BitMeTV",
|
||||
Settings = new BitMeTvSettings() { Cookie = "uid=123" }
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_BitMeTv()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/BitMeTv/BitMeTv.xml");
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
var torrentInfo = releases.First() as TorrentInfo;
|
||||
|
||||
torrentInfo.Title.Should().Be("Total.Divas.S02E08.HDTV.x264-CRiMSON");
|
||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
torrentInfo.DownloadUrl.Should().Be("http://www.bitmetv.org/download.php/12/Total.Divas.S02E08.HDTV.x264-CRiMSON.torrent");
|
||||
torrentInfo.InfoUrl.Should().BeNullOrEmpty();
|
||||
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
|
||||
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2014/05/13 17:04:29"));
|
||||
torrentInfo.Size.Should().Be(395009065);
|
||||
torrentInfo.InfoHash.Should().Be(null);
|
||||
torrentInfo.MagnetUrl.Should().Be(null);
|
||||
torrentInfo.Peers.Should().Be(null);
|
||||
torrentInfo.Seeders.Should().Be(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.BroadcastheNet;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests.BroadcastheNetTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class BroadcastheNetFixture : CoreTest<BroadcastheNet>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Subject.Definition = new IndexerDefinition()
|
||||
{
|
||||
Name = "BroadcastheNet",
|
||||
Settings = new BroadcastheNetSettings() { ApiKey = "abc", BaseUrl = "https://api.btnapps.net/" }
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_BroadcastheNet()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/BroadcastheNet/RecentFeed.json");
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.POST)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(2);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
var torrentInfo = releases.First() as TorrentInfo;
|
||||
|
||||
torrentInfo.Guid.Should().Be("BTN-123");
|
||||
torrentInfo.Title.Should().Be("Jimmy.Kimmel.2014.09.15.Jane.Fonda.HDTV.x264-aAF");
|
||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
torrentInfo.DownloadUrl.Should().Be("https://broadcasthe.net/torrents.php?action=download&id=123&authkey=123&torrent_pass=123");
|
||||
torrentInfo.InfoUrl.Should().Be("https://broadcasthe.net/torrents.php?id=237457&torrentid=123");
|
||||
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
|
||||
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2014/09/16 21:15:33"));
|
||||
torrentInfo.Size.Should().Be(505099926);
|
||||
torrentInfo.InfoHash.Should().Be("123");
|
||||
torrentInfo.TvdbId.Should().Be(71998);
|
||||
torrentInfo.TvRageId.Should().Be(4055);
|
||||
torrentInfo.MagnetUrl.Should().BeNullOrEmpty();
|
||||
torrentInfo.Peers.Should().Be(40+9);
|
||||
torrentInfo.Seeders.Should().Be(40);
|
||||
|
||||
torrentInfo.Origin.Should().Be("Scene");
|
||||
torrentInfo.Source.Should().Be("HDTV");
|
||||
torrentInfo.Container.Should().Be("MP4");
|
||||
torrentInfo.Codec.Should().Be("x264");
|
||||
torrentInfo.Resolution.Should().Be("SD");
|
||||
}
|
||||
|
||||
private void VerifyBackOff()
|
||||
{
|
||||
Mocker.GetMock<IIndexerStatusService>()
|
||||
.Verify(v => v.RecordFailure(It.IsAny<int>(), It.IsAny<TimeSpan>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_back_off_on_bad_request()
|
||||
{
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(v => v.Execute(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[0], System.Net.HttpStatusCode.BadRequest));
|
||||
|
||||
var results = Subject.FetchRecent();
|
||||
|
||||
results.Should().BeEmpty();
|
||||
|
||||
VerifyBackOff();
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_back_off_and_report_api_key_invalid()
|
||||
{
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(v => v.Execute(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[0], System.Net.HttpStatusCode.Unauthorized));
|
||||
|
||||
var results = Subject.FetchRecent();
|
||||
|
||||
results.Should().BeEmpty();
|
||||
|
||||
VerifyBackOff();
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_back_off_on_unknown_method()
|
||||
{
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(v => v.Execute(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[0], System.Net.HttpStatusCode.NotFound));
|
||||
|
||||
var results = Subject.FetchRecent();
|
||||
|
||||
results.Should().BeEmpty();
|
||||
|
||||
VerifyBackOff();
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_back_off_api_limit_reached()
|
||||
{
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(v => v.Execute(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[0], System.Net.HttpStatusCode.ServiceUnavailable));
|
||||
|
||||
var results = Subject.FetchRecent();
|
||||
|
||||
results.Should().BeEmpty();
|
||||
|
||||
VerifyBackOff();
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_replace_https_http_as_needed()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/BroadcastheNet/RecentFeed.json");
|
||||
|
||||
(Subject.Definition.Settings as BroadcastheNetSettings).BaseUrl = "http://api.btnapps.net/";
|
||||
|
||||
recentFeed = recentFeed.Replace("http:", "https:");
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.POST)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(2);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
var torrentInfo = releases.First() as TorrentInfo;
|
||||
|
||||
torrentInfo.DownloadUrl.Should().Be("http://broadcasthe.net/torrents.php?action=download&id=123&authkey=123&torrent_pass=123");
|
||||
torrentInfo.InfoUrl.Should().Be("http://broadcasthe.net/torrents.php?id=237457&torrentid=123");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.Fanzub;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests.FanzubTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class FanzubFixture : CoreTest<Fanzub>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Subject.Definition = new IndexerDefinition()
|
||||
{
|
||||
Name = "Fanzub",
|
||||
Settings = new FanzubSettings()
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_fanzub()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Fanzub/fanzub.xml");
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(3);
|
||||
|
||||
var releaseInfo = releases.First();
|
||||
|
||||
releaseInfo.Title.Should().Be("[Vivid] Hanayamata - 10 [A33D6606]");
|
||||
releaseInfo.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
|
||||
releaseInfo.DownloadUrl.Should().Be("http://fanzub.com/nzb/296464/Vivid%20Hanayamata%20-%2010.nzb");
|
||||
releaseInfo.InfoUrl.Should().BeNullOrEmpty();
|
||||
releaseInfo.CommentUrl.Should().BeNullOrEmpty();
|
||||
releaseInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
releaseInfo.PublishDate.Should().Be(DateTime.Parse("2014/09/13 12:56:53"));
|
||||
releaseInfo.Size.Should().Be(556246858);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,14 +42,14 @@ namespace NzbDrone.Core.Test.IndexerTests.OmgwtfnzbsTests
|
||||
|
||||
var releaseInfo = releases.First();
|
||||
|
||||
releaseInfo.Title.Should().Be("Stephen.Fry.Gadget.Man.S01E05.HDTV.x264-C4TV");
|
||||
releaseInfo.Title.Should().Be("Un.Petit.Boulot.2016.FRENCH.720p.BluRay.DTS.x264-LOST");
|
||||
releaseInfo.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
|
||||
releaseInfo.DownloadUrl.Should().Be("http://api.omgwtfnzbs.org/sn.php?id=OAl4g&user=nzbdrone&api=nzbdrone");
|
||||
releaseInfo.InfoUrl.Should().Be("http://omgwtfnzbs.org/details.php?id=OAl4g");
|
||||
releaseInfo.DownloadUrl.Should().Be("https://api.omgwtfnzbs.me/nzb/?id=8a2Bw&user=nzbdrone&api=nzbdrone");
|
||||
releaseInfo.InfoUrl.Should().Be("https://omgwtfnzbs.me/details.php?id=8a2Bw");
|
||||
releaseInfo.CommentUrl.Should().BeNullOrEmpty();
|
||||
releaseInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
releaseInfo.PublishDate.Should().Be(DateTime.Parse("2012/12/17 23:30:13"));
|
||||
releaseInfo.Size.Should().Be(236822906);
|
||||
releaseInfo.PublishDate.Should().Be(DateTime.Parse("2017/01/09 00:16:54"));
|
||||
releaseInfo.Size.Should().Be(5354909355);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.Torrentleech;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests.TorrentleechTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TorrentleechFixture : CoreTest<Torrentleech>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Subject.Definition = new IndexerDefinition()
|
||||
{
|
||||
Name = "Torrentleech",
|
||||
Settings = new TorrentleechSettings()
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_Torrentleech()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Torrentleech/Torrentleech.xml");
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
var torrentInfo = releases.First() as TorrentInfo;
|
||||
|
||||
torrentInfo.Title.Should().Be("Classic Car Rescue S02E04 720p HDTV x264-C4TV");
|
||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
torrentInfo.DownloadUrl.Should().Be("http://www.torrentleech.org/rss/download/513575/1234/Classic.Car.Rescue.S02E04.720p.HDTV.x264-C4TV.torrent");
|
||||
torrentInfo.InfoUrl.Should().Be("http://www.torrentleech.org/torrent/513575");
|
||||
torrentInfo.CommentUrl.Should().Be("http://www.torrentleech.org/torrent/513575#comments");
|
||||
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2014/05/12 19:15:28"));
|
||||
torrentInfo.Size.Should().Be(0);
|
||||
torrentInfo.InfoHash.Should().Be(null);
|
||||
torrentInfo.MagnetUrl.Should().Be(null);
|
||||
torrentInfo.Peers.Should().Be(7+1);
|
||||
torrentInfo.Seeders.Should().Be(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,8 +237,6 @@
|
||||
<Compile Include="IndexerSearchTests\NzbSearchServiceFixture.cs" />
|
||||
<Compile Include="IndexerSearchTests\SearchDefinitionFixture.cs" />
|
||||
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
|
||||
<Compile Include="IndexerTests\BitMeTvTests\BitMeTvFixture.cs" />
|
||||
<Compile Include="IndexerTests\BroadcastheNetTests\BroadcastheNetFixture.cs" />
|
||||
<Compile Include="IndexerTests\HDBitsTests\HDBitsFixture.cs" />
|
||||
<Compile Include="IndexerTests\IndexerServiceFixture.cs" />
|
||||
<Compile Include="IndexerTests\IndexerStatusServiceFixture.cs" />
|
||||
@@ -251,7 +249,6 @@
|
||||
<Compile Include="IndexerTests\NewznabTests\NewznabFixture.cs" />
|
||||
<Compile Include="IndexerTests\NewznabTests\NewznabRequestGeneratorFixture.cs" />
|
||||
<Compile Include="IndexerTests\NewznabTests\NewznabSettingFixture.cs" />
|
||||
<Compile Include="IndexerTests\FanzubTests\FanzubFixture.cs" />
|
||||
<Compile Include="IndexerTests\OmgwtfnzbsTests\OmgwtfnzbsFixture.cs" />
|
||||
<Compile Include="IndexerTests\SeasonSearchFixture.cs" />
|
||||
<Compile Include="IndexerTests\TestIndexer.cs" />
|
||||
@@ -259,7 +256,6 @@
|
||||
<Compile Include="IndexerTests\IPTorrentsTests\IPTorrentsFixture.cs" />
|
||||
<Compile Include="IndexerTests\KickassTorrentsTests\KickassTorrentsFixture.cs" />
|
||||
<Compile Include="IndexerTests\NyaaTests\NyaaFixture.cs" />
|
||||
<Compile Include="IndexerTests\TorrentleechTests\TorrentleechFixture.cs" />
|
||||
<Compile Include="IndexerTests\TorrentRssIndexerTests\TorrentRssIndexerFixture.cs" />
|
||||
<Compile Include="IndexerTests\TorrentRssIndexerTests\TestTorrentRssIndexer.cs" />
|
||||
<Compile Include="IndexerTests\WomblesTests\WomblesFixture.cs" />
|
||||
|
||||
@@ -25,6 +25,4 @@ using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: Guid("699aed1b-015e-4f0d-9c81-d5557b05d260")]
|
||||
|
||||
[assembly: AssemblyVersion("0.1.0.*")]
|
||||
|
||||
[assembly: InternalsVisibleTo("NzbDrone.Core")]
|
||||
@@ -33,7 +33,7 @@ namespace NzbDrone.Core.Backup
|
||||
|
||||
private string _backupTempFolder;
|
||||
|
||||
private static readonly Regex BackupFileRegex = new Regex(@"nzbdrone_backup_[._0-9]+\.zip", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
private static readonly Regex BackupFileRegex = new Regex(@"radarr_backup_[._0-9]+\.zip", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public BackupService(IMainDatabase maindDb,
|
||||
IDiskTransferService diskTransferService,
|
||||
@@ -49,7 +49,7 @@ namespace NzbDrone.Core.Backup
|
||||
_archiveService = archiveService;
|
||||
_logger = logger;
|
||||
|
||||
_backupTempFolder = Path.Combine(_appFolderInfo.TempFolder, "nzbdrone_backup");
|
||||
_backupTempFolder = Path.Combine(_appFolderInfo.TempFolder, "radarr_backup");
|
||||
}
|
||||
|
||||
public void Backup(BackupType backupType)
|
||||
@@ -59,7 +59,7 @@ namespace NzbDrone.Core.Backup
|
||||
_diskProvider.EnsureFolder(_backupTempFolder);
|
||||
_diskProvider.EnsureFolder(GetBackupFolder(backupType));
|
||||
|
||||
var backupFilename = string.Format("nzbdrone_backup_{0:yyyy.MM.dd_HH.mm.ss}.zip", DateTime.Now);
|
||||
var backupFilename = string.Format("radarr_backup_{0:yyyy.MM.dd_HH.mm.ss}.zip", DateTime.Now);
|
||||
var backupPath = Path.Combine(GetBackupFolder(backupType), backupFilename);
|
||||
|
||||
Cleanup();
|
||||
|
||||
@@ -161,7 +161,8 @@ namespace NzbDrone.Core.Configuration
|
||||
|
||||
public bool AnalyticsEnabled => GetValueBoolean("AnalyticsEnabled", true, persist: false);
|
||||
|
||||
public string Branch => GetValue("Branch", "master").ToLowerInvariant();
|
||||
// TODO: Change back to "master" for the first stable release.
|
||||
public string Branch => GetValue("Branch", "develop").ToLowerInvariant();
|
||||
|
||||
public string LogLevel => GetValue("LogLevel", "Info");
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
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(110)]
|
||||
public class add_phyiscal_release : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Movies").AddColumn("PhysicalRelease").AsDateTime().Nullable();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
14
src/NzbDrone.Core/Datastore/Migration/111_remove_bitmetv.cs
Normal file
14
src/NzbDrone.Core/Datastore/Migration/111_remove_bitmetv.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(111)]
|
||||
public class remove_bitmetv : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Delete.FromTable("Indexers").Row(new { Implementation = "BitMeTv" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(112)]
|
||||
public class remove_torrentleech : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Delete.FromTable("Indexers").Row(new { Implementation = "Torrentleech" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(113)]
|
||||
public class remove_broadcasthenet : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Delete.FromTable("Indexers").Row(new { Implementation = "BroadcastheNet" });
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/NzbDrone.Core/Datastore/Migration/114_remove_fanzub.cs
Normal file
14
src/NzbDrone.Core/Datastore/Migration/114_remove_fanzub.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(114)]
|
||||
public class remove_fanzub : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Delete.FromTable("Indexers").Row(new { Implementation = "Fanzub" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Data;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(115)]
|
||||
public class update_movie_sorttitle : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
// Create.Column("SortTitle").OnTable("Series").AsString().Nullable();
|
||||
Execute.WithConnection(SetSortTitles);
|
||||
}
|
||||
|
||||
private void SetSortTitles(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, Title FROM Movies";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
{
|
||||
var id = seriesReader.GetInt32(0);
|
||||
var title = seriesReader.GetString(1);
|
||||
|
||||
var sortTitle = Parser.Parser.NormalizeTitle(title).ToLower();
|
||||
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE Movies SET SortTitle = ? WHERE Id = ?";
|
||||
updateCmd.AddParameter(sortTitle);
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
updateCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Data;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(116)]
|
||||
public class update_movie_sorttitle_again : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Execute.WithConnection(SetSortTitles);
|
||||
}
|
||||
|
||||
private void SetSortTitles(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, Title FROM Movies";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
{
|
||||
var id = seriesReader.GetInt32(0);
|
||||
var title = seriesReader.GetString(1);
|
||||
|
||||
var sortTitle = Parser.Parser.NormalizeTitle(title).ToLower();
|
||||
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE Movies SET SortTitle = ? WHERE Id = ?";
|
||||
updateCmd.AddParameter(sortTitle);
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
updateCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Data;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(117)]
|
||||
public class update_movie_file : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Create.Column("Edition").OnTable("MovieFiles").AsString().Nullable();
|
||||
//Execute.WithConnection(SetSortTitles);
|
||||
}
|
||||
|
||||
private void SetSortTitles(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, RelativePath FROM MovieFiles";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
{
|
||||
var id = seriesReader.GetInt32(0);
|
||||
var relativePath = seriesReader.GetString(1);
|
||||
|
||||
var result = Parser.Parser.ParseMovieTitle(relativePath);
|
||||
|
||||
var edition = "";
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
edition = Parser.Parser.ParseMovieTitle(relativePath).Edition;
|
||||
}
|
||||
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE MovieFiles SET Edition = ? WHERE Id = ?";
|
||||
updateCmd.AddParameter(edition);
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
updateCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Data;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(118)]
|
||||
public class update_movie_slug : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Execute.WithConnection(SetTitleSlug);
|
||||
}
|
||||
|
||||
private void SetTitleSlug(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, Title, Year FROM Movies";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
{
|
||||
var id = seriesReader.GetInt32(0);
|
||||
var title = seriesReader.GetString(1);
|
||||
var year = seriesReader.GetInt32(2);
|
||||
|
||||
var titleSlug = ToUrlSlug(title + "-" + year);
|
||||
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE Movies SET TitleSlug = ? WHERE Id = ?";
|
||||
updateCmd.AddParameter(titleSlug);
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
updateCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToUrlSlug(string value)
|
||||
{
|
||||
//First to lower case
|
||||
value = value.ToLowerInvariant();
|
||||
|
||||
//Remove all accents
|
||||
var bytes = Encoding.GetEncoding("Cyrillic").GetBytes(value);
|
||||
value = Encoding.ASCII.GetString(bytes);
|
||||
|
||||
//Replace spaces
|
||||
value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);
|
||||
|
||||
//Remove invalid chars
|
||||
value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled);
|
||||
|
||||
//Trim dashes from end
|
||||
value = value.Trim('-', '_');
|
||||
|
||||
//Replace double occurences of - or _
|
||||
value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
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(119)]
|
||||
public class add_youtube_trailer_id : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Movies").AddColumn("YouTubeTrailerId").AsString().Nullable();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
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(120)]
|
||||
public class add_studio : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Movies").AddColumn("Studio").AsString().Nullable();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.Data;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(121)]
|
||||
public class update_filedate_config : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Execute.WithConnection(SetTitleSlug);
|
||||
}
|
||||
|
||||
private void SetTitleSlug(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, Value FROM Config WHERE Key = 'filedate'";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
{
|
||||
var id = seriesReader.GetInt32(0);
|
||||
var value = seriesReader.GetString(1);
|
||||
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE Config SET Value = 'Release' WHERE Id = ?";
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
updateCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToUrlSlug(string value)
|
||||
{
|
||||
//First to lower case
|
||||
value = value.ToLowerInvariant();
|
||||
|
||||
//Remove all accents
|
||||
var bytes = Encoding.GetEncoding("Cyrillic").GetBytes(value);
|
||||
value = Encoding.ASCII.GetString(bytes);
|
||||
|
||||
//Replace spaces
|
||||
value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);
|
||||
|
||||
//Remove invalid chars
|
||||
value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled);
|
||||
|
||||
//Trim dashes from end
|
||||
value = value.Trim('-', '_');
|
||||
|
||||
//Replace double occurences of - or _
|
||||
value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,6 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
CompareQuality,
|
||||
CompareProtocol,
|
||||
CompareEpisodeCount,
|
||||
CompareEpisodeNumber,
|
||||
ComparePeersIfTorrent,
|
||||
CompareAgeIfUsenet,
|
||||
CompareSize
|
||||
@@ -56,6 +54,12 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
|
||||
private int CompareQuality(DownloadDecision x, DownloadDecision y)
|
||||
{
|
||||
if (x.IsForMovie && y.IsForMovie)
|
||||
{
|
||||
return CompareAll(CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode => remoteEpisode.Movie.Profile.Value.Items.FindIndex(v => v.Quality == remoteEpisode.ParsedMovieInfo.Quality.Quality)),
|
||||
CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode => remoteEpisode.ParsedMovieInfo.Quality.Revision.Real),
|
||||
CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode => remoteEpisode.ParsedMovieInfo.Quality.Revision.Version));
|
||||
}
|
||||
return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Series.Profile.Value.Items.FindIndex(v => v.Quality == remoteEpisode.ParsedEpisodeInfo.Quality.Quality)),
|
||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Real),
|
||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version));
|
||||
@@ -63,6 +67,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
|
||||
private int CompareProtocol(DownloadDecision x, DownloadDecision y)
|
||||
{
|
||||
|
||||
var result = CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
||||
{
|
||||
var delayProfile = _delayProfileService.BestForTags(remoteEpisode.Series.Tags);
|
||||
@@ -70,13 +75,22 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
return downloadProtocol == delayProfile.PreferredProtocol;
|
||||
});
|
||||
|
||||
if (x.IsForMovie)
|
||||
{
|
||||
result = CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
|
||||
{
|
||||
var delayProfile = _delayProfileService.BestForTags(remoteEpisode.Movie.Tags);
|
||||
var downloadProtocol = remoteEpisode.Release.DownloadProtocol;
|
||||
return downloadProtocol == delayProfile.PreferredProtocol;
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int CompareEpisodeCount(DownloadDecision x, DownloadDecision y)
|
||||
{
|
||||
return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.FullSeason),
|
||||
CompareByReverse(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Episodes.Count));
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int CompareEpisodeNumber(DownloadDecision x, DownloadDecision y)
|
||||
@@ -88,20 +102,20 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
// Different protocols should get caught when checking the preferred protocol,
|
||||
// since we're dealing with the same series in our comparisions
|
||||
if (x.RemoteEpisode.Release.DownloadProtocol != DownloadProtocol.Torrent ||
|
||||
y.RemoteEpisode.Release.DownloadProtocol != DownloadProtocol.Torrent)
|
||||
if (x.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Torrent ||
|
||||
y.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Torrent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CompareAll(
|
||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
||||
CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
|
||||
{
|
||||
var seeders = TorrentInfo.GetSeeders(remoteEpisode.Release);
|
||||
|
||||
return seeders.HasValue && seeders.Value > 0 ? Math.Round(Math.Log10(seeders.Value)) : 0;
|
||||
}),
|
||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
||||
CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
|
||||
{
|
||||
var peers = TorrentInfo.GetPeers(remoteEpisode.Release);
|
||||
|
||||
@@ -117,7 +131,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
||||
return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
|
||||
{
|
||||
var ageHours = remoteEpisode.Release.AgeHours;
|
||||
var age = remoteEpisode.Release.Age;
|
||||
@@ -145,7 +159,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
// TODO: Is smaller better? Smaller for usenet could mean no par2 files.
|
||||
|
||||
return CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Release.Size.Round(200.Megabytes()));
|
||||
return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode => remoteEpisode.Release.Size.Round(200.Megabytes()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
|
||||
public List<DownloadDecision> GetRssDecision(List<ReleaseInfo> reports)
|
||||
{
|
||||
return GetDecisions(reports).ToList();
|
||||
return GetMovieDecisions(reports).ToList();
|
||||
}
|
||||
|
||||
public List<DownloadDecision> GetSearchDecision(List<ReleaseInfo> reports, SearchCriteriaBase searchCriteriaBase)
|
||||
@@ -257,7 +257,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
_logger.Info("Spec " + spec.GetType().Name + " does not care about movies.");
|
||||
_logger.Trace("Spec " + spec.GetType().Name + " does not care about movies.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -265,7 +265,6 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
e.Data.Add("parsed", remoteEpisode.ParsedEpisodeInfo.ToJson());
|
||||
_logger.Error(e, "Couldn't evaluate decision on " + remoteEpisode.Release.Title + ", with spec: " + spec.GetType().Name);
|
||||
return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));//TODO UPDATE SPECS!
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -60,11 +60,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
|
||||
foreach (var remoteEpisode in matchingSeries)
|
||||
{
|
||||
_logger.Debug("Checking if existing release in queue meets cutoff. Queued quality is: {0}", remoteEpisode.ParsedEpisodeInfo.Quality);
|
||||
_logger.Debug("Checking if existing release in queue meets cutoff. Queued quality is: {0}", remoteEpisode.ParsedMovieInfo.Quality);
|
||||
|
||||
if (!_qualityUpgradableSpecification.CutoffNotMet(subject.Movie.Profile, remoteEpisode.ParsedMovieInfo.Quality, subject.ParsedMovieInfo.Quality))
|
||||
{
|
||||
return Decision.Reject("Quality for release in queue already meets cutoff: {0}", remoteEpisode.ParsedEpisodeInfo.Quality);
|
||||
return Decision.Reject("Quality for release in queue already meets cutoff: {0}", remoteEpisode.ParsedMovieInfo.Quality);
|
||||
}
|
||||
|
||||
_logger.Debug("Checking if release is higher quality than queued release. Queued quality is: {0}", remoteEpisode.ParsedMovieInfo.Quality);
|
||||
|
||||
@@ -26,10 +26,10 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||
|
||||
private static readonly TorrentBlackholeSettingsValidator Validator = new TorrentBlackholeSettingsValidator();
|
||||
|
||||
[FieldDefinition(0, Label = "Torrent Folder", Type = FieldType.Path, HelpText = "Folder in which Sonarr will store the .torrent file")]
|
||||
[FieldDefinition(0, Label = "Torrent Folder", Type = FieldType.Path, HelpText = "Folder in which Radarr will store the .torrent file")]
|
||||
public string TorrentFolder { get; set; }
|
||||
|
||||
[FieldDefinition(1, Label = "Watch Folder", Type = FieldType.Path, HelpText = "Folder from which Sonarr should import completed downloads")]
|
||||
[FieldDefinition(1, Label = "Watch Folder", Type = FieldType.Path, HelpText = "Folder from which Radarr should import completed downloads")]
|
||||
public string WatchFolder { get; set; }
|
||||
|
||||
[DefaultValue(false)]
|
||||
@@ -39,7 +39,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||
|
||||
[DefaultValue(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
[FieldDefinition(3, Label = "Read Only", Type = FieldType.Checkbox, HelpText = "Instead of moving files this will instruct Sonarr to Copy or Hardlink (depending on settings/system configuration)")]
|
||||
[FieldDefinition(3, Label = "Read Only", Type = FieldType.Checkbox, HelpText = "Instead of moving files this will instruct Radarr to Copy or Hardlink (depending on settings/system configuration)")]
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
|
||||
@@ -19,10 +19,10 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||
{
|
||||
private static readonly UsenetBlackholeSettingsValidator Validator = new UsenetBlackholeSettingsValidator();
|
||||
|
||||
[FieldDefinition(0, Label = "Nzb Folder", Type = FieldType.Path, HelpText = "Folder in which Sonarr will store the .nzb file")]
|
||||
[FieldDefinition(0, Label = "Nzb Folder", Type = FieldType.Path, HelpText = "Folder in which Radarr will store the .nzb file")]
|
||||
public string NzbFolder { get; set; }
|
||||
|
||||
[FieldDefinition(1, Label = "Watch Folder", Type = FieldType.Path, HelpText = "Folder from which Sonarr should import completed downloads")]
|
||||
[FieldDefinition(1, Label = "Watch Folder", Type = FieldType.Path, HelpText = "Folder from which Radarr should import completed downloads")]
|
||||
public string WatchFolder { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
|
||||
@@ -31,25 +31,17 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteMovie remoteEpisode, string hash, string magnetLink)
|
||||
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
|
||||
{
|
||||
var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings);
|
||||
|
||||
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
||||
if (!Settings.MovieCategory.IsNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetLabel(actualHash, Settings.TvCategory, Settings);
|
||||
_proxy.SetLabel(actualHash, Settings.MovieCategory, Settings);
|
||||
}
|
||||
|
||||
_proxy.SetTorrentConfiguration(actualHash, "remove_at_ratio", false, Settings);
|
||||
|
||||
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)DelugePriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)DelugePriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(actualHash, Settings);
|
||||
}*/
|
||||
|
||||
return actualHash.ToUpper();
|
||||
}
|
||||
|
||||
@@ -57,66 +49,24 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
{
|
||||
var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||
|
||||
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
||||
if (!Settings.MovieCategory.IsNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetLabel(actualHash, Settings.TvCategory, Settings);
|
||||
_proxy.SetLabel(actualHash, Settings.MovieCategory, Settings);
|
||||
}
|
||||
|
||||
_proxy.SetTorrentConfiguration(actualHash, "remove_at_ratio", false, Settings);
|
||||
|
||||
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)DelugePriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)DelugePriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(actualHash, Settings);
|
||||
}*/
|
||||
|
||||
return actualHash.ToUpper();
|
||||
}
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||
{
|
||||
var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings);
|
||||
|
||||
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetLabel(actualHash, Settings.TvCategory, Settings);
|
||||
}
|
||||
|
||||
_proxy.SetTorrentConfiguration(actualHash, "remove_at_ratio", false, Settings);
|
||||
|
||||
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)DelugePriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)DelugePriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(actualHash, Settings);
|
||||
}
|
||||
|
||||
return actualHash.ToUpper();
|
||||
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||
}
|
||||
|
||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||
{
|
||||
var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||
|
||||
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetLabel(actualHash, Settings.TvCategory, Settings);
|
||||
}
|
||||
|
||||
_proxy.SetTorrentConfiguration(actualHash, "remove_at_ratio", false, Settings);
|
||||
|
||||
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)DelugePriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)DelugePriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(actualHash, Settings);
|
||||
}
|
||||
|
||||
return actualHash.ToUpper();
|
||||
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||
}
|
||||
|
||||
public override string Name => "Deluge";
|
||||
@@ -127,9 +77,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
|
||||
try
|
||||
{
|
||||
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
||||
if (!Settings.MovieCategory.IsNullOrWhiteSpace())
|
||||
{
|
||||
torrents = _proxy.GetTorrentsByLabel(Settings.TvCategory, Settings);
|
||||
torrents = _proxy.GetTorrentsByLabel(Settings.MovieCategory, Settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -149,7 +99,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
var item = new DownloadClientItem();
|
||||
item.DownloadId = torrent.Hash.ToUpper();
|
||||
item.Title = torrent.Name;
|
||||
item.Category = Settings.TvCategory;
|
||||
item.Category = Settings.MovieCategory;
|
||||
|
||||
item.DownloadClient = Definition.Name;
|
||||
|
||||
@@ -280,7 +230,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
|
||||
private ValidationFailure TestCategory()
|
||||
{
|
||||
if (Settings.TvCategory.IsNullOrWhiteSpace())
|
||||
if (Settings.MovieCategory.IsNullOrWhiteSpace())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -297,16 +247,16 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
|
||||
var labels = _proxy.GetAvailableLabels(Settings);
|
||||
|
||||
if (!labels.Contains(Settings.TvCategory))
|
||||
if (!labels.Contains(Settings.MovieCategory))
|
||||
{
|
||||
_proxy.AddLabel(Settings.TvCategory, Settings);
|
||||
_proxy.AddLabel(Settings.MovieCategory, Settings);
|
||||
labels = _proxy.GetAvailableLabels(Settings);
|
||||
|
||||
if (!labels.Contains(Settings.TvCategory))
|
||||
if (!labels.Contains(Settings.MovieCategory))
|
||||
{
|
||||
return new NzbDroneValidationFailure("TvCategory", "Configuration of label failed")
|
||||
return new NzbDroneValidationFailure("MovieCategory", "Configuration of label failed")
|
||||
{
|
||||
DetailedDescription = "Sonarr as unable to add the label to Deluge."
|
||||
DetailedDescription = "Radarr as unable to add the label to Deluge."
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
RuleFor(c => c.Host).ValidHost();
|
||||
RuleFor(c => c.Port).GreaterThan(0);
|
||||
|
||||
RuleFor(c => c.TvCategory).Matches("^[-a-z]*$").WithMessage("Allowed characters a-z and -");
|
||||
RuleFor(c => c.MovieCategory).Matches("^[-a-z]*$").WithMessage("Allowed characters a-z and -");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
Host = "localhost";
|
||||
Port = 8112;
|
||||
Password = "deluge";
|
||||
TvCategory = "movie-radarr";
|
||||
MovieCategory = "movie-radarr";
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||
@@ -41,15 +41,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
public string Password { get; set; }
|
||||
|
||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
public string TvCategory { get; set; }
|
||||
public string MovieCategory { get; set; }
|
||||
|
||||
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(DelugePriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
public int RecentTvPriority { get; set; }
|
||||
|
||||
[FieldDefinition(6, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(DelugePriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
||||
public int OlderTvPriority { get; set; }
|
||||
|
||||
[FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||
[FieldDefinition(5, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||
public bool UseSsl { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||
[FieldDefinition(2, Label = "API Key", Type = FieldType.Textbox)]
|
||||
public string ApiKey { get; set; }
|
||||
|
||||
[FieldDefinition(3, Label = "Group", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
[FieldDefinition(3, Label = "Group", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
public string TvCategory { get; set; }
|
||||
|
||||
[FieldDefinition(4, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
return new NzbDroneValidationFailure(string.Empty, "NzbGet setting KeepHistory should be greater than 0")
|
||||
{
|
||||
InfoLink = string.Format("http://{0}:{1}/", Settings.Host, Settings.Port),
|
||||
DetailedDescription = "NzbGet setting KeepHistory is set to 0. Which prevents Sonarr from seeing completed downloads."
|
||||
DetailedDescription = "NzbGet setting KeepHistory is set to 0. Which prevents Radarr from seeing completed downloads."
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
||||
public string Password { get; set; }
|
||||
|
||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
public string TvCategory { get; set; }
|
||||
|
||||
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
|
||||
@@ -33,81 +33,35 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||
{
|
||||
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
||||
|
||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);
|
||||
}
|
||||
|
||||
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(hash.ToLower(), Settings);
|
||||
}
|
||||
|
||||
return hash;
|
||||
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||
}
|
||||
|
||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, Byte[] fileContent)
|
||||
{
|
||||
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||
|
||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);
|
||||
}
|
||||
|
||||
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(hash.ToLower(), Settings);
|
||||
}
|
||||
|
||||
return hash;
|
||||
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||
}
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteMovie remoteEpisode, string hash, string magnetLink)
|
||||
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
|
||||
{
|
||||
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
||||
|
||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||
if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);
|
||||
_proxy.SetTorrentLabel(hash.ToLower(), Settings.MovieCategory, Settings);
|
||||
}
|
||||
|
||||
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(hash.ToLower(), Settings);
|
||||
}*/ //TODO: Maybe reimplement for movies
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected override string AddFromTorrentFile(RemoteMovie remoteEpisode, string hash, string filename, Byte[] fileContent)
|
||||
protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, Byte[] fileContent)
|
||||
{
|
||||
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||
|
||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||
if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);
|
||||
_proxy.SetTorrentLabel(hash.ToLower(), Settings.MovieCategory, Settings);
|
||||
}
|
||||
|
||||
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(hash.ToLower(), Settings);
|
||||
}*/
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -236,7 +190,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
else if (version < 6)
|
||||
{
|
||||
// API version 6 introduced support for labels
|
||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||
if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return new NzbDroneValidationFailure("Category", "Category is not supported")
|
||||
{
|
||||
@@ -244,7 +198,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (Settings.TvCategory.IsNullOrWhiteSpace())
|
||||
else if (Settings.MovieCategory.IsNullOrWhiteSpace())
|
||||
{
|
||||
// warn if labels are supported, but category is not provided
|
||||
return new NzbDroneValidationFailure("TvCategory", "Category is recommended")
|
||||
|
||||
@@ -58,8 +58,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
public List<QBittorrentTorrent> GetTorrents(QBittorrentSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings).Resource("/query/torrents")
|
||||
.AddQueryParam("label", settings.TvCategory)
|
||||
.AddQueryParam("category", settings.TvCategory);
|
||||
.AddQueryParam("label", settings.MovieCategory)
|
||||
.AddQueryParam("category", settings.MovieCategory);
|
||||
|
||||
var response = ProcessRequest<List<QBittorrentTorrent>>(request, settings);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
{
|
||||
Host = "localhost";
|
||||
Port = 9091;
|
||||
TvCategory = "movie-radarr";
|
||||
MovieCategory = "movie-radarr";
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||
@@ -38,16 +38,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
public string Password { get; set; }
|
||||
|
||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
public string TvCategory { get; set; }
|
||||
public string MovieCategory { get; set; }
|
||||
|
||||
//Todo: update this shit.
|
||||
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(QBittorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
public int RecentTvPriority { get; set; }
|
||||
|
||||
[FieldDefinition(6, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(QBittorrentPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
||||
public int OlderTvPriority { get; set; }
|
||||
|
||||
[FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use a secure connection. See Options -> Web UI -> 'Use HTTPS instead of HTTP' in qBittorrent.")]
|
||||
[FieldDefinition(5, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use a secure connection. See Options -> Web UI -> 'Use HTTPS instead of HTTP' in qBittorrent.")]
|
||||
public bool UseSsl { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
|
||||
@@ -30,13 +30,13 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
}
|
||||
|
||||
// patch can be a number (releases) or 'x' (git)
|
||||
private static readonly Regex VersionRegex = new Regex(@"(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+|x)(?<candidate>.*)", RegexOptions.Compiled);
|
||||
private static readonly Regex VersionRegex = new Regex(@"(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+|x)", RegexOptions.Compiled);
|
||||
|
||||
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContents)
|
||||
{
|
||||
var category = Settings.TvCategory;
|
||||
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||
|
||||
|
||||
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings);
|
||||
|
||||
if (response != null && response.Ids.Any())
|
||||
@@ -284,110 +284,103 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
failures.AddIfNotNull(TestCategory());
|
||||
}
|
||||
|
||||
private bool HasVersion(int major, int minor, int patch = 0, string candidate = null)
|
||||
private bool HasVersion(int major, int minor, int patch = 0)
|
||||
{
|
||||
candidate = candidate ?? string.Empty;
|
||||
var rawVersion = _proxy.GetVersion(Settings);
|
||||
var version = ParseVersion(rawVersion);
|
||||
|
||||
var version = _proxy.GetVersion(Settings);
|
||||
if (version == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version.Major > major)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (version.Major < major)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version.Minor > minor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (version.Minor < minor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version.Build > patch)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (version.Build < patch)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Version ParseVersion(string version)
|
||||
{
|
||||
var parsed = VersionRegex.Match(version);
|
||||
|
||||
int actualMajor;
|
||||
int actualMinor;
|
||||
int actualPatch;
|
||||
string actualCandidate;
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
|
||||
if (!parsed.Success)
|
||||
if (parsed.Success)
|
||||
{
|
||||
major = Convert.ToInt32(parsed.Groups["major"].Value);
|
||||
minor = Convert.ToInt32(parsed.Groups["minor"].Value);
|
||||
patch = Convert.ToInt32(parsed.Groups["patch"].Value.Replace("x", "0"));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (!version.Equals("develop", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
actualMajor = 1;
|
||||
actualMinor = 1;
|
||||
actualPatch = 0;
|
||||
actualCandidate = null;
|
||||
major = 1;
|
||||
minor = 1;
|
||||
patch = 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
actualMajor = Convert.ToInt32(parsed.Groups["major"].Value);
|
||||
actualMinor = Convert.ToInt32(parsed.Groups["minor"].Value);
|
||||
actualPatch = Convert.ToInt32(parsed.Groups["patch"].Value.Replace("x", ""));
|
||||
actualCandidate = parsed.Groups["candidate"].Value.ToUpper();
|
||||
}
|
||||
|
||||
if (actualMajor > major)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (actualMajor < major)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (actualMinor > minor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (actualMinor < minor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (actualPatch > patch)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (actualPatch < patch)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (actualCandidate.IsNullOrWhiteSpace())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (candidate.IsNullOrWhiteSpace())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return actualCandidate.CompareTo(candidate) > 0;
|
||||
}
|
||||
return new Version(major, minor, patch);
|
||||
}
|
||||
|
||||
private ValidationFailure TestConnectionAndVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
var version = _proxy.GetVersion(Settings);
|
||||
var parsed = VersionRegex.Match(version);
|
||||
var rawVersion = _proxy.GetVersion(Settings);
|
||||
var version = ParseVersion(rawVersion);
|
||||
|
||||
if (!parsed.Success)
|
||||
if (version == null)
|
||||
{
|
||||
if (version.Equals("develop", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return new NzbDroneValidationFailure("Version", "Sabnzbd develop version, assuming version 1.1.0 or higher.")
|
||||
{
|
||||
IsWarning = true,
|
||||
DetailedDescription = "Sonarr may not be able to support new features added to SABnzbd when running develop versions."
|
||||
};
|
||||
}
|
||||
|
||||
return new ValidationFailure("Version", "Unknown Version: " + version);
|
||||
}
|
||||
|
||||
var major = Convert.ToInt32(parsed.Groups["major"].Value);
|
||||
var minor = Convert.ToInt32(parsed.Groups["minor"].Value);
|
||||
if (rawVersion.Equals("develop", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return new NzbDroneValidationFailure("Version", "Sabnzbd develop version, assuming version 1.1.0 or higher.")
|
||||
{
|
||||
IsWarning = true,
|
||||
DetailedDescription = "Radarr may not be able to support new features added to SABnzbd when running develop versions."
|
||||
};
|
||||
}
|
||||
|
||||
if (major >= 1)
|
||||
if (version.Major >= 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (minor >= 7)
|
||||
if (version.Minor >= 7)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -431,7 +424,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
return new NzbDroneValidationFailure("", "Disable 'Check before download' option in Sabnbzd")
|
||||
{
|
||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/switches/", Settings.Host, Settings.Port),
|
||||
DetailedDescription = "Using Check before download affects Sonarr ability to track new downloads. Also Sabnzbd recommends 'Abort jobs that cannot be completed' instead since it's more effective."
|
||||
DetailedDescription = "Using Check before download affects Radarr ability to track new downloads. Also Sabnzbd recommends 'Abort jobs that cannot be completed' instead since it's more effective."
|
||||
};
|
||||
}
|
||||
|
||||
@@ -450,7 +443,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
return new NzbDroneValidationFailure("TvCategory", "Enable Job folders")
|
||||
{
|
||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/categories/", Settings.Host, Settings.Port),
|
||||
DetailedDescription = "Sonarr prefers each download to have a separate folder. With * appended to the Folder/Path Sabnzbd will not create these job folders. Go to Sabnzbd to fix it."
|
||||
DetailedDescription = "Radarr prefers each download to have a separate folder. With * appended to the Folder/Path Sabnzbd will not create these job folders. Go to Sabnzbd to fix it."
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -475,7 +468,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
return new NzbDroneValidationFailure("TvCategory", "Disable TV Sorting")
|
||||
{
|
||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/sorting/", Settings.Host, Settings.Port),
|
||||
DetailedDescription = "You must disable Sabnzbd TV Sorting for the category Sonarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
||||
DetailedDescription = "You must disable Sabnzbd TV Sorting for the category Radarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -489,7 +482,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
return new NzbDroneValidationFailure("TvCategory", "Disable Movie Sorting")
|
||||
{
|
||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/sorting/", Settings.Host, Settings.Port),
|
||||
DetailedDescription = "You must disable Sabnzbd Movie Sorting for the category Sonarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
||||
DetailedDescription = "You must disable Sabnzbd Movie Sorting for the category Radarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -503,7 +496,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
return new NzbDroneValidationFailure("TvCategory", "Disable Date Sorting")
|
||||
{
|
||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/sorting/", Settings.Host, Settings.Port),
|
||||
DetailedDescription = "You must disable Sabnzbd Date Sorting for the category Sonarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
||||
DetailedDescription = "You must disable Sabnzbd Date Sorting for the category Radarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
[FieldDefinition(4, Label = "Password", Type = FieldType.Password)]
|
||||
public string Password { get; set; }
|
||||
|
||||
[FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
[FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
public string TvCategory { get; set; }
|
||||
|
||||
[FieldDefinition(6, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
|
||||
@@ -54,21 +54,21 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||
|
||||
var outputPath = new OsPath(torrent.DownloadDir);
|
||||
|
||||
if (Settings.TvDirectory.IsNotNullOrWhiteSpace())
|
||||
if (Settings.MovieDirectory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
if (!new OsPath(Settings.TvDirectory).Contains(outputPath)) continue;
|
||||
if (!new OsPath(Settings.MovieDirectory).Contains(outputPath)) continue;
|
||||
}
|
||||
else if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||
else if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
var directories = outputPath.FullPath.Split('\\', '/');
|
||||
if (!directories.Contains(Settings.TvCategory)) continue;
|
||||
if (!directories.Contains(Settings.MovieCategory)) continue;
|
||||
}
|
||||
|
||||
outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, outputPath);
|
||||
|
||||
var item = new DownloadClientItem();
|
||||
item.DownloadId = torrent.HashString.ToUpper();
|
||||
item.Category = Settings.TvCategory;
|
||||
item.Category = Settings.MovieCategory;
|
||||
item.Title = torrent.Name;
|
||||
|
||||
item.DownloadClient = Definition.Name;
|
||||
@@ -123,9 +123,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||
var config = _proxy.GetConfig(Settings);
|
||||
var destDir = config.GetValueOrDefault("download-dir") as string;
|
||||
|
||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||
if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
destDir = string.Format("{0}/.{1}", destDir, Settings.TvCategory);
|
||||
destDir = string.Format("{0}/.{1}", destDir, Settings.MovieCategory);
|
||||
}
|
||||
|
||||
return new DownloadClientStatus
|
||||
@@ -137,31 +137,23 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||
{
|
||||
_proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings);
|
||||
|
||||
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)TransmissionPriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)TransmissionPriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(hash, Settings);
|
||||
}
|
||||
|
||||
return hash;
|
||||
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||
}
|
||||
|
||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||
{
|
||||
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||
}
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
|
||||
{
|
||||
_proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings);
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent)
|
||||
{
|
||||
_proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings);
|
||||
|
||||
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)TransmissionPriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)TransmissionPriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(hash, Settings);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -179,16 +171,16 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||
|
||||
protected string GetDownloadDirectory()
|
||||
{
|
||||
if (Settings.TvDirectory.IsNotNullOrWhiteSpace())
|
||||
if (Settings.MovieDirectory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return Settings.TvDirectory;
|
||||
return Settings.MovieDirectory;
|
||||
}
|
||||
else if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||
else if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
var config = _proxy.GetConfig(Settings);
|
||||
var destDir = (string)config.GetValueOrDefault("download-dir");
|
||||
|
||||
return string.Format("{0}/{1}", destDir.TrimEnd('/'), Settings.TvCategory);
|
||||
return string.Format("{0}/{1}", destDir.TrimEnd('/'), Settings.MovieCategory);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -207,7 +199,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||
_logger.Error(ex, ex.Message);
|
||||
return new NzbDroneValidationFailure("Username", "Authentication failure")
|
||||
{
|
||||
DetailedDescription = string.Format("Please verify your username and password. Also verify if the host running Sonarr isn't blocked from accessing {0} by WhiteList limitations in the {0} configuration.", Name)
|
||||
DetailedDescription = string.Format("Please verify your username and password. Also verify if the host running Radarr isn't blocked from accessing {0} by WhiteList limitations in the {0} configuration.", Name)
|
||||
};
|
||||
}
|
||||
catch (WebException ex)
|
||||
|
||||
@@ -16,10 +16,10 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||
|
||||
RuleFor(c => c.UrlBase).ValidUrlBase();
|
||||
|
||||
RuleFor(c => c.TvCategory).Matches(@"^\.?[-a-z]*$", RegexOptions.IgnoreCase).WithMessage("Allowed characters a-z and -");
|
||||
RuleFor(c => c.MovieCategory).Matches(@"^\.?[-a-z]*$", RegexOptions.IgnoreCase).WithMessage("Allowed characters a-z and -");
|
||||
|
||||
RuleFor(c => c.TvCategory).Empty()
|
||||
.When(c => c.TvDirectory.IsNotNullOrWhiteSpace())
|
||||
RuleFor(c => c.MovieCategory).Empty()
|
||||
.When(c => c.MovieDirectory.IsNotNullOrWhiteSpace())
|
||||
.WithMessage("Cannot use Category and Directory");
|
||||
}
|
||||
}
|
||||
@@ -50,19 +50,13 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||
[FieldDefinition(4, Label = "Password", Type = FieldType.Password)]
|
||||
public string Password { get; set; }
|
||||
|
||||
[FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional. Creates a [category] subdirectory in the output directory.")]
|
||||
public string TvCategory { get; set; }
|
||||
[FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional. Creates a [category] subdirectory in the output directory.")]
|
||||
public string MovieCategory { get; set; }
|
||||
|
||||
[FieldDefinition(6, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "Optional location to put downloads in, leave blank to use the default Transmission location")]
|
||||
public string TvDirectory { get; set; }
|
||||
public string MovieDirectory { get; set; }
|
||||
|
||||
[FieldDefinition(7, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
public int RecentTvPriority { get; set; }
|
||||
|
||||
[FieldDefinition(8, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
||||
public int OlderTvPriority { get; set; }
|
||||
|
||||
[FieldDefinition(9, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||
[FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||
public bool UseSsl { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
|
||||
@@ -38,19 +38,22 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
}
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||
{
|
||||
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||
}
|
||||
|
||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||
{
|
||||
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||
}
|
||||
|
||||
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);
|
||||
_proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings);
|
||||
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.
|
||||
@@ -68,7 +71,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
}
|
||||
}
|
||||
|
||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||
protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent)
|
||||
{
|
||||
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||
|
||||
@@ -76,13 +79,9 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
var retryDelay = 100;
|
||||
if (WaitForTorrent(hash, tries, retryDelay))
|
||||
{
|
||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
||||
|
||||
SetPriority(remoteEpisode, hash);
|
||||
_proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings);
|
||||
SetDownloadDirectory(hash);
|
||||
|
||||
_proxy.StartTorrent(hash, Settings);
|
||||
|
||||
return hash;
|
||||
}
|
||||
else
|
||||
@@ -90,13 +89,13 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
_logger.Debug("rTorrent could not add file");
|
||||
|
||||
RemoveItem(hash, true);
|
||||
throw new ReleaseDownloadException(remoteEpisode.Release, "Downloading torrent failed");
|
||||
throw new ReleaseDownloadException(remoteMovie.Release, "Downloading torrent failed");
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
@@ -110,7 +109,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
foreach (RTorrentTorrent torrent in torrents)
|
||||
{
|
||||
// Don't concern ourselves with categories other than specified
|
||||
if (torrent.Category != Settings.TvCategory) continue;
|
||||
if (torrent.Category != Settings.MovieCategory) continue;
|
||||
|
||||
if (torrent.Path.StartsWith("."))
|
||||
{
|
||||
@@ -230,17 +229,11 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
return result.Errors.First();
|
||||
}
|
||||
|
||||
private void SetPriority(RemoteEpisode remoteEpisode, string hash)
|
||||
{
|
||||
var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority);
|
||||
_proxy.SetTorrentPriority(hash, priority, Settings);
|
||||
}
|
||||
|
||||
private void SetDownloadDirectory(string hash)
|
||||
{
|
||||
if (Settings.TvDirectory.IsNotNullOrWhiteSpace())
|
||||
if (Settings.MovieDirectory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetTorrentDownloadDirectory(hash, Settings.TvDirectory, Settings);
|
||||
_proxy.SetTorrentDownloadDirectory(hash, Settings.MovieDirectory, Settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@ namespace NzbDrone.Core.Download.Clients.rTorrent
|
||||
DroneFactoryValidator droneFactoryValidator,
|
||||
MappedNetworkDriveValidator mappedNetworkDriveValidator)
|
||||
{
|
||||
RuleFor(c => c.TvDirectory).Cascade(CascadeMode.StopOnFirstFailure)
|
||||
RuleFor(c => c.MovieDirectory).Cascade(CascadeMode.StopOnFirstFailure)
|
||||
.IsValidPath()
|
||||
.SetValidator(rootFolderValidator)
|
||||
.SetValidator(droneFactoryValidator)
|
||||
.SetValidator(mappedNetworkDriveValidator)
|
||||
.SetValidator(pathExistsValidator)
|
||||
.When(c => c.TvDirectory.IsNotNullOrWhiteSpace())
|
||||
.When(c => c.MovieDirectory.IsNotNullOrWhiteSpace())
|
||||
.When(c => c.Host == "localhost" || c.Host == "127.0.0.1");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
{
|
||||
RuleFor(c => c.Host).ValidHost();
|
||||
RuleFor(c => c.Port).InclusiveBetween(0, 65535);
|
||||
RuleFor(c => c.TvCategory).NotEmpty()
|
||||
RuleFor(c => c.MovieCategory).NotEmpty()
|
||||
.WithMessage("A category is recommended")
|
||||
.AsWarning();
|
||||
}
|
||||
@@ -26,9 +26,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
Host = "localhost";
|
||||
Port = 8080;
|
||||
UrlBase = "RPC2";
|
||||
TvCategory = "tv-sonarr";
|
||||
OlderTvPriority = (int)RTorrentPriority.Normal;
|
||||
RecentTvPriority = (int)RTorrentPriority.Normal;
|
||||
MovieCategory = "movies-radarr";
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||
@@ -49,17 +47,11 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password)]
|
||||
public string Password { get; set; }
|
||||
|
||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional.")]
|
||||
public string TvCategory { get; set; }
|
||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional.")]
|
||||
public string MovieCategory { get; set; }
|
||||
|
||||
[FieldDefinition(7, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "Optional location to put downloads in, leave blank to use the default rTorrent location")]
|
||||
public string TvDirectory { get; set; }
|
||||
|
||||
[FieldDefinition(8, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
public int RecentTvPriority { get; set; }
|
||||
|
||||
[FieldDefinition(9, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
||||
public int OlderTvPriority { get; set; }
|
||||
public string MovieDirectory { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
|
||||
@@ -68,6 +68,38 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteMovie remoteEpisode, string hash, string magnetLink)
|
||||
{
|
||||
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
||||
|
||||
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)UTorrentPriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)UTorrentPriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(hash, Settings);
|
||||
}*/
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected override string AddFromTorrentFile(RemoteMovie remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||
{
|
||||
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
||||
|
||||
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||
|
||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)UTorrentPriority.First ||
|
||||
!isRecentEpisode && Settings.OlderTvPriority == (int)UTorrentPriority.First)
|
||||
{
|
||||
_proxy.MoveTorrentToTopInQueue(hash, Settings);
|
||||
}*/
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
public override string Name => "uTorrent";
|
||||
|
||||
public override IEnumerable<DownloadClientItem> GetItems()
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
||||
public string Password { get; set; }
|
||||
|
||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||
public string TvCategory { get; set; }
|
||||
|
||||
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(UTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
|
||||
@@ -94,31 +94,18 @@ namespace NzbDrone.Core.Download
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var series = _parsingService.GetSeries(trackedDownload.DownloadItem.Title);
|
||||
|
||||
if (series == null)
|
||||
var movie = _parsingService.GetMovie(trackedDownload.DownloadItem.Title);
|
||||
if (movie == null)
|
||||
{
|
||||
if (historyItem != null)
|
||||
{
|
||||
//series = _seriesService.GetSeries(historyItem.SeriesId);
|
||||
movie = _movieService.GetMovie(historyItem.MovieId);
|
||||
}
|
||||
|
||||
if (series == null)
|
||||
if (movie == null)
|
||||
{
|
||||
var movie = _parsingService.GetMovie(trackedDownload.DownloadItem.Title);
|
||||
|
||||
if (movie == null)
|
||||
{
|
||||
movie = _movieService.GetMovie(historyItem.MovieId);
|
||||
|
||||
if (movie == null)
|
||||
{
|
||||
trackedDownload.Warn("Movie title mismatch, automatic import is not possible.");
|
||||
}
|
||||
}
|
||||
//trackedDownload.Warn("Series title mismatch, automatic import is not possible.");
|
||||
//return;
|
||||
trackedDownload.Warn("Movie title mismatch, automatic import is not possible.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,61 +116,30 @@ namespace NzbDrone.Core.Download
|
||||
private void Import(TrackedDownload trackedDownload)
|
||||
{
|
||||
var outputPath = trackedDownload.DownloadItem.OutputPath.FullPath;
|
||||
if (trackedDownload.RemoteMovie.Movie != null)
|
||||
var importResults = _downloadedMovieImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteMovie.Movie, trackedDownload.DownloadItem);
|
||||
|
||||
if (importResults.Empty())
|
||||
{
|
||||
var importResults = _downloadedMovieImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteMovie.Movie, trackedDownload.DownloadItem);
|
||||
|
||||
if (importResults.Empty())
|
||||
{
|
||||
trackedDownload.Warn("No files found are eligible for import in {0}", outputPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (importResults.Count(c => c.Result == ImportResultType.Imported) >= 1)
|
||||
{
|
||||
trackedDownload.State = TrackedDownloadStage.Imported;
|
||||
_eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload));
|
||||
return;
|
||||
}
|
||||
|
||||
if (importResults.Any(c => c.Result != ImportResultType.Imported))
|
||||
{
|
||||
var statusMessages = importResults
|
||||
.Where(v => v.Result != ImportResultType.Imported)
|
||||
.Select(v => new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.LocalEpisode.Path), v.Errors))
|
||||
.ToArray();
|
||||
|
||||
trackedDownload.Warn(statusMessages);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var importResults = _downloadedEpisodesImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteEpisode.Series, trackedDownload.DownloadItem);
|
||||
|
||||
if (importResults.Empty())
|
||||
{
|
||||
trackedDownload.Warn("No files found are eligible for import in {0}", outputPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (importResults.Count(c => c.Result == ImportResultType.Imported) >= Math.Max(1, trackedDownload.RemoteEpisode.Episodes.Count))
|
||||
{
|
||||
trackedDownload.State = TrackedDownloadStage.Imported;
|
||||
_eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload));
|
||||
return;
|
||||
}
|
||||
|
||||
if (importResults.Any(c => c.Result != ImportResultType.Imported))
|
||||
{
|
||||
var statusMessages = importResults
|
||||
.Where(v => v.Result != ImportResultType.Imported)
|
||||
.Select(v => new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.LocalEpisode.Path), v.Errors))
|
||||
.ToArray();
|
||||
|
||||
trackedDownload.Warn(statusMessages);
|
||||
}
|
||||
trackedDownload.Warn("No files found are eligible for import in {0}", outputPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (importResults.Count(c => c.Result == ImportResultType.Imported) >= 1)
|
||||
{
|
||||
trackedDownload.State = TrackedDownloadStage.Imported;
|
||||
_eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload));
|
||||
return;
|
||||
}
|
||||
|
||||
if (importResults.Any(c => c.Result != ImportResultType.Imported))
|
||||
{
|
||||
var statusMessages = importResults
|
||||
.Where(v => v.Result != ImportResultType.Imported)
|
||||
.Select(v => new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.LocalMovie.Path), v.Errors))
|
||||
.ToArray();
|
||||
|
||||
trackedDownload.Warn(statusMessages);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace NzbDrone.Core.Download
|
||||
}
|
||||
|
||||
public int SeriesId { get; set; }
|
||||
public int MovieId { get; set; }
|
||||
public List<int> EpisodeIds { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public string SourceTitle { get; set; }
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace NzbDrone.Core.Download
|
||||
|
||||
if (grabbedItems.Empty())
|
||||
{
|
||||
trackedDownload.Warn("Download wasn't grabbed by sonarr, skipping");
|
||||
trackedDownload.Warn("Download wasn't grabbed by Radarr, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ namespace NzbDrone.Core.Download
|
||||
var downloadFailedEvent = new DownloadFailedEvent
|
||||
{
|
||||
SeriesId = historyItem.SeriesId,
|
||||
MovieId = historyItem.MovieId,
|
||||
EpisodeIds = historyItems.Select(h => h.EpisodeId).ToList(),
|
||||
Quality = historyItem.Quality,
|
||||
SourceTitle = historyItem.SourceTitle,
|
||||
|
||||
@@ -51,6 +51,12 @@ namespace NzbDrone.Core.Download
|
||||
continue;
|
||||
}
|
||||
|
||||
if (report.Rejections.Any())
|
||||
{
|
||||
_logger.Debug("Rejecting release {0} because {1}", report.ToString(), report.Rejections.First().Reason);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (remoteMovie == null || remoteMovie.Movie == null)
|
||||
{
|
||||
continue;
|
||||
|
||||
@@ -34,6 +34,15 @@ namespace NzbDrone.Core.Download
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.MovieId != 0)
|
||||
{
|
||||
_logger.Debug("Failed download contains a movie, searching again.");
|
||||
|
||||
_commandQueueManager.Push(new MoviesSearchCommand { MovieId = message.MovieId });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.EpisodeIds.Count == 1)
|
||||
{
|
||||
_logger.Debug("Failed download only contains one episode, searching again");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user