mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-23 06:45:19 -07:00
Merge branch 'develop' into feature/net-import
This commit is contained in:
commit
47824426c6
138 changed files with 2642 additions and 1723 deletions
26
.gitignore
vendored
26
.gitignore
vendored
|
@ -101,16 +101,21 @@ App_Data/*.ldf
|
||||||
_NCrunch_*
|
_NCrunch_*
|
||||||
_TeamCity*
|
_TeamCity*
|
||||||
|
|
||||||
# Sonarr
|
# Radarr
|
||||||
config.xml
|
Backups/
|
||||||
nzbdrone.log*txt
|
logs/
|
||||||
|
MediaCover/
|
||||||
UpdateLogs/
|
UpdateLogs/
|
||||||
|
xdg/
|
||||||
|
config.xml
|
||||||
|
logs.db*
|
||||||
|
nzbdrone.db*
|
||||||
|
nzbdrone.pid
|
||||||
*workspace.xml
|
*workspace.xml
|
||||||
*.test-cache
|
*.test-cache
|
||||||
*.userprefs
|
*.userprefs
|
||||||
*/test-results/*
|
*/test-results/*
|
||||||
src/UI/.idea/*
|
src/UI/.idea/*
|
||||||
*log.txt
|
|
||||||
node_modules/
|
node_modules/
|
||||||
_output*
|
_output*
|
||||||
_rawPackage/
|
_rawPackage/
|
||||||
|
@ -122,23 +127,26 @@ setup/Output/
|
||||||
|
|
||||||
UI.Phantom/
|
UI.Phantom/
|
||||||
|
|
||||||
#VS outout folders
|
# VS outout folders
|
||||||
bin
|
bin
|
||||||
obj
|
obj
|
||||||
output/*
|
output/*
|
||||||
|
|
||||||
#Packages
|
# Packages
|
||||||
Radarr_*/
|
Radarr_*/
|
||||||
Radarr_*.zip
|
Radarr_*.zip
|
||||||
Radarr_*.gz
|
Radarr_*.gz
|
||||||
|
|
||||||
#OS X metadata files
|
# macOS metadata files
|
||||||
._*
|
._*
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
_start
|
_start
|
||||||
_temp_*/**/*
|
_temp_*/**/*
|
||||||
|
|
||||||
#AppVeyor
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# AppVeyor
|
||||||
/tools-cake/
|
/tools-cake/
|
||||||
/_artifacts/
|
/_artifacts/
|
||||||
|
|
10
.travis.yml
10
.travis.yml
|
@ -1,12 +1,14 @@
|
||||||
language: csharp
|
language: csharp
|
||||||
solution: src/NzbDrone.sln
|
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
|
- ./build.sh
|
||||||
- chmod +x test.sh
|
- chmod +x test.sh
|
||||||
# - ./test.sh Linux Unit Takes far too long, maybe even crashes travis :/
|
# - ./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:
|
after_success:
|
||||||
- chmod +x package.sh
|
- chmod +x package.sh
|
||||||
- ./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.
|
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. Definitions ##
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# How to Contribute #
|
# How to Contribute #
|
||||||
|
|
||||||
We're always looking for people to help make Sonarr even better, there are a number of ways to contribute.
|
We're always looking for people to help make Radarr even better, there are a number of ways to contribute.
|
||||||
|
|
||||||
## Documentation ##
|
## Documentation ##
|
||||||
Setup guides, FAQ, the more information we have on the wiki the better.
|
Setup guides, FAQ, the more information we have on the wiki the better.
|
||||||
|
@ -15,7 +15,7 @@ Setup guides, FAQ, the more information we have on the wiki the better.
|
||||||
|
|
||||||
### Getting started ###
|
### 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)*
|
2. Clone (develop branch) *you may need pull in submodules separately if you client doesn't clone them automatically (CurlSharp)*
|
||||||
3. Run `npm install`
|
3. Run `npm install`
|
||||||
4. Run `npm start` - Used to compile the UI components and copy them.
|
4. Run `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
|
5. Compile in Visual Studio
|
||||||
|
|
||||||
### Contributing Code ###
|
### 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)
|
- 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 Sonarr's develop branch, don't merge
|
- Rebase from Radarr's develop branch, don't merge
|
||||||
- Make meaningful commits, or squash them
|
- 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
|
- 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
|
- Reach out to us on the forums or on IRC if you have any questions
|
||||||
|
|
BIN
Logo/Thumbs.db
BIN
Logo/Thumbs.db
Binary file not shown.
85
README.md
Normal file
85
README.md
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
## 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)
|
||||||
|
|
||||||
|
| 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>.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
*Please note: 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)
|
|
@ -36,6 +36,9 @@ artifacts:
|
||||||
cache:
|
cache:
|
||||||
- '%USERPROFILE%\.nuget\packages'
|
- '%USERPROFILE%\.nuget\packages'
|
||||||
- node_modules
|
- node_modules
|
||||||
|
|
||||||
|
pull_requests:
|
||||||
|
do_not_increment_build_number: true
|
||||||
|
|
||||||
only_commits:
|
only_commits:
|
||||||
files:
|
files:
|
||||||
|
|
81
readme.md
81
readme.md
|
@ -1,81 +0,0 @@
|
||||||
# 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/galli-leo/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.
|
|
||||||
|
|
||||||
Docker containers from [linuxserver.io](https://linuxserver.io) can be found here.
|
|
||||||
* [Radarr (x64)](https://hub.docker.com/r/linuxserver/radarr/)
|
|
||||||
* [Radarr (armhf)](https://hub.docker.com/r/lsioarmhf/radarr/)
|
|
||||||
* [Radarr (aarch64)](https://hub.docker.com/r/lsioarmhf/radarr-aarch64/)
|
|
||||||
|
|
||||||
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/)
|
|
|
@ -27,6 +27,7 @@ namespace NzbDrone.Api.Calendar
|
||||||
|
|
||||||
Get["/NzbDrone.ics"] = options => GetCalendarFeed();
|
Get["/NzbDrone.ics"] = options => GetCalendarFeed();
|
||||||
Get["/Sonarr.ics"] = options => GetCalendarFeed();
|
Get["/Sonarr.ics"] = options => GetCalendarFeed();
|
||||||
|
Get["/Radarr.ics"] = options => GetCalendarFeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response GetCalendarFeed()
|
private Response GetCalendarFeed()
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
Guid = releaseInfo.Guid,
|
Guid = releaseInfo.Guid,
|
||||||
Quality = parsedMovieInfo.Quality,
|
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,
|
Age = releaseInfo.Age,
|
||||||
AgeHours = releaseInfo.AgeHours,
|
AgeHours = releaseInfo.AgeHours,
|
||||||
AgeMinutes = releaseInfo.AgeMinutes,
|
AgeMinutes = releaseInfo.AgeMinutes,
|
||||||
|
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -116,6 +116,7 @@
|
||||||
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
||||||
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
||||||
<Compile Include="Indexers\ReleasePushModule.cs" />
|
<Compile Include="Indexers\ReleasePushModule.cs" />
|
||||||
|
<Compile Include="Movies\MovieFileModule.cs" />
|
||||||
<Compile Include="Movies\MovieModule.cs" />
|
<Compile Include="Movies\MovieModule.cs" />
|
||||||
<Compile Include="Movies\RenameMovieModule.cs" />
|
<Compile Include="Movies\RenameMovieModule.cs" />
|
||||||
<Compile Include="Movies\RenameMovieResource.cs" />
|
<Compile Include="Movies\RenameMovieResource.cs" />
|
||||||
|
|
|
@ -30,8 +30,8 @@ namespace NzbDrone.Api.Movie
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public MovieResource Movie { 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)
|
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,8 @@ namespace NzbDrone.Api.Movie
|
||||||
ReleaseGroup = model.ReleaseGroup,
|
ReleaseGroup = model.ReleaseGroup,
|
||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
Movie = movie,
|
Movie = movie,
|
||||||
|
MediaInfo = model.MediaInfo,
|
||||||
|
Edition = model.Edition
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace NzbDrone.Common
|
||||||
Console.WriteLine(" Commands:");
|
Console.WriteLine(" Commands:");
|
||||||
Console.WriteLine(" /{0} Install the application as a Windows Service ({1}).", StartupContext.INSTALL_SERVICE, ServiceProvider.NZBDRONE_SERVICE_NAME);
|
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} 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.");
|
Console.WriteLine(" <No Arguments> Run application in console mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,12 @@ namespace NzbDrone.Common.Http
|
||||||
|
|
||||||
static UserAgentBuilder()
|
static UserAgentBuilder()
|
||||||
{
|
{
|
||||||
UserAgent = string.Format("Sonarr/{0} ({1} {2})",
|
UserAgent = string.Format("Radarr/{0} ({1} {2})",
|
||||||
BuildInfo.Version,
|
BuildInfo.Version,
|
||||||
OsInfo.Os, OsInfo.Version.ToString(2));
|
OsInfo.Os, OsInfo.Version.ToString(2));
|
||||||
|
|
||||||
UserAgentSimplified = string.Format("Sonarr/{0}",
|
UserAgentSimplified = string.Format("Radarr/{0}",
|
||||||
BuildInfo.Version.ToString(2));
|
BuildInfo.Version.ToString(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,9 +103,9 @@ namespace NzbDrone.Common.Instrumentation
|
||||||
|
|
||||||
private static void RegisterAppFile(IAppFolderInfo appFolderInfo)
|
private static void RegisterAppFile(IAppFolderInfo appFolderInfo)
|
||||||
{
|
{
|
||||||
RegisterAppFile(appFolderInfo, "appFileInfo", "sonarr.txt", 5, LogLevel.Info);
|
RegisterAppFile(appFolderInfo, "appFileInfo", "radarr.txt", 5, LogLevel.Info);
|
||||||
RegisterAppFile(appFolderInfo, "appFileDebug", "sonarr.debug.txt", 50, LogLevel.Off);
|
RegisterAppFile(appFolderInfo, "appFileDebug", "radarr.debug.txt", 50, LogLevel.Off);
|
||||||
RegisterAppFile(appFolderInfo, "appFileTrace", "sonarr.trace.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)
|
private static LoggingRule RegisterAppFile(IAppFolderInfo appFolderInfo, string name, string fileName, int maxArchiveFiles, LogLevel minLogLevel)
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||||
Subject.Definition = new DownloadClientDefinition();
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
Subject.Definition.Settings = new DelugeSettings()
|
Subject.Definition.Settings = new DelugeSettings()
|
||||||
{
|
{
|
||||||
TvCategory = null
|
MovieCategory = null
|
||||||
};
|
};
|
||||||
|
|
||||||
_queued = new DelugeTorrent
|
_queued = new DelugeTorrent
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||||
Port = 2222,
|
Port = 2222,
|
||||||
Username = "admin",
|
Username = "admin",
|
||||||
Password = "pass",
|
Password = "pass",
|
||||||
TvCategory = "tv"
|
MovieCategory = "movies-radarr"
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<ITorrentFileInfoReader>()
|
Mocker.GetMock<ITorrentFileInfoReader>()
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests
|
||||||
Subject.Definition = new DownloadClientDefinition();
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
Subject.Definition.Settings = new RTorrentSettings()
|
Subject.Definition.Settings = new RTorrentSettings()
|
||||||
{
|
{
|
||||||
TvCategory = null
|
MovieCategory = null
|
||||||
};
|
};
|
||||||
|
|
||||||
_downloading = new RTorrentTorrent
|
_downloading = new RTorrentTorrent
|
||||||
|
|
|
@ -112,12 +112,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||||
|
|
||||||
protected void GivenTvCategory()
|
protected void GivenTvCategory()
|
||||||
{
|
{
|
||||||
_settings.TvCategory = "sonarr";
|
_settings.MovieCategory = "radarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void GivenTvDirectory()
|
protected void GivenTvDirectory()
|
||||||
{
|
{
|
||||||
_settings.TvDirectory = @"C:/Downloads/Finished/sonarr";
|
_settings.MovieDirectory = @"C:/Downloads/Finished/radarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void GivenFailedDownload()
|
protected void GivenFailedDownload()
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -42,14 +42,14 @@ namespace NzbDrone.Core.Test.IndexerTests.OmgwtfnzbsTests
|
||||||
|
|
||||||
var releaseInfo = releases.First();
|
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.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
|
||||||
releaseInfo.DownloadUrl.Should().Be("http://api.omgwtfnzbs.org/sn.php?id=OAl4g&user=nzbdrone&api=nzbdrone");
|
releaseInfo.DownloadUrl.Should().Be("https://api.omgwtfnzbs.me/nzb/?id=8a2Bw&user=nzbdrone&api=nzbdrone");
|
||||||
releaseInfo.InfoUrl.Should().Be("http://omgwtfnzbs.org/details.php?id=OAl4g");
|
releaseInfo.InfoUrl.Should().Be("https://omgwtfnzbs.me/details.php?id=8a2Bw");
|
||||||
releaseInfo.CommentUrl.Should().BeNullOrEmpty();
|
releaseInfo.CommentUrl.Should().BeNullOrEmpty();
|
||||||
releaseInfo.Indexer.Should().Be(Subject.Definition.Name);
|
releaseInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||||
releaseInfo.PublishDate.Should().Be(DateTime.Parse("2012/12/17 23:30:13"));
|
releaseInfo.PublishDate.Should().Be(DateTime.Parse("2017/01/09 00:16:54"));
|
||||||
releaseInfo.Size.Should().Be(236822906);
|
releaseInfo.Size.Should().Be(5354909355);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,8 +24,6 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
{
|
{
|
||||||
CompareQuality,
|
CompareQuality,
|
||||||
CompareProtocol,
|
CompareProtocol,
|
||||||
CompareEpisodeCount,
|
|
||||||
CompareEpisodeNumber,
|
|
||||||
ComparePeersIfTorrent,
|
ComparePeersIfTorrent,
|
||||||
CompareAgeIfUsenet,
|
CompareAgeIfUsenet,
|
||||||
CompareSize
|
CompareSize
|
||||||
|
@ -56,6 +54,12 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
|
|
||||||
private int CompareQuality(DownloadDecision x, DownloadDecision y)
|
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)),
|
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.Real),
|
||||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version));
|
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)
|
private int CompareProtocol(DownloadDecision x, DownloadDecision y)
|
||||||
{
|
{
|
||||||
|
|
||||||
var result = CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
var result = CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
||||||
{
|
{
|
||||||
var delayProfile = _delayProfileService.BestForTags(remoteEpisode.Series.Tags);
|
var delayProfile = _delayProfileService.BestForTags(remoteEpisode.Series.Tags);
|
||||||
|
@ -70,13 +75,22 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
return downloadProtocol == delayProfile.PreferredProtocol;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int CompareEpisodeCount(DownloadDecision x, DownloadDecision y)
|
private int CompareEpisodeCount(DownloadDecision x, DownloadDecision y)
|
||||||
{
|
{
|
||||||
return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.FullSeason),
|
return 0;
|
||||||
CompareByReverse(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Episodes.Count));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int CompareEpisodeNumber(DownloadDecision x, DownloadDecision y)
|
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,
|
// Different protocols should get caught when checking the preferred protocol,
|
||||||
// since we're dealing with the same series in our comparisions
|
// since we're dealing with the same series in our comparisions
|
||||||
if (x.RemoteEpisode.Release.DownloadProtocol != DownloadProtocol.Torrent ||
|
if (x.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Torrent ||
|
||||||
y.RemoteEpisode.Release.DownloadProtocol != DownloadProtocol.Torrent)
|
y.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Torrent)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CompareAll(
|
return CompareAll(
|
||||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
|
||||||
{
|
{
|
||||||
var seeders = TorrentInfo.GetSeeders(remoteEpisode.Release);
|
var seeders = TorrentInfo.GetSeeders(remoteEpisode.Release);
|
||||||
|
|
||||||
return seeders.HasValue && seeders.Value > 0 ? Math.Round(Math.Log10(seeders.Value)) : 0;
|
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);
|
var peers = TorrentInfo.GetPeers(remoteEpisode.Release);
|
||||||
|
|
||||||
|
@ -117,7 +131,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
|
||||||
{
|
{
|
||||||
var ageHours = remoteEpisode.Release.AgeHours;
|
var ageHours = remoteEpisode.Release.AgeHours;
|
||||||
var age = remoteEpisode.Release.Age;
|
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.
|
// 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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,7 +265,6 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
e.Data.Add("parsed", remoteEpisode.ParsedEpisodeInfo.ToJson());
|
e.Data.Add("parsed", remoteEpisode.ParsedEpisodeInfo.ToJson());
|
||||||
_logger.Error(e, "Couldn't evaluate decision on " + remoteEpisode.Release.Title + ", with spec: " + spec.GetType().Name);
|
_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 new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));//TODO UPDATE SPECS!
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
|
|
||||||
if (!_qualityUpgradableSpecification.CutoffNotMet(subject.Movie.Profile, remoteEpisode.ParsedMovieInfo.Quality, subject.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);
|
_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();
|
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; }
|
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; }
|
public string WatchFolder { get; set; }
|
||||||
|
|
||||||
[DefaultValue(false)]
|
[DefaultValue(false)]
|
||||||
|
@ -39,7 +39,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
|
||||||
[DefaultValue(false)]
|
[DefaultValue(false)]
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
[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 bool ReadOnly { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -19,10 +19,10 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
{
|
{
|
||||||
private static readonly UsenetBlackholeSettingsValidator Validator = new UsenetBlackholeSettingsValidator();
|
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; }
|
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 string WatchFolder { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -31,25 +31,17 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
_proxy = proxy;
|
_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);
|
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);
|
_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();
|
return actualHash.ToUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,66 +49,24 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
{
|
{
|
||||||
var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
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);
|
_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();
|
return actualHash.ToUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||||
{
|
{
|
||||||
var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings);
|
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||||
{
|
{
|
||||||
var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Deluge";
|
public override string Name => "Deluge";
|
||||||
|
@ -127,9 +77,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
if (!Settings.MovieCategory.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
torrents = _proxy.GetTorrentsByLabel(Settings.TvCategory, Settings);
|
torrents = _proxy.GetTorrentsByLabel(Settings.MovieCategory, Settings);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -149,7 +99,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
var item = new DownloadClientItem();
|
var item = new DownloadClientItem();
|
||||||
item.DownloadId = torrent.Hash.ToUpper();
|
item.DownloadId = torrent.Hash.ToUpper();
|
||||||
item.Title = torrent.Name;
|
item.Title = torrent.Name;
|
||||||
item.Category = Settings.TvCategory;
|
item.Category = Settings.MovieCategory;
|
||||||
|
|
||||||
item.DownloadClient = Definition.Name;
|
item.DownloadClient = Definition.Name;
|
||||||
|
|
||||||
|
@ -280,7 +230,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
|
|
||||||
private ValidationFailure TestCategory()
|
private ValidationFailure TestCategory()
|
||||||
{
|
{
|
||||||
if (Settings.TvCategory.IsNullOrWhiteSpace())
|
if (Settings.MovieCategory.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -297,16 +247,16 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
|
|
||||||
var labels = _proxy.GetAvailableLabels(Settings);
|
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);
|
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.Host).ValidHost();
|
||||||
RuleFor(c => c.Port).GreaterThan(0);
|
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";
|
Host = "localhost";
|
||||||
Port = 8112;
|
Port = 8112;
|
||||||
Password = "deluge";
|
Password = "deluge";
|
||||||
TvCategory = "movie-radarr";
|
MovieCategory = "movie-radarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
|
@ -41,15 +41,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
public string Password { get; set; }
|
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")]
|
[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")]
|
[FieldDefinition(5, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||||
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)]
|
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
[FieldDefinition(2, Label = "API Key", Type = FieldType.Textbox)]
|
[FieldDefinition(2, Label = "API Key", Type = FieldType.Textbox)]
|
||||||
public string ApiKey { get; set; }
|
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; }
|
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")]
|
[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")
|
return new NzbDroneValidationFailure(string.Empty, "NzbGet setting KeepHistory should be greater than 0")
|
||||||
{
|
{
|
||||||
InfoLink = string.Format("http://{0}:{1}/", Settings.Host, Settings.Port),
|
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)]
|
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
||||||
public string Password { get; set; }
|
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; }
|
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")]
|
[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)
|
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||||
{
|
{
|
||||||
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, Byte[] fileContent)
|
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, Byte[] fileContent)
|
||||||
{
|
{
|
||||||
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromMagnetLink(RemoteMovie remoteEpisode, string hash, string magnetLink)
|
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
|
||||||
{
|
{
|
||||||
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
_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;
|
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);
|
_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;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +190,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
else if (version < 6)
|
else if (version < 6)
|
||||||
{
|
{
|
||||||
// API version 6 introduced support for labels
|
// API version 6 introduced support for labels
|
||||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("Category", "Category is not supported")
|
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
|
// warn if labels are supported, but category is not provided
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Category is recommended")
|
return new NzbDroneValidationFailure("TvCategory", "Category is recommended")
|
||||||
|
|
|
@ -58,8 +58,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
public List<QBittorrentTorrent> GetTorrents(QBittorrentSettings settings)
|
public List<QBittorrentTorrent> GetTorrents(QBittorrentSettings settings)
|
||||||
{
|
{
|
||||||
var request = BuildRequest(settings).Resource("/query/torrents")
|
var request = BuildRequest(settings).Resource("/query/torrents")
|
||||||
.AddQueryParam("label", settings.TvCategory)
|
.AddQueryParam("label", settings.MovieCategory)
|
||||||
.AddQueryParam("category", settings.TvCategory);
|
.AddQueryParam("category", settings.MovieCategory);
|
||||||
|
|
||||||
var response = ProcessRequest<List<QBittorrentTorrent>>(request, settings);
|
var response = ProcessRequest<List<QBittorrentTorrent>>(request, settings);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
{
|
{
|
||||||
Host = "localhost";
|
Host = "localhost";
|
||||||
Port = 9091;
|
Port = 9091;
|
||||||
TvCategory = "movie-radarr";
|
MovieCategory = "movie-radarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
|
@ -38,16 +38,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
public string Password { get; set; }
|
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")]
|
[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 = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use a secure connection. See Options -> Web UI -> 'Use HTTPS instead of HTTP' in qBittorrent.")]
|
||||||
[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.")]
|
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -30,13 +30,13 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
}
|
}
|
||||||
|
|
||||||
// patch can be a number (releases) or 'x' (git)
|
// 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)
|
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContents)
|
||||||
{
|
{
|
||||||
var category = Settings.TvCategory;
|
var category = Settings.TvCategory;
|
||||||
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||||
|
|
||||||
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings);
|
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings);
|
||||||
|
|
||||||
if (response != null && response.Ids.Any())
|
if (response != null && response.Ids.Any())
|
||||||
|
@ -284,110 +284,103 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
failures.AddIfNotNull(TestCategory());
|
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);
|
var parsed = VersionRegex.Match(version);
|
||||||
|
|
||||||
int actualMajor;
|
int major;
|
||||||
int actualMinor;
|
int minor;
|
||||||
int actualPatch;
|
int patch;
|
||||||
string actualCandidate;
|
|
||||||
|
|
||||||
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))
|
if (!version.Equals("develop", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
actualMajor = 1;
|
major = 1;
|
||||||
actualMinor = 1;
|
minor = 1;
|
||||||
actualPatch = 0;
|
patch = 0;
|
||||||
actualCandidate = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
return new Version(major, minor, patch);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValidationFailure TestConnectionAndVersion()
|
private ValidationFailure TestConnectionAndVersion()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var version = _proxy.GetVersion(Settings);
|
var rawVersion = _proxy.GetVersion(Settings);
|
||||||
var parsed = VersionRegex.Match(version);
|
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);
|
return new ValidationFailure("Version", "Unknown Version: " + version);
|
||||||
}
|
}
|
||||||
|
|
||||||
var major = Convert.ToInt32(parsed.Groups["major"].Value);
|
if (rawVersion.Equals("develop", StringComparison.InvariantCultureIgnoreCase))
|
||||||
var minor = Convert.ToInt32(parsed.Groups["minor"].Value);
|
{
|
||||||
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minor >= 7)
|
if (version.Minor >= 7)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -431,7 +424,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
return new NzbDroneValidationFailure("", "Disable 'Check before download' option in Sabnbzd")
|
return new NzbDroneValidationFailure("", "Disable 'Check before download' option in Sabnbzd")
|
||||||
{
|
{
|
||||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/switches/", Settings.Host, Settings.Port),
|
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")
|
return new NzbDroneValidationFailure("TvCategory", "Enable Job folders")
|
||||||
{
|
{
|
||||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/categories/", Settings.Host, Settings.Port),
|
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")
|
return new NzbDroneValidationFailure("TvCategory", "Disable TV Sorting")
|
||||||
{
|
{
|
||||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/sorting/", Settings.Host, Settings.Port),
|
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")
|
return new NzbDroneValidationFailure("TvCategory", "Disable Movie Sorting")
|
||||||
{
|
{
|
||||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/sorting/", Settings.Host, Settings.Port),
|
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")
|
return new NzbDroneValidationFailure("TvCategory", "Disable Date Sorting")
|
||||||
{
|
{
|
||||||
InfoLink = string.Format("http://{0}:{1}/sabnzbd/config/sorting/", Settings.Host, Settings.Port),
|
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)]
|
[FieldDefinition(4, Label = "Password", Type = FieldType.Password)]
|
||||||
public string Password { get; set; }
|
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; }
|
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")]
|
[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);
|
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('\\', '/');
|
var directories = outputPath.FullPath.Split('\\', '/');
|
||||||
if (!directories.Contains(Settings.TvCategory)) continue;
|
if (!directories.Contains(Settings.MovieCategory)) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, outputPath);
|
outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, outputPath);
|
||||||
|
|
||||||
var item = new DownloadClientItem();
|
var item = new DownloadClientItem();
|
||||||
item.DownloadId = torrent.HashString.ToUpper();
|
item.DownloadId = torrent.HashString.ToUpper();
|
||||||
item.Category = Settings.TvCategory;
|
item.Category = Settings.MovieCategory;
|
||||||
item.Title = torrent.Name;
|
item.Title = torrent.Name;
|
||||||
|
|
||||||
item.DownloadClient = Definition.Name;
|
item.DownloadClient = Definition.Name;
|
||||||
|
@ -123,9 +123,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
var config = _proxy.GetConfig(Settings);
|
var config = _proxy.GetConfig(Settings);
|
||||||
var destDir = config.GetValueOrDefault("download-dir") as string;
|
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
|
return new DownloadClientStatus
|
||||||
|
@ -137,56 +137,23 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
|
||||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||||
{
|
{
|
||||||
_proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings);
|
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||||
|
|
||||||
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
|
||||||
|
|
||||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)TransmissionPriority.First ||
|
|
||||||
!isRecentEpisode && Settings.OlderTvPriority == (int)TransmissionPriority.First)
|
|
||||||
{
|
|
||||||
_proxy.MoveTorrentToTopInQueue(hash, Settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||||
{
|
{
|
||||||
_proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings);
|
throw new NotImplementedException("Episodes are not working with Radarr");
|
||||||
|
|
||||||
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
|
||||||
|
|
||||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)TransmissionPriority.First ||
|
|
||||||
!isRecentEpisode && Settings.OlderTvPriority == (int)TransmissionPriority.First)
|
|
||||||
{
|
|
||||||
_proxy.MoveTorrentToTopInQueue(hash, Settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
|
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
|
||||||
{
|
{
|
||||||
_proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings);
|
_proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings);
|
||||||
if (remoteMovie.Release.Age < 14 && Settings.RecentTvPriority == (int)TransmissionPriority.First ||
|
|
||||||
remoteMovie.Release.Age > 14 && Settings.OlderTvPriority == (int)TransmissionPriority.First)
|
|
||||||
{
|
|
||||||
_proxy.MoveTorrentToTopInQueue(hash, Settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent)
|
protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent)
|
||||||
{
|
{
|
||||||
_proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings);
|
_proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings);
|
||||||
|
|
||||||
if (remoteMovie.Release.Age < 14 && Settings.RecentTvPriority == (int)TransmissionPriority.First ||
|
|
||||||
remoteMovie.Release.Age > 14 && Settings.OlderTvPriority == (int)TransmissionPriority.First)
|
|
||||||
{
|
|
||||||
_proxy.MoveTorrentToTopInQueue(hash, Settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,16 +171,16 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
|
||||||
protected string GetDownloadDirectory()
|
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 config = _proxy.GetConfig(Settings);
|
||||||
var destDir = (string)config.GetValueOrDefault("download-dir");
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -232,7 +199,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
return new NzbDroneValidationFailure("Username", "Authentication failure")
|
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)
|
catch (WebException ex)
|
||||||
|
|
|
@ -16,10 +16,10 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
|
||||||
RuleFor(c => c.UrlBase).ValidUrlBase();
|
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()
|
RuleFor(c => c.MovieCategory).Empty()
|
||||||
.When(c => c.TvDirectory.IsNotNullOrWhiteSpace())
|
.When(c => c.MovieDirectory.IsNotNullOrWhiteSpace())
|
||||||
.WithMessage("Cannot use Category and Directory");
|
.WithMessage("Cannot use Category and Directory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,19 +50,13 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
[FieldDefinition(4, Label = "Password", Type = FieldType.Password)]
|
[FieldDefinition(4, Label = "Password", Type = FieldType.Password)]
|
||||||
public string Password { get; set; }
|
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.")]
|
[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 TvCategory { get; set; }
|
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")]
|
[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 movies that we're released within the last 14 days")]
|
[FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||||
public int RecentTvPriority { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing movies that we're released over 14 days ago")]
|
|
||||||
public int OlderTvPriority { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Use SSL", Type = FieldType.Checkbox)]
|
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -37,51 +37,23 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
_rTorrentDirectoryValidator = rTorrentDirectoryValidator;
|
_rTorrentDirectoryValidator = rTorrentDirectoryValidator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
|
||||||
{
|
{
|
||||||
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
||||||
|
|
||||||
// Download the magnet to the appropriate directory.
|
// Download the magnet to the appropriate directory.
|
||||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
_proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings);
|
||||||
//SetPriority(remoteEpisode, hash);
|
|
||||||
SetDownloadDirectory(hash);
|
SetDownloadDirectory(hash);
|
||||||
|
|
||||||
// Once the magnet meta download finishes, rTorrent replaces it with the actual torrent download with default settings.
|
|
||||||
// Schedule an event to apply the appropriate settings when that happens.
|
|
||||||
// var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority);
|
|
||||||
//_proxy.SetDeferredMagnetProperties(hash, Settings.TvCategory, Settings.TvDirectory, priority, Settings);
|
|
||||||
|
|
||||||
_proxy.StartTorrent(hash, Settings);
|
|
||||||
|
|
||||||
// Wait for the magnet to be resolved.
|
|
||||||
var tries = 10;
|
|
||||||
var retryDelay = 500;
|
|
||||||
if (WaitForTorrent(hash, tries, retryDelay))
|
|
||||||
{
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Warn("rTorrent could not resolve magnet within {0} seconds, download may remain stuck: {1}.", tries * retryDelay / 1000, magnetLink);
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
|
||||||
{
|
|
||||||
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
|
||||||
|
|
||||||
// Download the magnet to the appropriate directory.
|
|
||||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
|
||||||
SetPriority(remoteEpisode, hash);
|
|
||||||
SetDownloadDirectory(hash);
|
|
||||||
|
|
||||||
// Once the magnet meta download finishes, rTorrent replaces it with the actual torrent download with default settings.
|
|
||||||
// Schedule an event to apply the appropriate settings when that happens.
|
|
||||||
var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority);
|
|
||||||
_proxy.SetDeferredMagnetProperties(hash, Settings.TvCategory, Settings.TvDirectory, priority, Settings);
|
|
||||||
|
|
||||||
_proxy.StartTorrent(hash, Settings);
|
_proxy.StartTorrent(hash, Settings);
|
||||||
|
|
||||||
// Wait for the magnet to be resolved.
|
// Wait for the magnet to be resolved.
|
||||||
|
@ -107,13 +79,9 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
var retryDelay = 100;
|
var retryDelay = 100;
|
||||||
if (WaitForTorrent(hash, tries, retryDelay))
|
if (WaitForTorrent(hash, tries, retryDelay))
|
||||||
{
|
{
|
||||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
_proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings);
|
||||||
|
|
||||||
//SetPriority(remoteEpisode, hash);
|
|
||||||
SetDownloadDirectory(hash);
|
SetDownloadDirectory(hash);
|
||||||
|
|
||||||
_proxy.StartTorrent(hash, Settings);
|
_proxy.StartTorrent(hash, Settings);
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -125,32 +93,6 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
|
||||||
{
|
|
||||||
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
|
||||||
|
|
||||||
var tries = 2;
|
|
||||||
var retryDelay = 100;
|
|
||||||
if (WaitForTorrent(hash, tries, retryDelay))
|
|
||||||
{
|
|
||||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
|
||||||
|
|
||||||
SetPriority(remoteEpisode, hash);
|
|
||||||
SetDownloadDirectory(hash);
|
|
||||||
|
|
||||||
_proxy.StartTorrent(hash, Settings);
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Debug("rTorrent could not add file");
|
|
||||||
|
|
||||||
RemoveItem(hash, true);
|
|
||||||
throw new ReleaseDownloadException(remoteEpisode.Release, "Downloading torrent failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Name => "rTorrent";
|
public override string Name => "rTorrent";
|
||||||
|
|
||||||
public override ProviderMessage Message => new ProviderMessage("Radarr 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);
|
||||||
|
@ -167,7 +109,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
foreach (RTorrentTorrent torrent in torrents)
|
foreach (RTorrentTorrent torrent in torrents)
|
||||||
{
|
{
|
||||||
// Don't concern ourselves with categories other than specified
|
// 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("."))
|
if (torrent.Path.StartsWith("."))
|
||||||
{
|
{
|
||||||
|
@ -287,17 +229,11 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
return result.Errors.First();
|
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)
|
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,
|
DroneFactoryValidator droneFactoryValidator,
|
||||||
MappedNetworkDriveValidator mappedNetworkDriveValidator)
|
MappedNetworkDriveValidator mappedNetworkDriveValidator)
|
||||||
{
|
{
|
||||||
RuleFor(c => c.TvDirectory).Cascade(CascadeMode.StopOnFirstFailure)
|
RuleFor(c => c.MovieDirectory).Cascade(CascadeMode.StopOnFirstFailure)
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
.SetValidator(rootFolderValidator)
|
.SetValidator(rootFolderValidator)
|
||||||
.SetValidator(droneFactoryValidator)
|
.SetValidator(droneFactoryValidator)
|
||||||
.SetValidator(mappedNetworkDriveValidator)
|
.SetValidator(mappedNetworkDriveValidator)
|
||||||
.SetValidator(pathExistsValidator)
|
.SetValidator(pathExistsValidator)
|
||||||
.When(c => c.TvDirectory.IsNotNullOrWhiteSpace())
|
.When(c => c.MovieDirectory.IsNotNullOrWhiteSpace())
|
||||||
.When(c => c.Host == "localhost" || c.Host == "127.0.0.1");
|
.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.Host).ValidHost();
|
||||||
RuleFor(c => c.Port).InclusiveBetween(0, 65535);
|
RuleFor(c => c.Port).InclusiveBetween(0, 65535);
|
||||||
RuleFor(c => c.TvCategory).NotEmpty()
|
RuleFor(c => c.MovieCategory).NotEmpty()
|
||||||
.WithMessage("A category is recommended")
|
.WithMessage("A category is recommended")
|
||||||
.AsWarning();
|
.AsWarning();
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
Host = "localhost";
|
Host = "localhost";
|
||||||
Port = 8080;
|
Port = 8080;
|
||||||
UrlBase = "RPC2";
|
UrlBase = "RPC2";
|
||||||
TvCategory = "movies-radarr";
|
MovieCategory = "movies-radarr";
|
||||||
OlderTvPriority = (int)RTorrentPriority.Normal;
|
|
||||||
RecentTvPriority = (int)RTorrentPriority.Normal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
|
@ -49,17 +47,11 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password)]
|
[FieldDefinition(5, Label = "Password", Type = FieldType.Password)]
|
||||||
public string Password { get; set; }
|
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.")]
|
[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 TvCategory { get; set; }
|
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")]
|
[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; }
|
public string MovieDirectory { 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 NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,6 +68,38 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
return hash;
|
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 string Name => "uTorrent";
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
||||||
public string Password { get; set; }
|
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; }
|
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")]
|
[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,30 +94,18 @@ namespace NzbDrone.Core.Download
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var series = _parsingService.GetSeries(trackedDownload.DownloadItem.Title);
|
var movie = _parsingService.GetMovie(trackedDownload.DownloadItem.Title);
|
||||||
|
if (movie == null)
|
||||||
if (series == null)
|
|
||||||
{
|
{
|
||||||
if (historyItem != 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);
|
trackedDownload.Warn("Movie title mismatch, automatic import is not possible.");
|
||||||
|
return;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,61 +116,30 @@ namespace NzbDrone.Core.Download
|
||||||
private void Import(TrackedDownload trackedDownload)
|
private void Import(TrackedDownload trackedDownload)
|
||||||
{
|
{
|
||||||
var outputPath = trackedDownload.DownloadItem.OutputPath.FullPath;
|
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);
|
trackedDownload.Warn("No files found are eligible for import in {0}", outputPath);
|
||||||
|
return;
|
||||||
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 if (trackedDownload.RemoteEpisode.Series != null)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace NzbDrone.Core.Download
|
||||||
|
|
||||||
if (grabbedItems.Empty())
|
if (grabbedItems.Empty())
|
||||||
{
|
{
|
||||||
trackedDownload.Warn("Download wasn't grabbed by sonarr, skipping");
|
trackedDownload.Warn("Download wasn't grabbed by Radarr, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,9 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
|
|
||||||
public void Clean()
|
public void Clean()
|
||||||
{
|
{
|
||||||
CleanupOrphanedBySeries();
|
//CleanupOrphanedBySeries();
|
||||||
CleanupOrphanedByEpisode();
|
//CleanupOrphanedByEpisode();
|
||||||
|
CleanupOrphanedByMovie();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CleanupOrphanedBySeries()
|
private void CleanupOrphanedBySeries()
|
||||||
|
@ -29,6 +30,18 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
WHERE Series.Id IS NULL)");
|
WHERE Series.Id IS NULL)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CleanupOrphanedByMovie()
|
||||||
|
{
|
||||||
|
var mapper = _database.GetDataMapper();
|
||||||
|
|
||||||
|
mapper.ExecuteNonQuery(@"DELETE FROM History
|
||||||
|
WHERE Id IN (
|
||||||
|
SELECT History.Id FROM History
|
||||||
|
LEFT OUTER JOIN Movies
|
||||||
|
ON History.MovieId = Movies.Id
|
||||||
|
WHERE Movies.Id IS NULL)");
|
||||||
|
}
|
||||||
|
|
||||||
private void CleanupOrphanedByEpisode()
|
private void CleanupOrphanedByEpisode()
|
||||||
{
|
{
|
||||||
var mapper = _database.GetDataMapper();
|
var mapper = _database.GetDataMapper();
|
||||||
|
|
30
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHD.cs
Normal file
30
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHD.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class AwesomeHD : HttpIndexerBase<AwesomeHDSettings>
|
||||||
|
{
|
||||||
|
public override string Name => "AwesomeHD";
|
||||||
|
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||||
|
public override bool SupportsRss => true;
|
||||||
|
public override bool SupportsSearch => true;
|
||||||
|
public override int PageSize => 50;
|
||||||
|
|
||||||
|
public AwesomeHD(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
||||||
|
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public override IIndexerRequestGenerator GetRequestGenerator()
|
||||||
|
{
|
||||||
|
return new AwesomeHDRequestGenerator() { Settings = Settings };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IParseIndexerResponse GetParser()
|
||||||
|
{
|
||||||
|
return new AwesomeHDRssParser(Settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDApi.cs
Normal file
80
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDApi.cs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class Torrent
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "id")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
[XmlElement(ElementName = "groupid")]
|
||||||
|
public string GroupId { get; set; }
|
||||||
|
[XmlElement(ElementName = "time")]
|
||||||
|
public DateTime Time { get; set; }
|
||||||
|
[XmlElement(ElementName = "userid")]
|
||||||
|
public string Userid { get; set; }
|
||||||
|
[XmlElement(ElementName = "size")]
|
||||||
|
public long Size { get; set; }
|
||||||
|
[XmlElement(ElementName = "snatched")]
|
||||||
|
public string Snatched { get; set; }
|
||||||
|
[XmlElement(ElementName = "seeders")]
|
||||||
|
public string Seeders { get; set; }
|
||||||
|
[XmlElement(ElementName = "leechers")]
|
||||||
|
public string Leechers { get; set; }
|
||||||
|
[XmlElement(ElementName = "releasegroup")]
|
||||||
|
public string Releasegroup { get; set; }
|
||||||
|
[XmlElement(ElementName = "resolution")]
|
||||||
|
public string Resolution { get; set; }
|
||||||
|
[XmlElement(ElementName = "media")]
|
||||||
|
public string Media { get; set; }
|
||||||
|
[XmlElement(ElementName = "format")]
|
||||||
|
public string Format { get; set; }
|
||||||
|
[XmlElement(ElementName = "encoding")]
|
||||||
|
public string Encoding { get; set; }
|
||||||
|
[XmlElement(ElementName = "audioformat")]
|
||||||
|
public string Audioformat { get; set; }
|
||||||
|
[XmlElement(ElementName = "audiobitrate")]
|
||||||
|
public string Audiobitrate { get; set; }
|
||||||
|
[XmlElement(ElementName = "audiochannels")]
|
||||||
|
public string Audiochannels { get; set; }
|
||||||
|
[XmlElement(ElementName = "subtitles")]
|
||||||
|
public string Subtitles { get; set; }
|
||||||
|
[XmlElement(ElementName = "encodestatus")]
|
||||||
|
public string Encodestatus { get; set; }
|
||||||
|
[XmlElement(ElementName = "freeleech")]
|
||||||
|
public string Freeleech { get; set; }
|
||||||
|
[XmlElement(ElementName = "cover")]
|
||||||
|
public string Cover { get; set; }
|
||||||
|
[XmlElement(ElementName = "smallcover")]
|
||||||
|
public string Smallcover { get; set; }
|
||||||
|
[XmlElement(ElementName = "year")]
|
||||||
|
public string Year { get; set; }
|
||||||
|
[XmlElement(ElementName = "name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
[XmlElement(ElementName = "imdb")]
|
||||||
|
public string Imdb { get; set; }
|
||||||
|
[XmlElement(ElementName = "type")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
[XmlElement(ElementName = "plotoutline")]
|
||||||
|
public string Plotoutline { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SearchResults
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "authkey")]
|
||||||
|
public string AuthKey { get; set; }
|
||||||
|
[XmlElement(ElementName = "torrent")]
|
||||||
|
public List<Torrent> Torrent { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AwesomeHDSearchResponse
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "?xml")]
|
||||||
|
public string Xml { get; set; }
|
||||||
|
[XmlElement(ElementName = "searchresults")]
|
||||||
|
public SearchResults SearchResults { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class AwesomeHDRequestGenerator : IIndexerRequestGenerator
|
||||||
|
{
|
||||||
|
public AwesomeHDSettings Settings { get; set; }
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetRecentRequests()
|
||||||
|
{
|
||||||
|
var pageableRequests = new IndexerPageableRequestChain();
|
||||||
|
|
||||||
|
pageableRequests.Add(GetRequest(null));
|
||||||
|
|
||||||
|
return pageableRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(SingleEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(AnimeEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(SpecialEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(DailyEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(SeasonSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
var pageableRequests = new IndexerPageableRequestChain();
|
||||||
|
pageableRequests.Add(GetRequest(searchCriteria.Movie.ImdbId));
|
||||||
|
return pageableRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<IndexerRequest> GetRequest(string searchParameters)
|
||||||
|
{
|
||||||
|
if (searchParameters != null)
|
||||||
|
{
|
||||||
|
yield return new IndexerRequest(string.Format("{0}/searchapi.php?action=imdbsearch&passkey={1}&imdb={2}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.Passkey.Trim(), searchParameters), HttpAccept.Rss);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yield return new IndexerRequest(string.Format("{0}/searchapi.php?action=latestmovies&passkey={1}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.Passkey.Trim()), HttpAccept.Rss);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
92
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDRssParser.cs
Normal file
92
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDRssParser.cs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Indexers.Exceptions;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class AwesomeHDRssParser : IParseIndexerResponse
|
||||||
|
{
|
||||||
|
private readonly AwesomeHDSettings _settings;
|
||||||
|
|
||||||
|
public AwesomeHDRssParser(AwesomeHDSettings settings)
|
||||||
|
{
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
|
||||||
|
{
|
||||||
|
var torrentInfos = new List<ReleaseInfo>();
|
||||||
|
|
||||||
|
if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
throw new IndexerException(indexerResponse,
|
||||||
|
"Unexpected response status {0} code from API request",
|
||||||
|
indexerResponse.HttpResponse.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hacky ¯\_(ツ)_/¯
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
doc.LoadXml(indexerResponse.Content);
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeXmlNode(doc);
|
||||||
|
|
||||||
|
Console.WriteLine(json);
|
||||||
|
|
||||||
|
var jsonResponse = JsonConvert.DeserializeObject<AwesomeHDSearchResponse>(json);
|
||||||
|
|
||||||
|
if (jsonResponse == null)
|
||||||
|
{
|
||||||
|
throw new IndexerException(indexerResponse, "Unexpected response from request");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var torrent in jsonResponse.SearchResults.Torrent)
|
||||||
|
{
|
||||||
|
var id = torrent.Id;
|
||||||
|
var title = $"{torrent.Name}.{torrent.Year}.{torrent.Resolution}.{torrent.Media}.{torrent.Encoding}.{torrent.Audioformat}-{torrent.Releasegroup}";
|
||||||
|
|
||||||
|
torrentInfos.Add(new TorrentInfo()
|
||||||
|
{
|
||||||
|
Guid = string.Format("AwesomeHD-{0}", id),
|
||||||
|
Title = title,
|
||||||
|
Size = torrent.Size,
|
||||||
|
DownloadUrl = GetDownloadUrl(id, jsonResponse.SearchResults.AuthKey, _settings.Passkey),
|
||||||
|
InfoUrl = GetInfoUrl(torrent.GroupId, id),
|
||||||
|
Seeders = int.Parse(torrent.Seeders),
|
||||||
|
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
||||||
|
PublishDate = torrent.Time.ToUniversalTime()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return torrentInfos.OrderByDescending(o => ((dynamic)o).Seeders).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetDownloadUrl(string torrentId, string authKey, string passKey)
|
||||||
|
{
|
||||||
|
var url = new HttpUri(_settings.BaseUrl)
|
||||||
|
.CombinePath("/torrents.php")
|
||||||
|
.AddQueryParam("action", "download")
|
||||||
|
.AddQueryParam("id", torrentId)
|
||||||
|
.AddQueryParam("authkey", authKey)
|
||||||
|
.AddQueryParam("torrent_pass", passKey);
|
||||||
|
|
||||||
|
return url.FullUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetInfoUrl(string groupId, string torrentId)
|
||||||
|
{
|
||||||
|
var url = new HttpUri(_settings.BaseUrl)
|
||||||
|
.CombinePath("/torrents.php")
|
||||||
|
.AddQueryParam("id", groupId)
|
||||||
|
.AddQueryParam("torrentid", torrentId);
|
||||||
|
|
||||||
|
return url.FullUri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDSettings.cs
Normal file
37
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDSettings.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Validation;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class AwesomeHDSettingsValidator : AbstractValidator<AwesomeHDSettings>
|
||||||
|
{
|
||||||
|
public AwesomeHDSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.BaseUrl).ValidRootUrl();
|
||||||
|
RuleFor(c => c.Passkey).NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AwesomeHDSettings : IProviderConfig
|
||||||
|
{
|
||||||
|
private static readonly AwesomeHDSettingsValidator Validator = new AwesomeHDSettingsValidator();
|
||||||
|
|
||||||
|
public AwesomeHDSettings()
|
||||||
|
{
|
||||||
|
BaseUrl = "https://awesome-hd.me";
|
||||||
|
}
|
||||||
|
|
||||||
|
[FieldDefinition(0, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since you Passkey will be sent to that host.")]
|
||||||
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(1, Label = "Passkey")]
|
||||||
|
public string Passkey { get; set; }
|
||||||
|
|
||||||
|
public NzbDroneValidationResult Validate()
|
||||||
|
{
|
||||||
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,14 +39,15 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return GetDefinition("Dognzb.cr", GetSettings("https://api.dognzb.cr"));
|
yield return GetDefinition("DOGnzb", GetSettings("https://api.dognzb.cr"));
|
||||||
yield return GetDefinition("DrunkenSlug", GetSettings("https://api.drunkenslug.com"));
|
yield return GetDefinition("DrunkenSlug", GetSettings("https://api.drunkenslug.com"));
|
||||||
|
yield return GetDefinition("Nzb-Tortuga", GetSettings("https://www.nzb-tortuga.com"));
|
||||||
yield return GetDefinition("Nzb.su", GetSettings("https://api.nzb.su"));
|
yield return GetDefinition("Nzb.su", GetSettings("https://api.nzb.su"));
|
||||||
yield return GetDefinition("NZBCat", GetSettings("https://nzb.cat"));
|
yield return GetDefinition("NZBCat", GetSettings("https://nzb.cat"));
|
||||||
yield return GetDefinition("NZBFinder.ws", GetSettings("https://nzbfinder.ws", 5010, 5030, 5040, 5045));
|
yield return GetDefinition("NZBFinder.ws", GetSettings("https://nzbfinder.ws"));
|
||||||
yield return GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info"));
|
yield return GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info"));
|
||||||
yield return GetDefinition("nzbplanet.net", GetSettings("https://api.nzbplanet.net"));
|
yield return GetDefinition("nzbplanet.net", GetSettings("https://api.nzbplanet.net"));
|
||||||
yield return GetDefinition("Nzbs.org", GetSettings("http://nzbs.org", 2000));
|
yield return GetDefinition("Nzbs.org", GetSettings("http://nzbs.org"));
|
||||||
yield return GetDefinition("OZnzb.com", GetSettings("https://api.oznzb.com"));
|
yield return GetDefinition("OZnzb.com", GetSettings("https://api.oznzb.com"));
|
||||||
yield return GetDefinition("PFmonkey", GetSettings("https://www.pfmonkey.com"));
|
yield return GetDefinition("PFmonkey", GetSettings("https://www.pfmonkey.com"));
|
||||||
yield return GetDefinition("SimplyNZBs", GetSettings("https://simplynzbs.com"));
|
yield return GetDefinition("SimplyNZBs", GetSettings("https://simplynzbs.com"));
|
||||||
|
|
|
@ -124,7 +124,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
{
|
{
|
||||||
var pageableRequests = new IndexerPageableRequestChain();
|
var pageableRequests = new IndexerPageableRequestChain();
|
||||||
|
|
||||||
if (SupportsMovieSearch)
|
if (false)
|
||||||
{
|
{
|
||||||
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories, "movie",
|
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories, "movie",
|
||||||
string.Format("&imdbid={0}", searchCriteria.Movie.ImdbId.Substring(2)))); //strip off the "tt" - VERY HACKY
|
string.Format("&imdbid={0}", searchCriteria.Movie.ImdbId.Substring(2)))); //strip off the "tt" - VERY HACKY
|
||||||
|
@ -133,7 +133,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
{
|
{
|
||||||
//Let's try anyways with q parameter, worst case nothing found.
|
//Let's try anyways with q parameter, worst case nothing found.
|
||||||
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories, "search",
|
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories, "search",
|
||||||
string.Format("&q={0}", searchCriteria.Movie.Title)));
|
string.Format("&q={0}", Parser.Parser.NormalizeTitle(searchCriteria.Movie.Title))));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pageableRequests;
|
return pageableRequests;
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
|
|
||||||
public NewznabSettings()
|
public NewznabSettings()
|
||||||
{
|
{
|
||||||
Categories = new[] { 2030, 2035, 2040, 2050 };
|
Categories = new[] { 2000, 2010, 2020, 2030, 2035, 2040, 2045, 2050, 2060 };
|
||||||
AnimeCategories = Enumerable.Empty<int>();
|
AnimeCategories = Enumerable.Empty<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Indexers.Omgwtfnzbs
|
||||||
protected override string GetInfoUrl(XElement item)
|
protected override string GetInfoUrl(XElement item)
|
||||||
{
|
{
|
||||||
//Todo: Me thinks I need to parse details to get this...
|
//Todo: Me thinks I need to parse details to get this...
|
||||||
var match = Regex.Match(item.Description(), @"(?:\<b\>View NZB\:\<\/b\>\s\<a\shref\=\"")(?<URL>.+)(?:\""\starget)",
|
var match = Regex.Match(item.Description(), @"(?:\<b\>View NZB\:\<\/b\>\s\<a\shref\=\"")(?<URL>.+)(?:\"")",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||||
torrentInfo.Seeders = torrent.seeders;
|
torrentInfo.Seeders = torrent.seeders;
|
||||||
torrentInfo.Peers = torrent.leechers + torrent.seeders;
|
torrentInfo.Peers = torrent.leechers + torrent.seeders;
|
||||||
torrentInfo.Freeleech = torrent.freeleech;
|
torrentInfo.Freeleech = torrent.freeleech;
|
||||||
|
torrentInfo.PublishDate = torrent.publishdate.ToUniversalTime();
|
||||||
|
|
||||||
results.Add(torrentInfo);
|
results.Add(torrentInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,9 +78,16 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||||
.Accept(HttpAccept.Json);
|
.Accept(HttpAccept.Json);
|
||||||
|
|
||||||
requestBuilder.AddQueryParam("passkey", Settings.Passkey);
|
requestBuilder.AddQueryParam("passkey", Settings.Passkey);
|
||||||
requestBuilder.AddQueryParam("user", Settings.User);
|
if (!string.IsNullOrWhiteSpace(Settings.User))
|
||||||
// requestBuilder.AddQueryParam("imdbid", "tt0076759"); //For now just search for Star Wars.
|
{
|
||||||
requestBuilder.AddQueryParam("search", "the"); // there has to be movies with 'the' in the title on any indexer
|
requestBuilder.AddQueryParam("user", Settings.User);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requestBuilder.AddQueryParam("user", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
requestBuilder.AddQueryParam("search", "the");
|
||||||
|
|
||||||
yield return new IndexerRequest(requestBuilder.Build());
|
yield return new IndexerRequest(requestBuilder.Build());
|
||||||
}
|
}
|
||||||
|
@ -91,7 +98,15 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||||
.Accept(HttpAccept.Json);
|
.Accept(HttpAccept.Json);
|
||||||
|
|
||||||
requestBuilder.AddQueryParam("passkey", Settings.Passkey);
|
requestBuilder.AddQueryParam("passkey", Settings.Passkey);
|
||||||
requestBuilder.AddQueryParam("user", Settings.User);
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(Settings.User))
|
||||||
|
{
|
||||||
|
requestBuilder.AddQueryParam("user", Settings.User);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requestBuilder.AddQueryParam("user", "");
|
||||||
|
}
|
||||||
|
|
||||||
if (searchCriteria.Movie.ImdbId.IsNotNullOrWhiteSpace())
|
if (searchCriteria.Movie.ImdbId.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||||
public int size { get; set; }
|
public int size { get; set; }
|
||||||
public int leechers { get; set; }
|
public int leechers { get; set; }
|
||||||
public int seeders { get; set; }
|
public int seeders { get; set; }
|
||||||
|
public DateTime publishdate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||||
|
|
||||||
public TorrentPotatoSettings()
|
public TorrentPotatoSettings()
|
||||||
{
|
{
|
||||||
BaseUrl = "";
|
BaseUrl = "http://127.0.0.1";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "API URL", HelpText = "URL to TorrentPotato api.")]
|
[FieldDefinition(0, Label = "API URL", HelpText = "URL to TorrentPotato api.")]
|
||||||
|
|
|
@ -97,8 +97,7 @@ namespace NzbDrone.Core.Indexers.Torznab
|
||||||
}
|
}
|
||||||
|
|
||||||
if (capabilities.SupportedTvSearchParameters != null &&
|
if (capabilities.SupportedTvSearchParameters != null &&
|
||||||
new[] { "q", "tvdbid", "rid" }.Any(v => capabilities.SupportedTvSearchParameters.Contains(v)) &&
|
new[] { "q", "imdbid" }.Any(v => capabilities.SupportedTvSearchParameters.Contains(v)))
|
||||||
new[] { "season", "ep" }.All(v => capabilities.SupportedTvSearchParameters.Contains(v)))
|
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,7 @@ namespace NzbDrone.Core.Indexers.Torznab
|
||||||
protected override ReleaseInfo ProcessItem(XElement item, ReleaseInfo releaseInfo)
|
protected override ReleaseInfo ProcessItem(XElement item, ReleaseInfo releaseInfo)
|
||||||
{
|
{
|
||||||
var torrentInfo = base.ProcessItem(item, releaseInfo) as TorrentInfo;
|
var torrentInfo = base.ProcessItem(item, releaseInfo) as TorrentInfo;
|
||||||
|
torrentInfo.ImdbId = int.Parse(GetImdbId(item).Substring(2));
|
||||||
torrentInfo.TvdbId = GetTvdbId(item);
|
|
||||||
torrentInfo.TvRageId = GetTvRageId(item);
|
|
||||||
|
|
||||||
return torrentInfo;
|
return torrentInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,31 +97,12 @@ namespace NzbDrone.Core.Indexers.Torznab
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual int GetTvdbId(XElement item)
|
protected virtual string GetImdbId(XElement item)
|
||||||
{
|
{
|
||||||
var tvdbIdString = TryGetTorznabAttribute(item, "tvdbid");
|
var imdbIdString = TryGetTorznabAttribute(item, "imdbid");
|
||||||
int tvdbId;
|
return (!imdbIdString.IsNullOrWhiteSpace() ? imdbIdString.Substring(2) : null);
|
||||||
|
|
||||||
if (!tvdbIdString.IsNullOrWhiteSpace() && int.TryParse(tvdbIdString, out tvdbId))
|
|
||||||
{
|
|
||||||
return tvdbId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual int GetTvRageId(XElement item)
|
|
||||||
{
|
|
||||||
var tvRageIdString = TryGetTorznabAttribute(item, "rageid");
|
|
||||||
int tvRageId;
|
|
||||||
|
|
||||||
if (!tvRageIdString.IsNullOrWhiteSpace() && int.TryParse(tvRageIdString, out tvRageId))
|
|
||||||
{
|
|
||||||
return tvRageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
protected override string GetInfoHash(XElement item)
|
protected override string GetInfoHash(XElement item)
|
||||||
{
|
{
|
||||||
return TryGetTorznabAttribute(item, "infohash");
|
return TryGetTorznabAttribute(item, "infohash");
|
||||||
|
|
|
@ -178,7 +178,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
_mediaFileTableCleanupService.Clean(movie, mediaFileList);
|
_mediaFileTableCleanupService.Clean(movie, mediaFileList);
|
||||||
|
|
||||||
var decisionsStopwatch = Stopwatch.StartNew();
|
var decisionsStopwatch = Stopwatch.StartNew();
|
||||||
var decisions = _importDecisionMaker.GetImportDecisions(mediaFileList, movie);
|
var decisions = _importDecisionMaker.GetImportDecisions(mediaFileList, movie, true);
|
||||||
decisionsStopwatch.Stop();
|
decisionsStopwatch.Stop();
|
||||||
_logger.Trace("Import decisions complete for: {0} [{1}]", movie, decisionsStopwatch.Elapsed);
|
_logger.Trace("Import decisions complete for: {0} [{1}]", movie, decisionsStopwatch.Elapsed);
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), movie, folderInfo, true);
|
var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), movie, folderInfo, true, false);
|
||||||
var importResults = _importApprovedMovie.Import(decisions, true, downloadClientItem, importMode);
|
var importResults = _importApprovedMovie.Import(decisions, true, downloadClientItem, importMode);
|
||||||
|
|
||||||
if ((downloadClientItem == null || !downloadClientItem.IsReadOnly) &&
|
if ((downloadClientItem == null || !downloadClientItem.IsReadOnly) &&
|
||||||
|
@ -237,7 +237,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var decisions = _importDecisionMaker.GetImportDecisions(new List<string>() { fileInfo.FullName }, movie, null, true);
|
var decisions = _importDecisionMaker.GetImportDecisions(new List<string>() { fileInfo.FullName }, movie, null, true, false);
|
||||||
|
|
||||||
return _importApprovedMovie.Import(decisions, true, downloadClientItem, importMode);
|
return _importApprovedMovie.Import(decisions, true, downloadClientItem, importMode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
episodeFile.MediaInfo = localMovie.MediaInfo;
|
episodeFile.MediaInfo = localMovie.MediaInfo;
|
||||||
episodeFile.Movie = localMovie.Movie;
|
episodeFile.Movie = localMovie.Movie;
|
||||||
episodeFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
episodeFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
||||||
|
episodeFile.Edition = localMovie.ParsedMovieInfo.Edition;
|
||||||
|
|
||||||
bool copyOnly;
|
bool copyOnly;
|
||||||
switch (importMode)
|
switch (importMode)
|
||||||
|
|
|
@ -19,7 +19,8 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
{
|
{
|
||||||
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series);
|
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series);
|
||||||
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie);
|
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie);
|
||||||
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource); //TODO: Needs changing to ParsedMovieInfo!!
|
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, bool shouldCheckQuality);
|
||||||
|
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldCheckQuality); //TODO: Needs changing to ParsedMovieInfo!!
|
||||||
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource);
|
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IVideoFileInfoReader _videoFileInfoReader;
|
private readonly IVideoFileInfoReader _videoFileInfoReader;
|
||||||
private readonly IDetectSample _detectSample;
|
private readonly IDetectSample _detectSample;
|
||||||
|
private readonly IQualityDefinitionService _qualitiesService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public ImportDecisionMaker(IEnumerable<IImportDecisionEngineSpecification> specifications,
|
public ImportDecisionMaker(IEnumerable<IImportDecisionEngineSpecification> specifications,
|
||||||
|
@ -39,6 +41,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IVideoFileInfoReader videoFileInfoReader,
|
IVideoFileInfoReader videoFileInfoReader,
|
||||||
IDetectSample detectSample,
|
IDetectSample detectSample,
|
||||||
|
IQualityDefinitionService qualitiesService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_specifications = specifications;
|
_specifications = specifications;
|
||||||
|
@ -47,6 +50,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_videoFileInfoReader = videoFileInfoReader;
|
_videoFileInfoReader = videoFileInfoReader;
|
||||||
_detectSample = detectSample;
|
_detectSample = detectSample;
|
||||||
|
_qualitiesService = qualitiesService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +61,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie)
|
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie)
|
||||||
{
|
{
|
||||||
return GetImportDecisions(videoFiles, movie, null, false);
|
return GetImportDecisions(videoFiles, movie, null, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, bool shouldCheckQuality = false)
|
||||||
|
{
|
||||||
|
return GetImportDecisions(videoFiles, movie, null, true, shouldCheckQuality);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource)
|
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource)
|
||||||
|
@ -77,7 +86,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
return decisions;
|
return decisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource)
|
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldCheckQuality = false)
|
||||||
{
|
{
|
||||||
var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), movie);
|
var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), movie);
|
||||||
|
|
||||||
|
@ -88,13 +97,13 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
foreach (var file in newFiles)
|
foreach (var file in newFiles)
|
||||||
{
|
{
|
||||||
decisions.AddIfNotNull(GetDecision(file, movie, folderInfo, sceneSource, shouldUseFolderName));
|
decisions.AddIfNotNull(GetDecision(file, movie, folderInfo, sceneSource, shouldUseFolderName, shouldCheckQuality));
|
||||||
}
|
}
|
||||||
|
|
||||||
return decisions;
|
return decisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImportDecision GetDecision(string file, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName)
|
private ImportDecision GetDecision(string file, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName, bool shouldCheckQuality = false)
|
||||||
{
|
{
|
||||||
ImportDecision decision = null;
|
ImportDecision decision = null;
|
||||||
|
|
||||||
|
@ -113,6 +122,106 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
if (sceneSource)
|
if (sceneSource)
|
||||||
{
|
{
|
||||||
localMovie.MediaInfo = _videoFileInfoReader.GetMediaInfo(file);
|
localMovie.MediaInfo = _videoFileInfoReader.GetMediaInfo(file);
|
||||||
|
if (shouldCheckQuality)
|
||||||
|
{
|
||||||
|
var width = localMovie.MediaInfo.Width;
|
||||||
|
var current = localMovie.Quality;
|
||||||
|
var qualityName = current.Quality.Name.ToLower();
|
||||||
|
QualityModel updated = null;
|
||||||
|
if (width > 1400)
|
||||||
|
{
|
||||||
|
if (qualityName.Contains("bluray"))
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.Bluray1080p);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (qualityName.Contains("webdl"))
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.WEBDL1080p);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (qualityName.Contains("hdtv"))
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.HDTV1080p);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
var def = _qualitiesService.Get(Quality.HDTV1080p);
|
||||||
|
if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size)
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.HDTV1080p);
|
||||||
|
}
|
||||||
|
def = _qualitiesService.Get(Quality.WEBDL1080p);
|
||||||
|
if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size)
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.WEBDL1080p);
|
||||||
|
}
|
||||||
|
def = _qualitiesService.Get(Quality.Bluray1080p);
|
||||||
|
if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size)
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.Bluray1080p);
|
||||||
|
}
|
||||||
|
if (updated == null)
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.Bluray1080p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (width > 900)
|
||||||
|
{
|
||||||
|
if (qualityName.Contains("bluray"))
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.Bluray720p);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (qualityName.Contains("webdl"))
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.WEBDL720p);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (qualityName.Contains("hdtv"))
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.HDTV720p);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
var def = _qualitiesService.Get(Quality.HDTV720p);
|
||||||
|
if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size)
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.HDTV720p);
|
||||||
|
}
|
||||||
|
def = _qualitiesService.Get(Quality.WEBDL720p);
|
||||||
|
if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size)
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.WEBDL720p);
|
||||||
|
}
|
||||||
|
def = _qualitiesService.Get(Quality.Bluray720p);
|
||||||
|
if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size)
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.Bluray720p);
|
||||||
|
}
|
||||||
|
if (updated == null)
|
||||||
|
{
|
||||||
|
updated = new QualityModel(Quality.Bluray720p);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (updated != null && updated != current)
|
||||||
|
{
|
||||||
|
updated.QualitySource = QualitySource.MediaInfo;
|
||||||
|
localMovie.Quality = updated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
decision = GetDecision(localMovie);
|
decision = GetDecision(localMovie);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -161,7 +161,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
}
|
}
|
||||||
|
|
||||||
var importDecisions = _importDecisionMaker.GetImportDecisions(new List<string> { file },
|
var importDecisions = _importDecisionMaker.GetImportDecisions(new List<string> { file },
|
||||||
movie, null, SceneSource(movie, folder));
|
movie, null, SceneSource(movie, folder), true);
|
||||||
|
|
||||||
return importDecisions.Any() ? MapItem(importDecisions.First(), folder, downloadId) : null;
|
return importDecisions.Any() ? MapItem(importDecisions.First(), folder, downloadId) : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
List<string> FilterExistingFiles(List<string> files, Series series);
|
List<string> FilterExistingFiles(List<string> files, Series series);
|
||||||
List<string> FilterExistingFiles(List<string> files, Movie movie);
|
List<string> FilterExistingFiles(List<string> files, Movie movie);
|
||||||
EpisodeFile Get(int id);
|
EpisodeFile Get(int id);
|
||||||
|
MovieFile GetMovie(int id);
|
||||||
List<EpisodeFile> Get(IEnumerable<int> ids);
|
List<EpisodeFile> Get(IEnumerable<int> ids);
|
||||||
List<MovieFile> GetMovies(IEnumerable<int> ids);
|
List<MovieFile> GetMovies(IEnumerable<int> ids);
|
||||||
|
|
||||||
|
@ -150,5 +151,9 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
_movieFileRepository.Update(episodeFile);
|
_movieFileRepository.Update(episodeFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MovieFile GetMovie(int id)
|
||||||
|
{
|
||||||
|
return _movieFileRepository.Get(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public MediaInfoModel MediaInfo { get; set; }
|
public MediaInfoModel MediaInfo { get; set; }
|
||||||
|
public string Edition { get; set; }
|
||||||
public LazyLoaded<Movie> Movie { get; set; }
|
public LazyLoaded<Movie> Movie { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
||||||
public Production_Companies[] production_companies { get; set; }
|
public Production_Companies[] production_companies { get; set; }
|
||||||
public Production_Countries[] production_countries { get; set; }
|
public Production_Countries[] production_countries { get; set; }
|
||||||
public string release_date { get; set; }
|
public string release_date { get; set; }
|
||||||
public int revenue { get; set; }
|
public long revenue { get; set; }
|
||||||
public int runtime { get; set; }
|
public int runtime { get; set; }
|
||||||
public Spoken_Languages[] spoken_languages { get; set; }
|
public Spoken_Languages[] spoken_languages { get; set; }
|
||||||
public string status { get; set; }
|
public string status { get; set; }
|
||||||
|
|
|
@ -13,6 +13,7 @@ using NzbDrone.Core.MetadataSource;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook
|
namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
{
|
{
|
||||||
|
@ -88,8 +89,9 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
movie.TmdbId = TmdbId;
|
movie.TmdbId = TmdbId;
|
||||||
movie.ImdbId = resource.imdb_id;
|
movie.ImdbId = resource.imdb_id;
|
||||||
movie.Title = resource.title;
|
movie.Title = resource.title;
|
||||||
movie.TitleSlug = movie.Title.ToLower().Replace(" ", "-");
|
movie.TitleSlug = ToUrlSlug(movie.Title);
|
||||||
movie.CleanTitle = Parser.Parser.CleanSeriesTitle(movie.Title);
|
movie.CleanTitle = Parser.Parser.CleanSeriesTitle(movie.Title);
|
||||||
|
movie.SortTitle = Parser.Parser.NormalizeTitle(movie.Title);
|
||||||
movie.Overview = resource.overview;
|
movie.Overview = resource.overview;
|
||||||
movie.Website = resource.homepage;
|
movie.Website = resource.homepage;
|
||||||
if (resource.release_date.IsNotNullOrWhiteSpace())
|
if (resource.release_date.IsNotNullOrWhiteSpace())
|
||||||
|
@ -98,11 +100,6 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
movie.Year = movie.InCinemas.Value.Year;
|
movie.Year = movie.InCinemas.Value.Year;
|
||||||
}
|
}
|
||||||
|
|
||||||
var slugResult = _movieService.FindByTitleSlug(movie.TitleSlug);
|
|
||||||
if (slugResult != null)
|
|
||||||
{
|
|
||||||
_logger.Debug("Movie with this title slug already exists. Adding year...");
|
|
||||||
}
|
|
||||||
movie.TitleSlug += "-" + movie.Year.ToString();
|
movie.TitleSlug += "-" + movie.Year.ToString();
|
||||||
|
|
||||||
movie.Images.Add(_configService.GetCoverForURL(resource.poster_path, MediaCoverTypes.Poster));//TODO: Update to load image specs from tmdb page!
|
movie.Images.Add(_configService.GetCoverForURL(resource.poster_path, MediaCoverTypes.Poster));//TODO: Update to load image specs from tmdb page!
|
||||||
|
@ -189,7 +186,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
{
|
{
|
||||||
var lowerTitle = title.ToLower();
|
var lowerTitle = title.ToLower();
|
||||||
|
|
||||||
var parserResult = Parser.Parser.ParseMovieTitle(title);
|
var parserResult = Parser.Parser.ParseMovieTitle(title, true);
|
||||||
|
|
||||||
var yearTerm = "";
|
var yearTerm = "";
|
||||||
|
|
||||||
|
@ -327,23 +324,20 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
imdbMovie.TmdbId = result.id;
|
imdbMovie.TmdbId = result.id;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
imdbMovie.SortTitle = result.title;
|
imdbMovie.SortTitle = Parser.Parser.NormalizeTitle(result.title);
|
||||||
imdbMovie.Title = result.title;
|
imdbMovie.Title = result.title;
|
||||||
string titleSlug = result.title;
|
string titleSlug = ToUrlSlug(result.title);
|
||||||
imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-");
|
imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-");
|
||||||
|
|
||||||
if (result.release_date.IsNotNullOrWhiteSpace())
|
if (result.release_date.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
imdbMovie.Year = DateTime.Parse(result.release_date).Year;
|
imdbMovie.Year = DateTime.Parse(result.release_date).Year;
|
||||||
}
|
}
|
||||||
|
//var slugResult = _movieService.FindByTitleSlug(imdbMovie.TitleSlug);
|
||||||
|
//if (slugResult != null)
|
||||||
|
//{
|
||||||
var slugResult = _movieService.FindByTitleSlug(imdbMovie.TitleSlug);
|
// _logger.Debug("Movie with this title slug already exists. Adding year...");
|
||||||
if (slugResult != null)
|
//}
|
||||||
{
|
|
||||||
_logger.Debug("Movie with this title slug already exists. Adding year...");
|
|
||||||
}
|
|
||||||
imdbMovie.TitleSlug += "-" + imdbMovie.Year.ToString();
|
imdbMovie.TitleSlug += "-" + imdbMovie.Year.ToString();
|
||||||
|
|
||||||
imdbMovie.Images = new List<MediaCover.MediaCover>();
|
imdbMovie.Images = new List<MediaCover.MediaCover>();
|
||||||
|
@ -524,5 +518,29 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
return MediaCoverTypes.Unknown;
|
return MediaCoverTypes.Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string subject = "Sonarr [TV] - Grabbed";
|
const string subject = "Radarr [TV] - Grabbed";
|
||||||
var body = string.Format("{0} sent to queue.", grabMessage.Message);
|
var body = string.Format("{0} sent to queue.", grabMessage.Message);
|
||||||
|
|
||||||
_emailService.SendEmail(Settings, subject, body);
|
_emailService.SendEmail(Settings, subject, body);
|
||||||
|
@ -26,7 +26,7 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string subject = "Sonarr [TV] - Downloaded";
|
const string subject = "Radarr [TV] - Downloaded";
|
||||||
var body = string.Format("{0} Downloaded and sorted.", message.Message);
|
var body = string.Format("{0} Downloaded and sorted.", message.Message);
|
||||||
|
|
||||||
_emailService.SendEmail(Settings, subject, body);
|
_emailService.SendEmail(Settings, subject, body);
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SendEmail(settings, "Sonarr - Test Notification", body);
|
SendEmail(settings, "Radarr - Test Notification", body);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,14 +18,14 @@ namespace NzbDrone.Core.Notifications.Join
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Sonarr - Episode Grabbed";
|
const string title = "Radarr - Episode Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Sonarr - Episode Downloaded";
|
const string title = "Radarr - Episode Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Sonarr - Grabbed";
|
const string title = "Radarr - Grabbed";
|
||||||
|
|
||||||
if (Settings.Notify)
|
if (Settings.Notify)
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Sonarr - Downloaded";
|
const string title = "Radarr - Downloaded";
|
||||||
|
|
||||||
if (Settings.Notify)
|
if (Settings.Notify)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,13 +18,13 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string header = "Sonarr [TV] - Grabbed";
|
const string header = "Radarr [TV] - Grabbed";
|
||||||
_plexClientService.Notify(Settings, header, grabMessage.Message);
|
_plexClientService.Notify(Settings, header, grabMessage.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string header = "Sonarr [TV] - Downloaded";
|
const string header = "Radarr [TV] - Downloaded";
|
||||||
_plexClientService.Notify(Settings, header, message.Message);
|
_plexClientService.Notify(Settings, header, message.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,14 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string header = "Sonarr - Grabbed";
|
const string header = "Radarr - Grabbed";
|
||||||
|
|
||||||
Notify(Settings, header, grabMessage.Message);
|
Notify(Settings, header, grabMessage.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string header = "Sonarr - Downloaded";
|
const string header = "Radarr - Downloaded";
|
||||||
|
|
||||||
Notify(Settings, header, message.Message);
|
Notify(Settings, header, message.Message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
if (version >= new Version(1, 3, 0) && version < new Version(1, 3, 1))
|
if (version >= new Version(1, 3, 0) && version < new Version(1, 3, 1))
|
||||||
{
|
{
|
||||||
throw new PlexVersionException("Found version {0}, upgrade to PMS 1.3.1 to fix library updating and then restart Sonarr", version);
|
throw new PlexVersionException("Found version {0}, upgrade to PMS 1.3.1 to fix library updating and then restart Radarr", version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,14 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Sonarr - Episode Grabbed";
|
const string title = "Radarr - Episode Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Sonarr - Episode Downloaded";
|
const string title = "Radarr - Episode Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const string title = "Sonarr - Test Notification";
|
const string title = "Radarr - Test Notification";
|
||||||
const string body = "This is a test message from Radarr";
|
const string body = "This is a test message from Radarr";
|
||||||
|
|
||||||
SendNotification(title, body, settings);
|
SendNotification(title, body, settings);
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.Pushalot
|
||||||
[FieldDefinition(1, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(PushalotPriority))]
|
[FieldDefinition(1, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(PushalotPriority))]
|
||||||
public int Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Image", Type = FieldType.Checkbox, HelpText = "Include Sonarr logo with notifications")]
|
[FieldDefinition(2, Label = "Image", Type = FieldType.Checkbox, HelpText = "Include Radarr logo with notifications")]
|
||||||
public bool Image { get; set; }
|
public bool Image { get; set; }
|
||||||
|
|
||||||
public bool IsValid => !string.IsNullOrWhiteSpace(AuthToken);
|
public bool IsValid => !string.IsNullOrWhiteSpace(AuthToken);
|
||||||
|
|
|
@ -101,7 +101,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var message = $"Test message from Sonarr posted at {DateTime.Now}";
|
var message = $"Test message from Radarr posted at {DateTime.Now}";
|
||||||
var payload = new SlackPayload
|
var payload = new SlackPayload
|
||||||
{
|
{
|
||||||
IconEmoji = Settings.Icon,
|
IconEmoji = Settings.Icon,
|
||||||
|
|
|
@ -125,7 +125,7 @@ namespace NzbDrone.Core.Notifications.Twitter
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var body = "Sonarr: Test Message @ " + DateTime.Now;
|
var body = "Radarr: Test Message @ " + DateTime.Now;
|
||||||
|
|
||||||
SendNotification(body, settings);
|
SendNotification(body, settings);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,14 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string header = "Sonarr - Grabbed";
|
const string header = "Radarr - Grabbed";
|
||||||
|
|
||||||
Notify(Settings, header, grabMessage.Message);
|
Notify(Settings, header, grabMessage.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string header = "Sonarr - Downloaded";
|
const string header = "Radarr - Downloaded";
|
||||||
|
|
||||||
Notify(Settings, header, message.Message);
|
Notify(Settings, header, message.Message);
|
||||||
UpdateAndClean(message.Series, message.OldFiles.Any());
|
UpdateAndClean(message.Series, message.OldFiles.Any());
|
||||||
|
|
|
@ -193,6 +193,10 @@
|
||||||
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
||||||
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
||||||
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\118_update_movie_slug.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\117_update_movie_file.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\116_update_movie_sorttitle_again.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\115_update_movie_sorttitle.cs" />
|
||||||
<Compile Include="Datastore\Migration\111_remove_bitmetv.cs" />
|
<Compile Include="Datastore\Migration\111_remove_bitmetv.cs" />
|
||||||
<Compile Include="Datastore\Migration\112_remove_torrentleech.cs" />
|
<Compile Include="Datastore\Migration\112_remove_torrentleech.cs" />
|
||||||
<Compile Include="Datastore\Migration\114_remove_fanzub.cs" />
|
<Compile Include="Datastore\Migration\114_remove_fanzub.cs" />
|
||||||
|
@ -587,6 +591,7 @@
|
||||||
<Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" />
|
<Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" />
|
||||||
<Compile Include="IndexerSearch\MoviesSearchCommand.cs" />
|
<Compile Include="IndexerSearch\MoviesSearchCommand.cs" />
|
||||||
<Compile Include="IndexerSearch\MoviesSearchService.cs" />
|
<Compile Include="IndexerSearch\MoviesSearchService.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDRssParser.cs" />
|
||||||
<Compile Include="Indexers\DownloadProtocol.cs" />
|
<Compile Include="Indexers\DownloadProtocol.cs" />
|
||||||
<Compile Include="Indexers\Exceptions\ApiKeyException.cs" />
|
<Compile Include="Indexers\Exceptions\ApiKeyException.cs" />
|
||||||
<Compile Include="Indexers\Exceptions\IndexerException.cs" />
|
<Compile Include="Indexers\Exceptions\IndexerException.cs" />
|
||||||
|
@ -594,6 +599,10 @@
|
||||||
<Compile Include="Indexers\Exceptions\UnsupportedFeedException.cs" />
|
<Compile Include="Indexers\Exceptions\UnsupportedFeedException.cs" />
|
||||||
<Compile Include="Indexers\EzrssTorrentRssParser.cs" />
|
<Compile Include="Indexers\EzrssTorrentRssParser.cs" />
|
||||||
<Compile Include="Indexers\FetchAndParseRssService.cs" />
|
<Compile Include="Indexers\FetchAndParseRssService.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHD.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDApi.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDRequestGenerator.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDSettings.cs" />
|
||||||
<Compile Include="Indexers\PassThePopcorn\PassThePopcorn.cs" />
|
<Compile Include="Indexers\PassThePopcorn\PassThePopcorn.cs" />
|
||||||
<Compile Include="Indexers\PassThePopcorn\PassThePopcornApi.cs" />
|
<Compile Include="Indexers\PassThePopcorn\PassThePopcornApi.cs" />
|
||||||
<Compile Include="Indexers\PassThePopcorn\PassThePopcornInfo.cs" />
|
<Compile Include="Indexers\PassThePopcorn\PassThePopcornInfo.cs" />
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace NzbDrone.Core.Organizer
|
||||||
public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})",
|
public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{(?:Movie)(?<separator>[- ._])(Clean)?Title\})",
|
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{((?:(Movie|Original))(?<separator>[- ._])(Clean)?Title)\})",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled);
|
private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled);
|
||||||
|
@ -163,6 +163,7 @@ namespace NzbDrone.Core.Organizer
|
||||||
AddReleaseDateTokens(tokenHandlers, movie.Year); //In case we want to separate the year
|
AddReleaseDateTokens(tokenHandlers, movie.Year); //In case we want to separate the year
|
||||||
AddQualityTokens(tokenHandlers, movie, movieFile);
|
AddQualityTokens(tokenHandlers, movie, movieFile);
|
||||||
AddMediaInfoTokens(tokenHandlers, movieFile);
|
AddMediaInfoTokens(tokenHandlers, movieFile);
|
||||||
|
AddMovieFileTokens(tokenHandlers, movieFile);
|
||||||
|
|
||||||
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
|
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
|
||||||
fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString());
|
fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString());
|
||||||
|
@ -503,6 +504,13 @@ namespace NzbDrone.Core.Organizer
|
||||||
tokenHandlers["{Release Group}"] = m => episodeFile.ReleaseGroup ?? m.DefaultValue("Sonarr");
|
tokenHandlers["{Release Group}"] = m => episodeFile.ReleaseGroup ?? m.DefaultValue("Sonarr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddMovieFileTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, MovieFile episodeFile)
|
||||||
|
{
|
||||||
|
tokenHandlers["{Original Title}"] = m => GetOriginalTitle(episodeFile);
|
||||||
|
tokenHandlers["{Original Filename}"] = m => GetOriginalFileName(episodeFile);
|
||||||
|
tokenHandlers["{Release Group}"] = m => episodeFile.ReleaseGroup ?? m.DefaultValue("Sonarr");
|
||||||
|
}
|
||||||
|
|
||||||
private void AddQualityTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Series series, EpisodeFile episodeFile)
|
private void AddQualityTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Series series, EpisodeFile episodeFile)
|
||||||
{
|
{
|
||||||
var qualityTitle = _qualityDefinitionService.Get(episodeFile.Quality.Quality).Title;
|
var qualityTitle = _qualityDefinitionService.Get(episodeFile.Quality.Quality).Title;
|
||||||
|
|
|
@ -18,16 +18,10 @@ namespace NzbDrone.Core.Parser
|
||||||
private static readonly Regex[] ReportMovieTitleRegex = new[]
|
private static readonly Regex[] ReportMovieTitleRegex = new[]
|
||||||
{
|
{
|
||||||
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.Special.Edition.2011
|
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.Special.Edition.2011
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<edition>(\w+\.?edition))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<edition>(\.?((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX)))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.2011.Special.Edition //TODO: Seems to slow down parsing heavily!
|
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.2011.Special.Edition //TODO: Seems to slow down parsing heavily!
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((\w+\.?){1,3}edition))",
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX))",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
||||||
//Cut Movies, e.g: Mission.Impossible.3.Directors.Cut.2011
|
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<edition>(\w+\.?cut))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
||||||
//Cut Movies, e.g: Mission.Impossible.3.2011.Directors.Cut
|
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((\w+\.?){1,3}cut))",
|
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Normal movie format, e.g: Mission.Impossible.3.2011
|
//Normal movie format, e.g: Mission.Impossible.3.2011
|
||||||
|
@ -36,6 +30,15 @@ namespace NzbDrone.Core.Parser
|
||||||
//PassThePopcorn Torrent names: Star.Wars[PassThePopcorn]
|
//PassThePopcorn Torrent names: Star.Wars[PassThePopcorn]
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(\[\w *\])))+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(\[\w *\])))+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
//That did not work? Maybe some tool uses [] for years. Who would do that?
|
||||||
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Regex[] ReportMovieTitleFolderRegex = new[]
|
||||||
|
{
|
||||||
|
//When year comes first.
|
||||||
|
new Regex(@"^(?:(?:[-_\W](?<![)!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\W\d+)))+(\W+|_|$)(?<title>.+?)?$")
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Regex[] ReportTitleRegex = new[]
|
private static readonly Regex[] ReportTitleRegex = new[]
|
||||||
|
@ -327,7 +330,7 @@ namespace NzbDrone.Core.Parser
|
||||||
{
|
{
|
||||||
var fileInfo = new FileInfo(path);
|
var fileInfo = new FileInfo(path);
|
||||||
|
|
||||||
var result = ParseMovieTitle(fileInfo.Name);
|
var result = ParseMovieTitle(fileInfo.Name, true);
|
||||||
|
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
|
@ -345,7 +348,7 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ParsedMovieInfo ParseMovieTitle(string title)
|
public static ParsedMovieInfo ParseMovieTitle(string title, bool isDir = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
ParsedMovieInfo realResult = null;
|
ParsedMovieInfo realResult = null;
|
||||||
|
@ -376,7 +379,14 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
simpleTitle = CleanTorrentSuffixRegex.Replace(simpleTitle, string.Empty);
|
simpleTitle = CleanTorrentSuffixRegex.Replace(simpleTitle, string.Empty);
|
||||||
|
|
||||||
foreach (var regex in ReportMovieTitleRegex)
|
var allRegexes = ReportMovieTitleRegex.ToList();
|
||||||
|
|
||||||
|
if (isDir)
|
||||||
|
{
|
||||||
|
allRegexes.AddRange(ReportMovieTitleFolderRegex);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var regex in allRegexes)
|
||||||
{
|
{
|
||||||
var match = regex.Matches(simpleTitle);
|
var match = regex.Matches(simpleTitle);
|
||||||
|
|
||||||
|
|
|
@ -44,14 +44,14 @@ namespace NzbDrone.Core.Queue
|
||||||
|
|
||||||
private IEnumerable<Queue> MapQueue(TrackedDownload trackedDownload)
|
private IEnumerable<Queue> MapQueue(TrackedDownload trackedDownload)
|
||||||
{
|
{
|
||||||
if (trackedDownload.RemoteEpisode.Episodes != null && trackedDownload.RemoteEpisode.Episodes.Any())
|
if (trackedDownload.RemoteEpisode != null && trackedDownload.RemoteEpisode.Episodes != null && trackedDownload.RemoteEpisode.Episodes.Any())
|
||||||
{
|
{
|
||||||
foreach (var episode in trackedDownload.RemoteEpisode.Episodes)
|
foreach (var episode in trackedDownload.RemoteEpisode.Episodes)
|
||||||
{
|
{
|
||||||
yield return MapEpisode(trackedDownload, episode);
|
yield return MapEpisode(trackedDownload, episode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (trackedDownload.RemoteMovie.Movie != null)
|
else if (trackedDownload.RemoteMovie != null && trackedDownload.RemoteMovie.Movie != null)
|
||||||
{
|
{
|
||||||
yield return MapMovie(trackedDownload, trackedDownload.RemoteMovie.Movie);
|
yield return MapMovie(trackedDownload, trackedDownload.RemoteMovie.Movie);
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,11 @@ namespace NzbDrone.Core.RootFolders
|
||||||
foreach (string unmappedFolder in unmappedFolders)
|
foreach (string unmappedFolder in unmappedFolders)
|
||||||
{
|
{
|
||||||
var di = new DirectoryInfo(unmappedFolder.Normalize());
|
var di = new DirectoryInfo(unmappedFolder.Normalize());
|
||||||
results.Add(new UnmappedFolder { Name = di.Name, Path = di.FullName });
|
if (!di.Attributes.HasFlag(FileAttributes.System) && !di.Attributes.HasFlag(FileAttributes.Hidden))
|
||||||
|
{
|
||||||
|
results.Add(new UnmappedFolder { Name = di.Name, Path = di.FullName });
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var setToRemove = SpecialFolders;
|
var setToRemove = SpecialFolders;
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace Radarr.Host
|
||||||
SecurityProtocolPolicy.Register();
|
SecurityProtocolPolicy.Register();
|
||||||
X509CertificateValidationPolicy.Register();
|
X509CertificateValidationPolicy.Register();
|
||||||
|
|
||||||
Logger.Info("Starting Sonarr - {0} - Version {1}", Assembly.GetCallingAssembly().Location, Assembly.GetExecutingAssembly().GetName().Version);
|
Logger.Info("Starting Radarr - {0} - Version {1}", Assembly.GetCallingAssembly().Location, Assembly.GetExecutingAssembly().GetName().Version);
|
||||||
|
|
||||||
if (!PlatformValidation.IsValidate(userAlert))
|
if (!PlatformValidation.IsValidate(userAlert))
|
||||||
{
|
{
|
||||||
|
|
Binary file not shown.
BIN
src/Thumbs.db
BIN
src/Thumbs.db
Binary file not shown.
|
@ -91,7 +91,7 @@
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
|
|
||||||
{{#if_eq reason compare="MissingFromDisk"}}
|
{{#if_eq reason compare="MissingFromDisk"}}
|
||||||
Sonarr was unable to find the file on disk so it was removed
|
Radarr was unable to find the file on disk so it was removed
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
|
|
||||||
{{#if_eq reason compare="Upgrade"}}
|
{{#if_eq reason compare="Upgrade"}}
|
||||||
|
|
|
@ -1,18 +1,6 @@
|
||||||
<dl class="monitor-tooltip-contents">
|
<dl class="monitor-tooltip-contents">
|
||||||
<dt>All</dt>
|
<dt>Yes</dt>
|
||||||
<dd>Monitor all episodes except specials</dd>
|
<dd>Monitor for new releases</dd>
|
||||||
<dt>Future</dt>
|
<dt>No</dt>
|
||||||
<dd>Monitor episodes that have not aired yet</dd>
|
<dd>Do not monitor for new releases</dd>
|
||||||
<dt>Missing</dt>
|
|
||||||
<dd>Monitor episodes that do not have files or have not aired yet</dd>
|
|
||||||
<dt>Existing</dt>
|
|
||||||
<dd>Monitor episodes that have files or have not aired yet</dd>
|
|
||||||
<dt>First Season</dt>
|
|
||||||
<dd>Monitor all episodes of the first season. All other seasons will be ignored</dd>
|
|
||||||
<dt>Latest Season</dt>
|
|
||||||
<dd>Monitor all episodes of the latest season and future seasons</dd>
|
|
||||||
<dt>None</dt>
|
|
||||||
<dd>No episodes will be monitored.</dd>
|
|
||||||
<!--<dt>Latest Season</dt>-->
|
|
||||||
<!--<dd>Monitor all episodes the latest season only, previous seasons will be ignored</dd>-->
|
|
||||||
</dl>
|
</dl>
|
|
@ -84,7 +84,7 @@ var view = Marionette.ItemView.extend({
|
||||||
content : content,
|
content : content,
|
||||||
html : true,
|
html : true,
|
||||||
trigger : 'hover',
|
trigger : 'hover',
|
||||||
title : 'Episode Monitoring Options',
|
title : 'Movie Monitoring Options',
|
||||||
placement : 'right',
|
placement : 'right',
|
||||||
container : this.$el
|
container : this.$el
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
<h3>Sonarr Calendar feed</h3>
|
<h3>Radarr Calendar feed</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body edit-series-modal">
|
<div class="modal-body edit-series-modal">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue