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

Compare commits

...

126 Commits

Author SHA1 Message Date
Devin Buhl 1112616514 Merge pull request #434 from Radarr/patch/dumb-metadata-erros
"fixed" error message
2017-01-24 17:35:27 -05:00
Devin Buhl 7fddbca4b7 "fixed" error message 2017-01-24 17:29:07 -05:00
Tim Turner 692841478c Add link to Activity -> History Tab (#408)
Fixes #365
2017-01-24 16:12:58 -05:00
Tim Turner 23232b9830 Allow renaming of movies that don't have an "Edition" (#432)
Fixes #405
2017-01-24 16:08:06 -05:00
Leonardo Galli b886566b25 Update README.md 2017-01-24 21:30:24 +01:00
Devin Buhl 2c56d60678 #292 - Allow longer threshold for RSS Sync (#428)
* #292 - Allow longer threshold for RSS Sync

Update RSS Sync interval default to 60 minutes, and don't allow values below 60 or higher than 720 minutes (12 hours)

* allow minimum of 10 mintes
2017-01-24 21:26:51 +01:00
hotio a0c8127ecf Update to favicon section, according to (#416)
* Update to favicon section, according to

http://realfavicongenerator.net/

* Windows start not as expected

* re-add msapplication-navbutton-color
2017-01-24 21:23:42 +01:00
Devin Buhl 05f61df59e update default sort order (#429)
#426
2017-01-24 21:16:22 +01:00
Devin Buhl a0b80ad41a Add year to search (#425)
#417
2017-01-24 20:17:35 +01:00
vertigo235 9e7cb708bf Initial Notification Updates and Support (#401)
* Bare bones of notifications working.

* Add MovieDownload event handler

To allow Download notificaitons

* Update pushover text to indicate movie

* Initial Notification Support

On Download and On Grab notifications should work.

* Telegram Notification Text

* Update Custom Script For Movies

* Update PP script WiKi page

Also added wiki page to Radarr wiki.
2017-01-24 20:17:24 +01:00
Leonardo Galli 1ad4006819 Fixes an issue where movies with (year) at the beginning were recognized with a title of "(" 2017-01-24 10:02:20 +01:00
Leonardo Galli 5339f8efdc Blind fix to support seperator in movie tags. 2017-01-23 22:34:16 +01:00
Leonardo Galli b273bfb10e Fix issue with certain audio streams. Should fix #404 2017-01-23 22:04:49 +01:00
Leonardo Galli b2317ada1f Add {Tags} to renaming options 2017-01-23 18:52:27 +01:00
Leonardo Galli 336aee7fda Fix when libgdiplus isn't present. 2017-01-23 18:42:05 +01:00
Leonardo Galli 9e7468d723 Merged branch develop into develop 2017-01-23 16:09:19 +01:00
Leonardo Galli f05ee13206 Fix issue where monitored movies were still downloaded. Fixes #326 2017-01-23 16:09:11 +01:00
Devin Buhl 2b579eb0d3 Merge pull request #385 from hotio/ui-logos
Ui logos
2017-01-22 23:21:23 -05:00
hotio 791121fa06 Proper ico and favicon 2017-01-22 23:32:01 +01:00
Leonardo Galli f0bcb27beb Fixes issue when multiple audio channels are present. Fixes #315 Fixes #294 2017-01-22 23:11:05 +01:00
Tim Turner ec6b389d75 Fix duplicate key prefixing 2017-01-22 16:59:53 -05:00
Tim Turner f38430d632 Update localstorage key prefixes 2017-01-22 16:24:22 -05:00
Tim Turner 266f28883a Prefix localstorage keys with "Radarr"
Updates #285
2017-01-22 15:54:41 -05:00
hotio cc3c2533fa Updated ico files 2017-01-22 21:31:20 +01:00
hotio f8162b34f2 Update UI logos 2017-01-22 21:07:12 +01:00
hotio 309877bf76 Optimized logo (#375)
* Optimized logo
Inkscape compatible SVG Honeycomb is slightly different)
File size optimized PNG's (446kB->163kB)

* Use Sonarr honeycomb and proper id's for future use
New png's included

* And final fixes are done
2017-01-22 13:33:33 -05:00
Leonardo Galli a50b20a397 Set update interval to 30 minutes if on nightly 2017-01-22 18:24:47 +01:00
Leonardo Galli de5489ae9a Merged branch develop into develop 2017-01-22 18:18:26 +01:00
Leonardo Galli 12e74aa38b Change Forms Auth Cookie. Fixes #285 2017-01-22 18:18:15 +01:00
Tim Turner 80ec66b47c Prefix Keys with "Radarr"
Makes progress on #285
2017-01-22 10:09:10 -05:00
Devin Buhl 585fd87ad6 Merge pull request #378 from Radarr/patch/add-more-filters
Add more filter options to movie list
2017-01-22 05:38:21 -05:00
Devin Buhl ec5161e848 Add more filter options to movie list 2017-01-22 04:58:04 -05:00
Devin Buhl 0ec54daaff Merge pull request #373 from baltoaca/develop
search selected button in wanted tab works
2017-01-21 19:27:00 -05:00
Tim Turner 3ed1bebb7d Fix #228 - Fix Drone Factory interval input not saving 2017-01-21 18:06:10 -05:00
Vlad Ilies 29ae088a3d search selected button in wanted tab works
* switched MoviesSearchCommand to a list of id's

* adapted the MovieSearchService

* adapted UI files to use the new command
2017-01-21 23:43:58 +02:00
Leonardo Galli eb299ce847 Fix Corruped Media Cover Images. 2017-01-21 12:57:04 +01:00
Leonardo Galli a7e071318b Update README.md 2017-01-21 10:47:11 +01:00
Leonardo Galli 3d67f6237e Should fix 4K releases not getting parsed. 2017-01-21 00:39:44 +01:00
Krystian Charubin a691ffa7b7 adds 'Movie Title, The' filename option (#359)
* adds 'Movie Title, The' filename option
* updates the FileNameBuilder.MovieTitleRegex to include new format
2017-01-20 17:42:14 -05:00
Leonardo Galli aa9537c201 Fix issue when movie file is null. 2017-01-20 20:30:36 +01:00
Leonardo Galli a3d9fb1c20 Should fix upgrading of existing movie files. 2017-01-20 18:26:18 +01:00
Leonardo Galli 62a1e70c86 Add tests for 4K quality. 2017-01-20 18:21:31 +01:00
Leonardo Galli 93d0d21846 Hopefully a fix for corrupt media covers. 2017-01-20 18:06:58 +01:00
Leonardo Galli b1c5a3ac14 Fixed blacklist being ignored by download decision maker. 2017-01-20 17:48:47 +01:00
vertigo235 55a525ba2f Add helptext to nzbget "add paused" settings. (#363)
Requires nzbget 16 or greater.
2017-01-20 09:14:15 -05:00
Devin Buhl a53768463b Merge pull request #358 from Radarr/patch/add-year-to-search
add year to search
2017-01-19 20:07:33 -05:00
Tim Turner 24cbd6bcef Fix issue with reimporting on movie fresh (#357)
Fixes #314. Still have multiple movieFiles issue to clean up.
2017-01-19 19:58:57 -05:00
Devin Buhl 3ab3e66853 Add year to quick search results 2017-01-19 19:56:26 -05:00
Leonardo Galli 40ca469339 Update MovieModule 2017-01-20 00:00:12 +01:00
Tim Turner 2cbd2f719f Merge branch 'develop' of https://github.com/Radarr/Radarr into develop 2017-01-19 16:45:39 -05:00
Tim Turner 53cbfa803b Fix MediaCoversUpdatedEvent broadcast
Cleans exception when updating media covers expects a series Id.
2017-01-19 16:45:29 -05:00
Leonardo Galli c0b0310bbd Update ISSUE_TEMPLATE.md 2017-01-19 22:10:59 +01:00
Devin Buhl 30e50062a8 Merge pull request #352 from baltoaca/develop
bug fix for 15 movie wanted tab limit
2017-01-19 13:17:40 -05:00
Vlad Ilies 85fd8f2c65 bug fix for 15 movie wanted tab (#348) 2017-01-19 20:08:15 +02:00
Leonardo Galli f72b042d5d Blacklisting works now. 2017-01-19 17:43:23 +01:00
Leonardo Galli 2d3a3a0677 Update sizing information in settings tab. 2017-01-19 17:40:25 +01:00
Tim Turner 2bb21fedab Update height of posters to accomodate additional labels 2017-01-18 17:24:32 -05:00
vertigo235 91c820f98b Fix pushover priority values. 2017-01-18 23:16:57 +01:00
Leonardo Galli 7d3118aece Hopefully fix issue when importing
existing scene named movies
2017-01-18 23:02:05 +01:00
Tim Turner 4f4ad77ad1 Add download status to poster view
Fixes #319
2017-01-18 16:54:17 -05:00
Leonardo Galli 42f205a731 Update SkyHookProxy.cs 2017-01-18 22:50:12 +01:00
Devin Buhl cbb2b778a6 Merge pull request #336 from Radarr/patch/add-imdb-to-naming
Add IMDb ID to file naming
2017-01-18 15:11:16 -05:00
Devin Buhl b3e03a648d Add IMDb ID to file naming 2017-01-18 14:53:29 -05:00
Devin Buhl acf45a79e8 Merge pull request #333 from baltoaca/develop
basic implementation of the wanted tab
2017-01-18 14:36:48 -05:00
Devin Buhl b5d8ac852e Merge pull request #335 from Radarr/patch/task-updates
Turn off scene mapping task #329, update TaskManager to use 'DownloadedMovieScanCommand
2017-01-18 14:36:29 -05:00
Vlad Ilies 4aec0e8fc6 fixed build 2017-01-18 21:09:00 +02:00
Devin Buhl ecea417fd8 Revert DownloadedMovieScanCommand to DownloadedEpisodesScanCommand
Not sure if it will break anything so putting it back.
2017-01-18 14:07:51 -05:00
Devin Buhl 6a41f6a435 Turn off scene mapping task #329, update TaskManager to use 'DownloadedMovieScanCommand' 2017-01-18 14:02:04 -05:00
Vlad Ilies da2d075aa8 basic implementation of the wanted tab (#31)
* top buttons don't yet work

* new missing module for movies

*  find missing movies method to movie service

* new movie status cell with text

* adapted UI missing collection and layout
2017-01-18 20:53:17 +02:00
Devin Buhl 10dc3993df Merge pull request #332 from Radarr/revert-318-sonarr/sqlite-updates
Revert "Sonarr/sqlite updates"
2017-01-18 13:33:46 -05:00
Devin Buhl 7e5020db9a Merge pull request #331 from vertigo235/nzbgetaddpaused
Nzbgetaddpaused
2017-01-18 13:20:12 -05:00
Devin Buhl c48fe9de12 Revert "Sonarr/sqlite updates" 2017-01-18 13:17:35 -05:00
vertigo235 421e827a95 Update Test Files for AddPaused to NZBGET 2017-01-18 13:08:59 -05:00
vertigo235 34d8045cf4 Add "Add Paused" option for NZBGET downloader
Adds option to pause nzbs uppon sending to NZBGET downloader.
2017-01-18 12:42:33 -05:00
Devin Buhl c6de163748 Merge pull request #318 from Radarr/sonarr/sqlite-updates
Sonarr/sqlite updates
2017-01-17 18:59:11 -05:00
Keivan Beigi d9e2b22e74 Upgraded System.Data.SQLite to 1.0.104.0 2017-01-17 18:45:23 -05:00
Keivan Beigi 65c0137964 Revert "Upgraded System.Data.SQLite to 1.0.104.0"
This reverts commit a6f3ac219d61964f1b923cfd89382f94c4c74243.
2017-01-17 18:44:37 -05:00
Keivan ae19424ce7 New: Upgraded SQLite binares for macOS
Upgraded from 3.8.1 to 3.9.1
2017-01-17 18:41:11 -05:00
Keivan Beigi 7527ec52b7 New: Upgraded SQLite binaries for Windows (3.16.0) 2017-01-17 18:41:05 -05:00
Leonardo Galli 640fcf3eaf Remove series references 2017-01-17 23:57:04 +01:00
Leonardo Galli 3ce8232777 Hopefully fix download ordering. 2017-01-17 23:30:11 +01:00
Devin Buhl 864b441d8e Merge pull request #316 from Radarr/patch/skyhook-cleanup
Maybe this will solve the error Object reference not set to an instance of an object
2017-01-17 17:20:49 -05:00
Devin Buhl bc2ff149b4 Maybe this will solve the error
Couldn't refresh info for [tt2032572][USS Indianapolis: Men of Courage]: Object reference not set to an instance of an object
2017-01-17 17:05:19 -05:00
Devin Buhl dea305e921 Fix Issue when adding some movies. 2017-01-17 22:25:49 +01:00
Leonardo Galli e2eab31548 Hopefully fix RSSSync 2017-01-17 21:22:51 +01:00
Devin Buhl fe62e18f0d Merge pull request #308 from Radarr/patch/jackett
Fix publish date for jackett #239
2017-01-17 13:56:47 -05:00
Devin Buhl f1fa1553cf Merge pull request #307 from aenima99x/aenima99x-issue91
Fix: Issue #91 - "Search All Missing" wording
2017-01-17 13:48:30 -05:00
Devin Buhl b576ae813d Fix publish date #239 2017-01-17 13:47:11 -05:00
Aenima99x 99123be936 Fix: Issue #91 - "Search All Missing" wording 2017-01-17 09:00:56 -08:00
Leonardo Galli dd0a033b0f Add Support for changing file date to either cinema or physical release.
Fixes #124
2017-01-17 15:02:48 +01:00
Leonardo Galli c64597c9f1 Fix for movies with . in title when importing them. Fixes #268 2017-01-17 14:47:23 +01:00
Leonardo Galli 6d2f81e3ed Remove - as replacement for : 2017-01-17 14:28:30 +01:00
Leonardo Galli 4263808360 Fix only one movie showing. Fix more button not showing up. 2017-01-17 13:21:40 +01:00
Leonardo Galli c5ca2babf7 Updated website and donation links 2017-01-17 13:07:02 +01:00
Leonardo Galli 08db74d6e6 Fix Audiochannels just being added together. 2017-01-17 13:03:20 +01:00
Leonardo Galli b309a9b01f Change Scheduled Refresh Series to Refresh Movie. Fixes #301 2017-01-17 12:55:32 +01:00
Tim Turner 2730745607 Clean up rename preview & organize
Fixes #125, #129,

BE SURE TO RUN "Update Library" before renaming/organizing.
2017-01-16 18:43:32 -05:00
Tim Turner ae0df2aef0 Disambiguate Movie from Episode Renaming
Fixes #84
2017-01-16 17:12:27 -05:00
Leonardo Galli 6d665aeb21 Fix for hardcoded subs regex. 2017-01-16 22:51:45 +01:00
Leonardo Galli 967d3fd5c0 Add Calendar Tab back. Fixes #32 2017-01-16 22:40:59 +01:00
Devin Buhl 199d9c93ed Merge pull request #287 from baltoaca/develop
Added movie studio to movie details page (#262)
2017-01-16 14:30:21 -05:00
Vlad Ilies 30d2b41fbb Added movie studio to movie details page (#262)
* modified Movie model

* db migration

* ui template modification
2017-01-16 20:57:43 +02:00
Devin Buhl 75bb2533a3 Merge pull request #286 from Radarr/onedr0p-patch-1
Removed duplicate PublishDate
2017-01-16 13:46:29 -05:00
Devin Buhl 9b3b4eb55b Removed duplicate PublishDate 2017-01-16 13:25:59 -05:00
Leonardo Galli 42f84b830c Update NewznabRequestGenerator.cs 2017-01-16 12:54:51 +01:00
Leonardo Galli eb0f825cfc Update README.md 2017-01-16 00:10:30 +01:00
Vlad Ilies 56a5b6ec89 Added trailer link to movie links (#255) (#282)
* added YouTubeTrailerId to movie model
* db migration for new column

* added videos to append_to_response for tmdb
* increased height of .series-posters-item
* new handlebar helper to build the trailer url
2017-01-15 15:17:24 -05:00
hotio af478d3799 Add support section to README (#281)
* Add support section to README

* Update README.md

* Change docker color badge
2017-01-15 18:23:49 +01:00
Tim Turner c2d40051d4 First pass at hiding existing movies upon import
Fixes #183
2017-01-15 11:34:43 -05:00
Tim Turner 281e516495 Merge branch 'develop' of https://github.com/Radarr/Radarr into develop 2017-01-15 11:07:41 -05:00
hotio f63c3091f4 Reworked README (#280) 2017-01-15 13:50:45 +01:00
Leonardo Galli 50f49863b7 Update README.md 2017-01-15 11:42:15 +01:00
Mitchell Cash 941b3bd701 Move Travis builds to container-based infrastructure (#273)
* Remove example warning as it does not apply

* Modify the way apt packages work in .travis.yml

By modifying the way apt packages work (remove the need to directly require sudo), the builds can now run on container-based infrastructure.
2017-01-15 11:39:00 +01:00
hotio f60b8cefca Update .gitignore and remove Thumbs.db files (#276)
* Update .gitignore

* Delete Thumbs.db

* Delete Thumbs.db

* Delete Thumbs.db

* Update .gitignore
2017-01-15 11:38:54 +01:00
Tim Turner 7c5f2ca54e 95% done with hiding existing movies 2017-01-14 23:04:31 -05:00
Leonardo Galli 401a650273 Adding only original title is now allowed. Fixes #272 2017-01-15 01:36:05 +01:00
Leonardo Galli 105af5cf11 Fix for special characters when searching with title in Newznab. Fixes #97 2017-01-15 01:20:07 +01:00
hotio 637c2e43eb Update README.md (#271)
* Update README.md

* Update README.md
2017-01-15 00:56:52 +01:00
Leonardo Galli 53373e6f4a Add {Original Title} to FileNameBuilder. Fixes #103 2017-01-15 00:55:15 +01:00
Leonardo Galli ad147ed425 Release Group should now be available for renamer to use. 2017-01-15 00:49:37 +01:00
Devin Buhl ed35e2f194 Merge pull request #270 from hotio/patch-1
Update README.md
2017-01-14 18:10:58 -05:00
hotio 674919dbf5 Update README.md 2017-01-15 00:06:18 +01:00
Devin Buhl 15b77e303f Merge pull request #266 from hotio/patch-1
Update README.md
2017-01-14 17:53:01 -05:00
hotio 757ca1d72c Update README.md
Some small additional fixes to README
2017-01-14 23:48:04 +01:00
Devin Buhl 8c8c7a99e3 Merge pull request #265 from mitchellcash/readme
Cleanup README
2017-01-14 17:35:33 -05:00
Mitchell Cash b3dfb960b5 Cleanup README 2017-01-15 08:23:35 +10:00
219 changed files with 13985 additions and 9759 deletions
+2
View File
@@ -1,6 +1,8 @@
Please use the search bar and make sure you are not submitting an already submitted issue.
Provide a description of the feature request or bug, the more details the better. Provide a description of the feature request or bug, the more details the better.
When possible include a log! When possible include a log!
+17 -9
View File
@@ -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/
+6 -4
View File
@@ -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
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 48 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 811 B

After

Width:  |  Height:  |  Size: 701 B

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 11 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 17 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 37 KiB

+25 -572
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 31 KiB

BIN
View File
Binary file not shown.
+96
View File
@@ -0,0 +1,96 @@
## Status
[![GitHub issues](https://img.shields.io/github/issues/radarr/radarr.svg?maxAge=60&style=flat-square)](https://github.com/Radarr/Radarr/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/radarr/radarr.svg?maxAge=60&style=flat-square)](https://github.com/Radarr/Radarr/pulls)
[![GNU GPL v3](https://img.shields.io/badge/license-GNU%20GPL%20v3-blue.svg?maxAge=60&style=flat-square)](http://www.gnu.org/licenses/gpl.html)
[![Copyright 2010-2017](https://img.shields.io/badge/copyright-2017-blue.svg?maxAge=60&style=flat-square)](https://github.com/Radarr/Radarr)
[![Github Releases](https://img.shields.io/github/downloads/Radarr/Radarr/total.svg?maxAge=60&style=flat-square)](https://github.com/Radar/Radarr/releases/latest)
[![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/radarr.svg?maxAge=60&style=flat-square)](https://hub.docker.com/r/linuxserver/radarr/)
| Service | Master | Develop |
|----------|:---------------------------:|:----------------------------:|
| AppVeyor | [![AppVeyor](https://img.shields.io/appveyor/ci/galli-leo/Radarr/master.svg?maxAge=60&style=flat-square)](https://ci.appveyor.com/project/galli-leo/Radarr) | [![AppVeyor](https://img.shields.io/appveyor/ci/galli-leo/Radarr-usby1/develop.svg?maxAge=60&style=flat-square)](https://ci.appveyor.com/project/galli-leo/Radarr-usby1) |
| Travis | [![Travis](https://img.shields.io/travis/Radarr/Radarr/master.svg?maxAge=60&style=flat-square)](https://travis-ci.org/Radarr/Radarr) | [![Travis](https://img.shields.io/travis/Radarr/Radarr/develop.svg?maxAge=60&style=flat-square)](https://travis-ci.org/Radarr/Radarr) |
A fork of [Sonarr](https://github.com/Sonarr/Sonarr) to work with movies à la Couchpotato.
**This fork works independently of Sonarr and will not interfere with it.**
## Downloads
[![GitHub Releases](https://img.shields.io/badge/downloads-releases-brightgreen.svg?maxAge=60&style=flat-square)](https://github.com/Radarr/Radarr/releases)
[![AppVeyor Builds](https://img.shields.io/badge/downloads-continuous-green.svg?maxAge=60&style=flat-square)](https://ci.appveyor.com/project/galli-leo/radarr-usby1/build/artifacts)
[![Docker x64](https://img.shields.io/badge/docker-x64-blue.svg?colorB=1488C6&maxAge=60&style=flat-square)](https://store.docker.com/community/images/linuxserver/radarr)
[![Docker armhf](https://img.shields.io/badge/docker-armhf-blue.svg?colorB=1488C6&maxAge=60&style=flat-square)](https://store.docker.com/community/images/lsioarmhf/radarr)
[![Docker aarch64](https://img.shields.io/badge/docker-aarch64-blue.svg?colorB=1488C6&maxAge=60&style=flat-square)](https://store.docker.com/community/images/lsioarmhf/radarr-aarch64)
To connect to the UI, fire up your browser and open <http://localhost:7878> or <http://your-ip:7878>.
## Support
[![Discord](https://img.shields.io/badge/discord-chat-7289DA.svg?maxAge=60&style=flat-square)](https://discord.gg/AD3UP37)
[![Reddit](https://img.shields.io/badge/reddit-discussion-FF4500.svg?maxAge=60&style=flat-square)](https://www.reddit.com/r/radarr)
[![GitHub](https://img.shields.io/badge/github-issues-181717.svg?maxAge=60&style=flat-square)](https://github.com/Radarr/Radarr/issues)
## Features
### Current Features
* Adding new movies with lots of information, such as trailers, ratings, etc.
* 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
* Automatically searching for releases as well as RSS Sync
* Automatically importing downloaded movies
* Recognizing Special Editions, Director's Cut, etc.
* Identifying releases with hardcoded subs
* All indexers supported by Sonarr also supported
* New PassThePopcorn Indexer
* QBittorrent, Deluge, rTorrent, Transmission and uTorrent download client (Other clients are coming)
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
* And a beautiful UI
### Planned Features
* Scanning PreDB to know when a new release is available
* Fixing the other Indexers and download clients
* Importing movies from various online sources, such as IMDb Watchlists (A complete list can be found [here](https://github.com/Radarr/Radarr/issues/114))
* Full integration with Kodi, Plex (notification, library update, metadata)
##Feature Requests
[![Feature Requests](http://feathub.com/Radarr/Radarr?format=svg)](http://feathub.com/Radarr/Radarr)
## Configuring Development Environment
### Requirements
* [Visual Studio Community](https://www.visualstudio.com/vs/community/) or [MonoDevelop](http://www.monodevelop.com)
* [Git](https://git-scm.com/downloads)
* [Node.js](https://nodejs.org/en/download/)
### Setup
* Make sure all the required software mentioned above are installed
* Clone the repository into your development machine ([*info*](https://help.github.com/desktop/guides/contributing/working-with-your-remote-repository-on-github-or-github-enterprise))
* Grab the submodules `git submodule init && git submodule update`
* Install the required Node Packages `npm install`
* Start gulp to monitor your dev environment for any changes that need post processing using `npm start` command.
> **Notice**
> Gulp must be running at all times while you are working with Radarr client source files.
### Development
* Open `NzbDrone.sln` in Visual Studio or run the build.sh script, if Mono is installed
* Make sure `NzbDrone.Console` is set as the startup project
## Sponsors
[JetBrains](http://www.jetbrains.com) for providing us with free licenses to their great tools:
* [ReSharper](http://www.jetbrains.com/resharper)
* [WebStorm](http://www.jetbrains.com/webstorm)
* [TeamCity](http://www.jetbrains.com/teamcity)
-83
View File
@@ -1,83 +0,0 @@
# Radarr
| Service | Master | Develop |
|----------|:---------------------------:|:----------------------------:|
| AppVeyor | [![AppVeyor](https://img.shields.io/appveyor/ci/galli-leo/Radarr/master.svg?maxAge=60&style=flat-square)](https://ci.appveyor.com/project/galli-leo/Radarr) | [![AppVeyor](https://img.shields.io/appveyor/ci/galli-leo/Radarr-usby1/develop.svg?maxAge=60&style=flat-square)](https://ci.appveyor.com/project/galli-leo/Radarr-usby1) |
| Travis | [![Travis](https://img.shields.io/travis/galli-leo/Radarr/master.svg?maxAge=60&style=flat-square)](https://travis-ci.org/galli-leo/Radarr) | [![Travis](https://img.shields.io/travis/galli-leo/Radarr/develop.svg?maxAge=60&style=flat-square)](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.
To connect to the UI, fire up your browser and open localhost:7878 or your-ip:7878.
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/)
@@ -64,6 +64,8 @@ namespace NzbDrone.Api.Authentication
new DefaultHmacProvider(new PassphraseKeyGenerator(_configService.HmacPassphrase, Encoding.ASCII.GetBytes(_configService.HmacSalt))) new DefaultHmacProvider(new PassphraseKeyGenerator(_configService.HmacPassphrase, Encoding.ASCII.GetBytes(_configService.HmacSalt)))
); );
FormsAuthentication.FormsAuthenticationCookieName = "_ncfaradarr"; //For those people that both have sonarr and radarr.
FormsAuthentication.Enable(pipelines, new FormsAuthenticationConfiguration FormsAuthentication.Enable(pipelines, new FormsAuthenticationConfiguration
{ {
RedirectUrl = _configFileProvider.UrlBase + "/login", RedirectUrl = _configFileProvider.UrlBase + "/login",
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Api.Movie;
using NzbDrone.Api.REST; using NzbDrone.Api.REST;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series; using NzbDrone.Api.Series;
@@ -11,13 +12,14 @@ namespace NzbDrone.Api.Blacklist
{ {
public int SeriesId { get; set; } public int SeriesId { get; set; }
public List<int> EpisodeIds { get; set; } public List<int> EpisodeIds { get; set; }
public int MovieId { get; set; }
public string SourceTitle { get; set; } public string SourceTitle { get; set; }
public QualityModel Quality { get; set; } public QualityModel Quality { get; set; }
public DateTime Date { get; set; } public DateTime Date { get; set; }
public DownloadProtocol Protocol { get; set; } public DownloadProtocol Protocol { get; set; }
public string Indexer { get; set; } public string Indexer { get; set; }
public string Message { get; set; } public string Message { get; set; }
public MovieResource Movie { get; set; }
public SeriesResource Series { get; set; } public SeriesResource Series { get; set; }
} }
@@ -30,7 +32,7 @@ namespace NzbDrone.Api.Blacklist
return new BlacklistResource return new BlacklistResource
{ {
Id = model.Id, Id = model.Id,
MovieId = model.MovieId,
SeriesId = model.SeriesId, SeriesId = model.SeriesId,
EpisodeIds = model.EpisodeIds, EpisodeIds = model.EpisodeIds,
SourceTitle = model.SourceTitle, SourceTitle = model.SourceTitle,
@@ -39,7 +41,7 @@ namespace NzbDrone.Api.Blacklist
Protocol = model.Protocol, Protocol = model.Protocol,
Indexer = model.Indexer, Indexer = model.Indexer,
Message = model.Message, Message = model.Message,
Movie = model.Movie.ToResource(),
Series = model.Series.ToResource() Series = model.Series.ToResource()
}; };
} }
+23 -9
View File
@@ -2,24 +2,38 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NzbDrone.Api.Episodes; using NzbDrone.Api.Episodes;
using NzbDrone.Api.Movie;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.MovieStats;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
using NzbDrone.Core.Validation.Paths;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.Validation;
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.SignalR; using NzbDrone.SignalR;
namespace NzbDrone.Api.Calendar namespace NzbDrone.Api.Calendar
{ {
public class CalendarModule : EpisodeModuleWithSignalR public class CalendarModule : MovieModule
{ {
public CalendarModule(IEpisodeService episodeService, public CalendarModule(IBroadcastSignalRMessage signalR,
ISeriesService seriesService, IMovieService moviesService,
IQualityUpgradableSpecification qualityUpgradableSpecification, IMovieStatisticsService moviesStatisticsService,
IBroadcastSignalRMessage signalRBroadcaster) ISceneMappingService sceneMappingService,
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "calendar") IMapCoversToLocal coverMapper)
: base(signalR, moviesService, moviesStatisticsService, sceneMappingService, coverMapper, "calendar")
{ {
GetResourceAll = GetCalendar; GetResourceAll = GetCalendar;
} }
private List<EpisodeResource> GetCalendar() private List<MovieResource> GetCalendar()
{ {
var start = DateTime.Today; var start = DateTime.Today;
var end = DateTime.Today.AddDays(2); var end = DateTime.Today.AddDays(2);
@@ -33,9 +47,9 @@ namespace NzbDrone.Api.Calendar
if (queryEnd.HasValue) end = DateTime.Parse(queryEnd.Value); if (queryEnd.HasValue) end = DateTime.Parse(queryEnd.Value);
if (queryIncludeUnmonitored.HasValue) includeUnmonitored = Convert.ToBoolean(queryIncludeUnmonitored.Value); if (queryIncludeUnmonitored.HasValue) includeUnmonitored = Convert.ToBoolean(queryIncludeUnmonitored.Value);
var resources = MapToResource(_episodeService.EpisodesBetweenDates(start, end, includeUnmonitored), true, true); var resources = _moviesService.GetMoviesBetweenDates(start, end, includeUnmonitored).Select(MapToResource);
return resources.OrderBy(e => e.AirDateUtc).ToList(); return resources.OrderBy(e => e.InCinemas).ToList();
} }
} }
} }
+1 -1
View File
@@ -12,7 +12,7 @@ namespace NzbDrone.Api.Movies
private readonly IRenameMovieFileService _renameMovieFileService; private readonly IRenameMovieFileService _renameMovieFileService;
public RenameMovieModule(IRenameMovieFileService renameMovieFileService) public RenameMovieModule(IRenameMovieFileService renameMovieFileService)
: base("rename") : base("renameMovie")
{ {
_renameMovieFileService = renameMovieFileService; _renameMovieFileService = renameMovieFileService;
+2 -1
View File
@@ -260,6 +260,7 @@
<Compile Include="Wanted\CutoffModule.cs" /> <Compile Include="Wanted\CutoffModule.cs" />
<Compile Include="Wanted\LegacyMissingModule.cs" /> <Compile Include="Wanted\LegacyMissingModule.cs" />
<Compile Include="Wanted\MissingModule.cs" /> <Compile Include="Wanted\MissingModule.cs" />
<Compile Include="Wanted\MovieMissingModule.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />
@@ -294,4 +295,4 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> </Project>
+25 -3
View File
@@ -28,7 +28,7 @@ namespace NzbDrone.Api.Movie
IHandle<MediaCoversUpdatedEvent> IHandle<MediaCoversUpdatedEvent>
{ {
private readonly IMovieService _moviesService; protected readonly IMovieService _moviesService;
private readonly IMovieStatisticsService _moviesStatisticsService; private readonly IMovieStatisticsService _moviesStatisticsService;
private readonly IMapCoversToLocal _coverMapper; private readonly IMapCoversToLocal _coverMapper;
@@ -78,13 +78,33 @@ namespace NzbDrone.Api.Movie
PutValidator.RuleFor(s => s.Path).IsValidPath(); PutValidator.RuleFor(s => s.Path).IsValidPath();
} }
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
IMovieService moviesService,
IMovieStatisticsService moviesStatisticsService,
ISceneMappingService sceneMappingService,
IMapCoversToLocal coverMapper,
string resource)
: base(signalRBroadcaster, resource)
{
_moviesService = moviesService;
_moviesStatisticsService = moviesStatisticsService;
_coverMapper = coverMapper;
GetResourceAll = AllMovie;
GetResourceById = GetMovie;
CreateResource = AddMovie;
UpdateResource = UpdateMovie;
DeleteResource = DeleteMovie;
}
private MovieResource GetMovie(int id) private MovieResource GetMovie(int id)
{ {
var movies = _moviesService.GetMovie(id); var movies = _moviesService.GetMovie(id);
return MapToResource(movies); return MapToResource(movies);
} }
private MovieResource MapToResource(Core.Tv.Movie movies) protected MovieResource MapToResource(Core.Tv.Movie movies)
{ {
if (movies == null) return null; if (movies == null) return null;
@@ -181,6 +201,8 @@ namespace NzbDrone.Api.Movie
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId); //var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
//if (mappings == null) return; //if (mappings == null) return;
//Not necessary anymore
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList(); //resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
} }
@@ -219,7 +241,7 @@ namespace NzbDrone.Api.Movie
public void Handle(MediaCoversUpdatedEvent message) public void Handle(MediaCoversUpdatedEvent message)
{ {
//BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
} }
} }
} }
+8 -2
View File
@@ -34,6 +34,8 @@ namespace NzbDrone.Api.Movie
public string RemotePoster { get; set; } public string RemotePoster { get; set; }
public int Year { get; set; } public int Year { get; set; }
public bool HasFile { get; set; } public bool HasFile { get; set; }
public string YouTubeTrailerId { get; set; }
public string Studio { get; set; }
//View & Edit //View & Edit
public string Path { get; set; } public string Path { get; set; }
@@ -144,7 +146,9 @@ namespace NzbDrone.Api.Movie
AddOptions = model.AddOptions, AddOptions = model.AddOptions,
AlternativeTitles = model.AlternativeTitles, AlternativeTitles = model.AlternativeTitles,
Ratings = model.Ratings, Ratings = model.Ratings,
MovieFile = movieFile MovieFile = movieFile,
YouTubeTrailerId = model.YouTubeTrailerId,
Studio = model.Studio
}; };
} }
@@ -191,7 +195,9 @@ namespace NzbDrone.Api.Movie
Added = resource.Added, Added = resource.Added,
AddOptions = resource.AddOptions, AddOptions = resource.AddOptions,
AlternativeTitles = resource.AlternativeTitles, AlternativeTitles = resource.AlternativeTitles,
Ratings = resource.Ratings Ratings = resource.Ratings,
YouTubeTrailerId = resource.YouTubeTrailerId,
Studio = resource.Studio
}; };
} }
+1 -1
View File
@@ -236,7 +236,7 @@ namespace NzbDrone.Api.Series
public void Handle(MediaCoversUpdatedEvent message) public void Handle(MediaCoversUpdatedEvent message)
{ {
BroadcastResourceChange(ModelAction.Updated, message.Series.Id); //BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
} }
} }
} }
+1 -1
View File
@@ -12,7 +12,7 @@ namespace NzbDrone.Api.Wanted
ISeriesService seriesService, ISeriesService seriesService,
IQualityUpgradableSpecification qualityUpgradableSpecification, IQualityUpgradableSpecification qualityUpgradableSpecification,
IBroadcastSignalRMessage signalRBroadcaster) IBroadcastSignalRMessage signalRBroadcaster)
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing") : base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing_episodes")
{ {
GetResourcePaged = GetMissingEpisodes; GetResourcePaged = GetMissingEpisodes;
} }
@@ -0,0 +1,77 @@
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Datastore;
using NzbDrone.SignalR;
using NzbDrone.Core.Download;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using System;
using NzbDrone.Core.Datastore.Events;
namespace NzbDrone.Api.Wanted
{
class MovieMissingModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
IHandle<MovieGrabbedEvent>,
IHandle<MovieDownloadedEvent>
{
protected readonly IMovieService _movieService;
public MovieMissingModule(IMovieService movieService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
IBroadcastSignalRMessage signalRBroadcaster)
: base(signalRBroadcaster, "wanted/missing")
{
_movieService = movieService;
GetResourcePaged = GetMissingMovies;
}
private PagingResource<MovieResource> GetMissingMovies(PagingResource<MovieResource> pagingResource)
{
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("physicalRelease", SortDirection.Descending);
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
{
pagingSpec.FilterExpression = v => v.Monitored == false;
}
else
{
pagingSpec.FilterExpression = v => v.Monitored == true;
}
var resource = ApplyToPage(_movieService.MoviesWithoutFiles, pagingSpec, v => MapToResource(v, false));
return resource;
}
private MovieResource GetMovie(int id)
{
var movie = _movieService.GetMovie(id);
var resource = MapToResource(movie, true);
return resource;
}
private MovieResource MapToResource(Core.Tv.Movie movie, bool includeMovieFile)
{
var resource = movie.ToResource();
return resource;
}
public void Handle(MovieGrabbedEvent message)
{
var resource = message.Movie.Movie.ToResource();
//add a grabbed field in MovieResource?
//resource.Grabbed = true;
BroadcastResourceChange(ModelAction.Updated, resource);
}
public void Handle(MovieDownloadedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Movie.Id);
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 81 KiB

@@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.Configuration
[Test] [Test]
public void Get_value_should_return_default_when_no_value() public void Get_value_should_return_default_when_no_value()
{ {
Subject.RssSyncInterval.Should().Be(15); Subject.RssSyncInterval.Should().Be(60);
} }
[Test] [Test]
@@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.Configuration
public void get_value_with_out_persist_should_not_store_default_value() public void get_value_with_out_persist_should_not_store_default_value()
{ {
var interval = Subject.RssSyncInterval; var interval = Subject.RssSyncInterval;
interval.Should().Be(15); interval.Should().Be(60);
Mocker.GetMock<IConfigRepository>().Verify(c => c.Insert(It.IsAny<Config>()), Times.Never()); Mocker.GetMock<IConfigRepository>().Verify(c => c.Insert(It.IsAny<Config>()), Times.Never());
} }
@@ -92,14 +92,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
protected void GivenFailedDownload() protected void GivenFailedDownload()
{ {
Mocker.GetMock<INzbgetProxy>() Mocker.GetMock<INzbgetProxy>()
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<NzbgetSettings>())) .Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<NzbgetSettings>()))
.Returns((string)null); .Returns((string)null);
} }
protected void GivenSuccessfulDownload() protected void GivenSuccessfulDownload()
{ {
Mocker.GetMock<INzbgetProxy>() Mocker.GetMock<INzbgetProxy>()
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<NzbgetSettings>())) .Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<NzbgetSettings>()))
.Returns(Guid.NewGuid().ToString().Replace("-", "")); .Returns(Guid.NewGuid().ToString().Replace("-", ""));
} }
@@ -47,5 +47,17 @@ namespace NzbDrone.Core.Test.ParserTests
{ {
QualityParser.ParseQuality(title).Revision.Version.Should().Be(version); QualityParser.ParseQuality(title).Revision.Version.Should().Be(version);
} }
[TestCase("Deadpool 2016 2160p 4K UltraHD BluRay DTS-HD MA 7 1 x264-Whatevs", 19)]
[TestCase("Deadpool 2016 2160p 4K UltraHD DTS-HD MA 7 1 x264-Whatevs", 16)]
[TestCase("Deadpool 2016 4K 2160p UltraHD BluRay AAC2 0 HEVC x265", 19)]
[TestCase("The Revenant 2015 2160p UHD BluRay DTS x264-Whatevs", 19)]
[TestCase("The Revenant 2015 2160p UHD BluRay FLAC 7 1 x264-Whatevs", 19)]
[TestCase("The Martian 2015 2160p Ultra HD BluRay DTS-HD MA 7 1 x264-Whatevs", 19)]
[TestCase("Into the Inferno 2016 2160p Netflix WEBRip DD5 1 x264-Whatevs", 18)]
public void should_parse_ultrahd_from_title(string title, int version)
{
QualityParser.ParseQuality(title).Quality.Id.Should().Be(version);
}
} }
} }
@@ -11,6 +11,8 @@ namespace NzbDrone.Core.Blacklisting
{ {
public int SeriesId { get; set; } public int SeriesId { get; set; }
public Series Series { get; set; } public Series Series { get; set; }
public int MovieId { get; set; }
public Movie Movie { get; set; }
public List<int> EpisodeIds { get; set; } public List<int> EpisodeIds { get; set; }
public string SourceTitle { get; set; } public string SourceTitle { get; set; }
public QualityModel Quality { get; set; } public QualityModel Quality { get; set; }
@@ -10,7 +10,7 @@ namespace NzbDrone.Core.Blacklisting
{ {
List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle); List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle);
List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash); List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash);
List<Blacklist> BlacklistedBySeries(int seriesId); List<Blacklist> BlacklistedByMovie(int seriesId);
} }
public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository
@@ -20,15 +20,15 @@ namespace NzbDrone.Core.Blacklisting
{ {
} }
public List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle) public List<Blacklist> BlacklistedByTitle(int movieId, string sourceTitle)
{ {
return Query.Where(e => e.SeriesId == seriesId) return Query.Where(e => e.MovieId == movieId)
.AndWhere(e => e.SourceTitle.Contains(sourceTitle)); .AndWhere(e => e.SourceTitle.Contains(sourceTitle));
} }
public List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash) public List<Blacklist> BlacklistedByTorrentInfoHash(int movieId, string torrentInfoHash)
{ {
return Query.Where(e => e.SeriesId == seriesId) return Query.Where(e => e.MovieId == movieId)
.AndWhere(e => e.TorrentInfoHash.Contains(torrentInfoHash)); .AndWhere(e => e.TorrentInfoHash.Contains(torrentInfoHash));
} }
@@ -37,9 +37,14 @@ namespace NzbDrone.Core.Blacklisting
return Query.Where(b => b.SeriesId == seriesId); return Query.Where(b => b.SeriesId == seriesId);
} }
public List<Blacklist> BlacklistedByMovie(int movieId)
{
return Query.Where(b => b.MovieId == movieId);
}
protected override SortBuilder<Blacklist> GetPagedQuery(QueryBuilder<Blacklist> query, PagingSpec<Blacklist> pagingSpec) protected override SortBuilder<Blacklist> GetPagedQuery(QueryBuilder<Blacklist> query, PagingSpec<Blacklist> pagingSpec)
{ {
var baseQuery = query.Join<Blacklist, Series>(JoinType.Inner, h => h.Series, (h, s) => h.SeriesId == s.Id); var baseQuery = query.Join<Blacklist, Movie>(JoinType.Inner, h => h.Movie, (h, s) => h.MovieId == s.Id);
return base.GetPagedQuery(baseQuery, pagingSpec); return base.GetPagedQuery(baseQuery, pagingSpec);
} }
@@ -21,7 +21,7 @@ namespace NzbDrone.Core.Blacklisting
IExecute<ClearBlacklistCommand>, IExecute<ClearBlacklistCommand>,
IHandle<DownloadFailedEvent>, IHandle<DownloadFailedEvent>,
IHandleAsync<SeriesDeletedEvent> IHandleAsync<MovieDeletedEvent>
{ {
private readonly IBlacklistRepository _blacklistRepository; private readonly IBlacklistRepository _blacklistRepository;
@@ -128,8 +128,9 @@ namespace NzbDrone.Core.Blacklisting
{ {
var blacklist = new Blacklist var blacklist = new Blacklist
{ {
SeriesId = message.SeriesId, SeriesId = 0,
EpisodeIds = message.EpisodeIds, EpisodeIds = message.EpisodeIds,
MovieId = message.MovieId,
SourceTitle = message.SourceTitle, SourceTitle = message.SourceTitle,
Quality = message.Quality, Quality = message.Quality,
Date = DateTime.UtcNow, Date = DateTime.UtcNow,
@@ -144,9 +145,9 @@ namespace NzbDrone.Core.Blacklisting
_blacklistRepository.Insert(blacklist); _blacklistRepository.Insert(blacklist);
} }
public void HandleAsync(SeriesDeletedEvent message) public void HandleAsync(MovieDeletedEvent message)
{ {
var blacklisted = _blacklistRepository.BlacklistedBySeries(message.Series.Id); var blacklisted = _blacklistRepository.BlacklistedByMovie(message.Movie.Id);
_blacklistRepository.DeleteMany(blacklisted); _blacklistRepository.DeleteMany(blacklisted);
} }
@@ -100,7 +100,7 @@ namespace NzbDrone.Core.Configuration
public int RssSyncInterval public int RssSyncInterval
{ {
get { return GetValueInt("RssSyncInterval", 15); } get { return GetValueInt("RssSyncInterval", 60); }
set { SetValue("RssSyncInterval", value); } set { SetValue("RssSyncInterval", value); }
} }
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
using System.Data;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(119)]
public class add_youtube_trailer_id : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Movies").AddColumn("YouTubeTrailerId").AsString().Nullable();
}
}
}
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
using System.Data;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(120)]
public class add_studio : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Movies").AddColumn("Studio").AsString().Nullable();
}
}
}
@@ -0,0 +1,67 @@
using System.Data;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
using System.Text;
using System.Text.RegularExpressions;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(121)]
public class update_filedate_config : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Execute.WithConnection(SetTitleSlug);
}
private void SetTitleSlug(IDbConnection conn, IDbTransaction tran)
{
using (IDbCommand getSeriesCmd = conn.CreateCommand())
{
getSeriesCmd.Transaction = tran;
getSeriesCmd.CommandText = @"SELECT Id, Value FROM Config WHERE Key = 'filedate'";
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
{
while (seriesReader.Read())
{
var id = seriesReader.GetInt32(0);
var value = seriesReader.GetString(1);
using (IDbCommand updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE Config SET Value = 'Release' WHERE Id = ?";
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
}
}
}
}
public static string ToUrlSlug(string value)
{
//First to lower case
value = value.ToLowerInvariant();
//Remove all accents
var bytes = Encoding.GetEncoding("Cyrillic").GetBytes(value);
value = Encoding.ASCII.GetString(bytes);
//Replace spaces
value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);
//Remove invalid chars
value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled);
//Trim dashes from end
value = value.Trim('-', '_');
//Replace double occurences of - or _
value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);
return value;
}
}
}
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
using System.Data;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(122)]
public class add_movieid_to_blacklist : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Blacklist").AddColumn("MovieId").AsInt32().Nullable().WithDefaultValue(0);
Alter.Table("Blacklist").AlterColumn("SeriesId").AsInt32().Nullable();
Alter.Table("Blacklist").AlterColumn("EpisodeIds").AsString().Nullable();
}
}
}
@@ -68,6 +68,17 @@ namespace NzbDrone.Core.DecisionEngine
private int CompareProtocol(DownloadDecision x, DownloadDecision y) private int CompareProtocol(DownloadDecision x, DownloadDecision y)
{ {
if (x.IsForMovie)
{
return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
{
var delayProfile = _delayProfileService.BestForTags(remoteEpisode.Movie.Tags);
var downloadProtocol = remoteEpisode.Release.DownloadProtocol;
return downloadProtocol == delayProfile.PreferredProtocol;
});
}
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);
@@ -75,15 +86,7 @@ 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;
} }
@@ -125,8 +128,8 @@ namespace NzbDrone.Core.DecisionEngine
private int CompareAgeIfUsenet(DownloadDecision x, DownloadDecision y) private int CompareAgeIfUsenet(DownloadDecision x, DownloadDecision y)
{ {
if (x.RemoteEpisode.Release.DownloadProtocol != DownloadProtocol.Usenet || if (x.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Usenet ||
y.RemoteEpisode.Release.DownloadProtocol != DownloadProtocol.Usenet) y.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Usenet)
{ {
return 0; return 0;
} }
@@ -32,7 +32,7 @@ namespace NzbDrone.Core.DecisionEngine
public List<DownloadDecision> GetRssDecision(List<ReleaseInfo> reports) public List<DownloadDecision> GetRssDecision(List<ReleaseInfo> reports)
{ {
return GetDecisions(reports).ToList(); return GetMovieDecisions(reports).ToList();
} }
public List<DownloadDecision> GetSearchDecision(List<ReleaseInfo> reports, SearchCriteriaBase searchCriteriaBase) public List<DownloadDecision> GetSearchDecision(List<ReleaseInfo> reports, SearchCriteriaBase searchCriteriaBase)
@@ -83,7 +83,7 @@ namespace NzbDrone.Core.DecisionEngine
{ {
if (parsedEpisodeInfo.Quality.HardcodedSubs.IsNotNullOrWhiteSpace()) if (parsedEpisodeInfo.Quality.HardcodedSubs.IsNotNullOrWhiteSpace())
{ {
remoteEpisode.DownloadAllowed = false; remoteEpisode.DownloadAllowed = true;
decision = new DownloadDecision(remoteEpisode, new Rejection("Hardcoded subs found: " + parsedEpisodeInfo.Quality.HardcodedSubs)); decision = new DownloadDecision(remoteEpisode, new Rejection("Hardcoded subs found: " + parsedEpisodeInfo.Quality.HardcodedSubs));
} }
else else
@@ -34,11 +34,11 @@ namespace NzbDrone.Core.DecisionEngine
public List<DownloadDecision> PrioritizeDecisionsForMovies(List<DownloadDecision> decisions) public List<DownloadDecision> PrioritizeDecisionsForMovies(List<DownloadDecision> decisions)
{ {
return decisions.Where(c => c.RemoteMovie.Movie != null) return decisions.Where(c => c.RemoteMovie.Movie != null)
/*.GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) => .GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) =>
{ {
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService)); return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService));
}) })
.SelectMany(c => c)*/ .SelectMany(c => c)
.Union(decisions.Where(c => c.RemoteMovie.Movie == null)) .Union(decisions.Where(c => c.RemoteMovie.Movie == null))
.ToList(); .ToList();
} }
@@ -33,7 +33,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{ {
throw new NotImplementedException(); if (_blacklistService.Blacklisted(subject.Movie.Id, subject.Release))
{
_logger.Debug("{0} is blacklisted, rejecting.", subject.Release.Title);
return Decision.Reject("Release is blacklisted");
}
return Decision.Accept(); return Decision.Accept();
} }
@@ -19,7 +19,21 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{ {
throw new NotImplementedException(); if (searchCriteria != null)
{
if (searchCriteria.UserInvokedSearch)
{
_logger.Debug("Skipping monitored check during search");
return Decision.Accept();
}
}
if (!subject.Movie.Monitored)
{
return Decision.Reject("Movie is not monitored");
}
return Decision.Accept();
} }
public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
@@ -32,9 +32,12 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
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 addpaused = Settings.AddPaused;
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, addpaused, Settings);
if (response == null) if (response == null)
{ {
@@ -47,9 +50,12 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
protected override string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents) protected override string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents)
{ {
var category = Settings.TvCategory; // TODO: Update this to MovieCategory? var category = Settings.TvCategory; // TODO: Update this to MovieCategory?
var priority = Settings.RecentTvPriority; var priority = Settings.RecentTvPriority;
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings); var addpaused = Settings.AddPaused;
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, addpaused, Settings);
if(response == null) if(response == null)
{ {
@@ -11,7 +11,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
{ {
public interface INzbgetProxy public interface INzbgetProxy
{ {
string DownloadNzb(byte[] nzbData, string title, string category, int priority, NzbgetSettings settings); string DownloadNzb(byte[] nzbData, string title, string category, int priority, bool addpaused, NzbgetSettings settings);
NzbgetGlobalStatus GetGlobalStatus(NzbgetSettings settings); NzbgetGlobalStatus GetGlobalStatus(NzbgetSettings settings);
List<NzbgetQueueItem> GetQueue(NzbgetSettings settings); List<NzbgetQueueItem> GetQueue(NzbgetSettings settings);
List<NzbgetHistoryItem> GetHistory(NzbgetSettings settings); List<NzbgetHistoryItem> GetHistory(NzbgetSettings settings);
@@ -45,12 +45,12 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
return version >= minimumVersion; return version >= minimumVersion;
} }
public string DownloadNzb(byte[] nzbData, string title, string category, int priority, NzbgetSettings settings) public string DownloadNzb(byte[] nzbData, string title, string category, int priority, bool addpaused, NzbgetSettings settings)
{ {
if (HasVersion(16, settings)) if (HasVersion(16, settings))
{ {
var droneId = Guid.NewGuid().ToString().Replace("-", ""); var droneId = Guid.NewGuid().ToString().Replace("-", "");
var response = ProcessRequest<int>(settings, "append", title, nzbData, category, priority, false, false, string.Empty, 0, "all", new string[] { "drone", droneId }); var response = ProcessRequest<int>(settings, "append", title, nzbData, category, priority, false, addpaused, string.Empty, 0, "all", new string[] { "drone", droneId });
if (response <= 0) if (response <= 0)
{ {
return null; return null;
@@ -57,6 +57,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
[FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox)] [FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox)]
public bool UseSsl { get; set; } public bool UseSsl { get; set; }
[FieldDefinition(8, Label = "Add Paused", Type = FieldType.Checkbox, HelpText = "This option requires at least NzbGet version 16.0")]
public bool AddPaused { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
@@ -5,6 +5,7 @@ using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using System.Collections.Generic;
namespace NzbDrone.Core.Download namespace NzbDrone.Core.Download
{ {
@@ -38,7 +39,7 @@ namespace NzbDrone.Core.Download
{ {
_logger.Debug("Failed download contains a movie, searching again."); _logger.Debug("Failed download contains a movie, searching again.");
_commandQueueManager.Push(new MoviesSearchCommand { MovieId = message.MovieId }); _commandQueueManager.Push(new MoviesSearchCommand { MovieIds = new List<int> { message.MovieId } });
return; return;
} }
+6 -6
View File
@@ -102,13 +102,13 @@ namespace NzbDrone.Core.Extras
public void Handle(MediaCoversUpdatedEvent message) public void Handle(MediaCoversUpdatedEvent message)
{ {
var series = message.Series; //var series = message.Series;
var episodeFiles = GetEpisodeFiles(series.Id); //var episodeFiles = GetEpisodeFiles(series.Id);
foreach (var extraFileManager in _extraFileManagers) //foreach (var extraFileManager in _extraFileManagers)
{ //{
extraFileManager.CreateAfterSeriesScan(series, episodeFiles); // extraFileManager.CreateAfterSeriesScan(series, episodeFiles);
} //}
} }
//TODO: Implementing this will fix a lot of our warning exceptions //TODO: Implementing this will fix a lot of our warning exceptions
@@ -0,0 +1,13 @@
using NzbDrone.Core.Messaging.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Core.IndexerSearch
{
public class MissingMoviesSearchCommand : Command
{
public override bool SendUpdatesToClient => true;
}
}
@@ -1,10 +1,11 @@
using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands;
using System.Collections.Generic;
namespace NzbDrone.Core.IndexerSearch namespace NzbDrone.Core.IndexerSearch
{ {
public class MoviesSearchCommand : Command public class MoviesSearchCommand : Command
{ {
public int MovieId { get; set; } public List<int> MovieIds { get; set; }
public override bool SendUpdatesToClient => true; public override bool SendUpdatesToClient => true;
} }
@@ -4,22 +4,23 @@ using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.Download; using NzbDrone.Core.Download;
using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.IndexerSearch namespace NzbDrone.Core.IndexerSearch
{ {
public class MovieSearchService : IExecute<MoviesSearchCommand> public class MovieSearchService : IExecute<MoviesSearchCommand>, IExecute<MissingMoviesSearchCommand>
{ {
private readonly IMovieService _seriesService; private readonly IMovieService _movieService;
private readonly ISearchForNzb _nzbSearchService; private readonly ISearchForNzb _nzbSearchService;
private readonly IProcessDownloadDecisions _processDownloadDecisions; private readonly IProcessDownloadDecisions _processDownloadDecisions;
private readonly Logger _logger; private readonly Logger _logger;
public MovieSearchService(IMovieService seriesService, public MovieSearchService(IMovieService movieService,
ISearchForNzb nzbSearchService, ISearchForNzb nzbSearchService,
IProcessDownloadDecisions processDownloadDecisions, IProcessDownloadDecisions processDownloadDecisions,
Logger logger) Logger logger)
{ {
_seriesService = seriesService; _movieService = movieService;
_nzbSearchService = nzbSearchService; _nzbSearchService = nzbSearchService;
_processDownloadDecisions = processDownloadDecisions; _processDownloadDecisions = processDownloadDecisions;
_logger = logger; _logger = logger;
@@ -27,20 +28,35 @@ namespace NzbDrone.Core.IndexerSearch
public void Execute(MoviesSearchCommand message) public void Execute(MoviesSearchCommand message)
{ {
var series = _seriesService.GetMovie(message.MovieId);
var downloadedCount = 0; var downloadedCount = 0;
foreach (var movieId in message.MovieIds)
{
var series = _movieService.GetMovie(movieId);
if (!series.Monitored) if (!series.Monitored)
{ {
_logger.Debug("Movie {0} is not monitored, skipping search", series.Title); _logger.Debug("Movie {0} is not monitored, skipping search", series.Title);
} }
var decisions = _nzbSearchService.MovieSearch(message.MovieId, false);//_nzbSearchService.SeasonSearch(message.MovieId, season.SeasonNumber, false, message.Trigger == CommandTrigger.Manual); var decisions = _nzbSearchService.MovieSearch(movieId, false);//_nzbSearchService.SeasonSearch(message.MovieId, season.SeasonNumber, false, message.Trigger == CommandTrigger.Manual);
downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count; downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count;
}
_logger.ProgressInfo("Movie search completed. {0} reports downloaded.", downloadedCount); _logger.ProgressInfo("Movie search completed. {0} reports downloaded.", downloadedCount);
} }
public void Execute(MissingMoviesSearchCommand message)
{
var movies = _movieService.MoviesWithoutFiles(new PagingSpec<Movie>
{
Page = 1,
PageSize = 100000,
SortDirection = SortDirection.Ascending,
SortKey = "Id",
FilterExpression =
v =>
v.Monitored == true
}).Records.ToList();
}
} }
} }
@@ -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;
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Net; using System.Net;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
@@ -36,12 +37,11 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
torrentInfo.Size = (long)torrent.size*1000*1000; torrentInfo.Size = (long)torrent.size*1000*1000;
torrentInfo.DownloadUrl = torrent.download_url; torrentInfo.DownloadUrl = torrent.download_url;
torrentInfo.InfoUrl = torrent.details_url; torrentInfo.InfoUrl = torrent.details_url;
torrentInfo.PublishDate = new System.DateTime(); torrentInfo.PublishDate = torrent.publish_date.ToUniversalTime();
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);
} }
@@ -21,7 +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; } public DateTime publish_date { get; set; }
} }
} }
@@ -39,7 +39,13 @@ 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)); if (GetImdbId(item) != null)
{
if (torrentInfo != null)
{
torrentInfo.ImdbId = int.Parse(GetImdbId(item).Substring(2));
}
}
return torrentInfo; return torrentInfo;
} }
+14 -4
View File
@@ -30,12 +30,14 @@ namespace NzbDrone.Core.Jobs
{ {
private readonly IScheduledTaskRepository _scheduledTaskRepository; private readonly IScheduledTaskRepository _scheduledTaskRepository;
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly IConfigFileProvider _configFileProvider;
private readonly Logger _logger; private readonly Logger _logger;
public TaskManager(IScheduledTaskRepository scheduledTaskRepository, IConfigService configService, Logger logger) public TaskManager(IScheduledTaskRepository scheduledTaskRepository, IConfigService configService, IConfigFileProvider configFileProvider, Logger logger)
{ {
_scheduledTaskRepository = scheduledTaskRepository; _scheduledTaskRepository = scheduledTaskRepository;
_configService = configService; _configService = configService;
_configFileProvider = configFileProvider;
_logger = logger; _logger = logger;
} }
@@ -59,14 +61,21 @@ namespace NzbDrone.Core.Jobs
public void Handle(ApplicationStartedEvent message) public void Handle(ApplicationStartedEvent message)
{ {
float updateInterval = 6 * 60;
if (_configFileProvider.Branch == "nightly")
{
updateInterval = 30;
}
var defaultTasks = new[] var defaultTasks = new[]
{ {
new ScheduledTask{ Interval = 0.25f, TypeName = typeof(CheckForFinishedDownloadCommand).FullName}, new ScheduledTask{ Interval = 0.25f, TypeName = typeof(CheckForFinishedDownloadCommand).FullName},
new ScheduledTask{ Interval = 5, TypeName = typeof(MessagingCleanupCommand).FullName}, new ScheduledTask{ Interval = 5, TypeName = typeof(MessagingCleanupCommand).FullName},
new ScheduledTask{ Interval = 6*60, TypeName = typeof(ApplicationUpdateCommand).FullName}, new ScheduledTask{ Interval = updateInterval, TypeName = typeof(ApplicationUpdateCommand).FullName},
new ScheduledTask{ Interval = 3*60, TypeName = typeof(UpdateSceneMappingCommand).FullName}, // new ScheduledTask{ Interval = 3*60, TypeName = typeof(UpdateSceneMappingCommand).FullName},
new ScheduledTask{ Interval = 6*60, TypeName = typeof(CheckHealthCommand).FullName}, new ScheduledTask{ Interval = 6*60, TypeName = typeof(CheckHealthCommand).FullName},
new ScheduledTask{ Interval = 12*60, TypeName = typeof(RefreshSeriesCommand).FullName}, new ScheduledTask{ Interval = 24*60, TypeName = typeof(RefreshMovieCommand).FullName},
new ScheduledTask{ Interval = 24*60, TypeName = typeof(HousekeepingCommand).FullName}, new ScheduledTask{ Interval = 24*60, TypeName = typeof(HousekeepingCommand).FullName},
new ScheduledTask{ Interval = 7*24*60, TypeName = typeof(BackupCommand).FullName}, new ScheduledTask{ Interval = 7*24*60, TypeName = typeof(BackupCommand).FullName},
@@ -80,6 +89,7 @@ namespace NzbDrone.Core.Jobs
{ {
Interval = _configService.DownloadedEpisodesScanInterval, Interval = _configService.DownloadedEpisodesScanInterval,
TypeName = typeof(DownloadedEpisodesScanCommand).FullName TypeName = typeof(DownloadedEpisodesScanCommand).FullName
//TypeName = typeof(DownloadedMovieScanCommand).FullName
}, },
}; };
@@ -1,5 +1,8 @@
using NzbDrone.Common.Disk; using System;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using System.Drawing;
using NLog;
namespace NzbDrone.Core.MediaCover namespace NzbDrone.Core.MediaCover
{ {
@@ -12,11 +15,13 @@ namespace NzbDrone.Core.MediaCover
{ {
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly IHttpClient _httpClient; private readonly IHttpClient _httpClient;
private readonly Logger _logger;
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpClient httpClient) public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpClient httpClient, Logger logger)
{ {
_diskProvider = diskProvider; _diskProvider = diskProvider;
_httpClient = httpClient; _httpClient = httpClient;
_logger = logger;
} }
public bool AlreadyExists(string url, string path) public bool AlreadyExists(string url, string path)
@@ -26,9 +31,38 @@ namespace NzbDrone.Core.MediaCover
return false; return false;
} }
if (!IsValidGDIPlusImage(path))
{
_diskProvider.DeleteFile(path);
return false;
}
var headers = _httpClient.Head(new HttpRequest(url)).Headers; var headers = _httpClient.Head(new HttpRequest(url)).Headers;
var fileSize = _diskProvider.GetFileSize(path); var fileSize = _diskProvider.GetFileSize(path);
return fileSize == headers.ContentLength; return fileSize == headers.ContentLength;
} }
private bool IsValidGDIPlusImage(string filename)
{
try
{
GdiPlusInterop.CheckGdiPlus();
using (var bmp = new Bitmap(filename))
{
}
return true;
}
catch (DllNotFoundException ex)
{
_logger.Error(ex, "Could not find libgdiplus. Cannot test if image is corrupt.");
return true;
}
catch (Exception ex)
{
_logger.Debug(ex, "Corrupted image found at: {0}. Redownloading...", filename);
return false;
}
}
} }
} }
@@ -114,7 +114,7 @@ namespace NzbDrone.Core.MediaCover
} }
} }
private void EnsureCovers(Movie movie) private void EnsureCovers(Movie movie, int retried = 0)
{ {
foreach (var cover in movie.Images) foreach (var cover in movie.Images)
{ {
@@ -130,7 +130,25 @@ namespace NzbDrone.Core.MediaCover
} }
catch (WebException e) catch (WebException e)
{ {
_logger.Warn(string.Format("Couldn't download media cover for {0}. {1}", movie, e.Message)); if (e.Status == WebExceptionStatus.ProtocolError)
{
_logger.Warn(e, "Server returned different code than 200. The poster is probably not available yet.");
return;
}
_logger.Warn(e, string.Format("Couldn't download media cover for {0}. {1}", movie, e.Message));
if (retried < 3)
{
retried = +1;
_logger.Warn("Retrying for the {0}. time in ten seconds.", retried);
System.Threading.Thread.Sleep(10*1000);
EnsureCovers(movie, retried);
}
else
{
_logger.Warn(e, "Couldn't download media cover even after retrying five times :(.");
}
} }
catch (Exception e) catch (Exception e)
{ {
@@ -68,22 +68,22 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
{ {
//check if already imported //check if already imported
if (importResults.Select(r => r.ImportDecision.LocalMovie.Movie) if (importResults.Select(r => r.ImportDecision.LocalMovie.Movie)
.Select(e => e.Id).Contains(localMovie.Movie.Id)) .Select(m => m.Id).Contains(localMovie.Movie.Id))
{ {
importResults.Add(new ImportResult(importDecision, "Movie has already been imported")); importResults.Add(new ImportResult(importDecision, "Movie has already been imported"));
continue; continue;
} }
var episodeFile = new MovieFile(); var movieFile = new MovieFile();
episodeFile.DateAdded = DateTime.UtcNow; movieFile.DateAdded = DateTime.UtcNow;
episodeFile.MovieId = localMovie.Movie.Id; movieFile.MovieId = localMovie.Movie.Id;
episodeFile.Path = localMovie.Path.CleanFilePath(); movieFile.Path = localMovie.Path.CleanFilePath();
episodeFile.Size = _diskProvider.GetFileSize(localMovie.Path); movieFile.Size = _diskProvider.GetFileSize(localMovie.Path);
episodeFile.Quality = localMovie.Quality; movieFile.Quality = localMovie.Quality;
episodeFile.MediaInfo = localMovie.MediaInfo; movieFile.MediaInfo = localMovie.MediaInfo;
episodeFile.Movie = localMovie.Movie; movieFile.Movie = localMovie.Movie;
episodeFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup; movieFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
episodeFile.Edition = localMovie.ParsedMovieInfo.Edition; movieFile.Edition = localMovie.ParsedMovieInfo.Edition;
bool copyOnly; bool copyOnly;
switch (importMode) switch (importMode)
@@ -102,17 +102,17 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
if (newDownload) if (newDownload)
{ {
episodeFile.SceneName = GetSceneName(downloadClientItem, localMovie); movieFile.SceneName = GetSceneName(downloadClientItem, localMovie);
var moveResult = _episodeFileUpgrader.UpgradeMovieFile(episodeFile, localMovie, copyOnly); var moveResult = _episodeFileUpgrader.UpgradeMovieFile(movieFile, localMovie, copyOnly); //TODO: Check if this works
oldFiles = moveResult.OldFiles; oldFiles = moveResult.OldFiles;
} }
else else
{ {
episodeFile.RelativePath = localMovie.Movie.Path.GetRelativePath(episodeFile.Path); movieFile.RelativePath = localMovie.Movie.Path.GetRelativePath(movieFile.Path);
} }
_mediaFileService.Add(episodeFile); _mediaFileService.Add(movieFile);
importResults.Add(new ImportResult(importDecision)); importResults.Add(new ImportResult(importDecision));
if (newDownload) if (newDownload)
@@ -122,22 +122,22 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
if (downloadClientItem != null) if (downloadClientItem != null)
{ {
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, episodeFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId, downloadClientItem.IsReadOnly)); _eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId, downloadClientItem.IsReadOnly));
} }
else else
{ {
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, episodeFile, newDownload)); _eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload));
} }
if (newDownload) if (newDownload)
{ {
_eventAggregator.PublishEvent(new MovieDownloadedEvent(localMovie, episodeFile, oldFiles)); _eventAggregator.PublishEvent(new MovieDownloadedEvent(localMovie, movieFile, oldFiles));
} }
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Warn(e, "Couldn't import episode " + localMovie); _logger.Warn(e, "Couldn't import movie " + localMovie);
importResults.Add(new ImportResult(importDecision, "Failed to import episode")); importResults.Add(new ImportResult(importDecision, "Failed to import movie"));
} }
} }
+2 -2
View File
@@ -3,7 +3,7 @@
public enum FileDateType public enum FileDateType
{ {
None = 0, None = 0,
LocalAirDate = 1, Cinemas = 1,
UtcAirDate = 2 Release = 2
} }
} }
@@ -111,11 +111,11 @@ namespace NzbDrone.Core.MediaFiles
public List<string> FilterExistingFiles(List<string> files, Movie movie) public List<string> FilterExistingFiles(List<string> files, Movie movie)
{ {
var seriesFiles = GetFilesBySeries(movie.Id).Select(f => Path.Combine(movie.Path, f.RelativePath)).ToList(); var movieFiles = GetFilesByMovie(movie.Id).Select(f => Path.Combine(movie.Path, f.RelativePath)).ToList();
if (!seriesFiles.Any()) return files; if (!movieFiles.Any()) return files;
return files.Except(seriesFiles, PathEqualityComparer.Instance).ToList(); return files.Except(movieFiles, PathEqualityComparer.Instance).ToList();
} }
public EpisodeFile Get(int id) public EpisodeFile Get(int id)
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using NLog; using NLog;
@@ -18,14 +18,17 @@ namespace NzbDrone.Core.MediaFiles
public class MediaFileTableCleanupService : IMediaFileTableCleanupService public class MediaFileTableCleanupService : IMediaFileTableCleanupService
{ {
private readonly IMediaFileService _mediaFileService; private readonly IMediaFileService _mediaFileService;
private readonly IMovieService _movieService;
private readonly IEpisodeService _episodeService; private readonly IEpisodeService _episodeService;
private readonly Logger _logger; private readonly Logger _logger;
public MediaFileTableCleanupService(IMediaFileService mediaFileService, public MediaFileTableCleanupService(IMediaFileService mediaFileService,
IMovieService movieService,
IEpisodeService episodeService, IEpisodeService episodeService,
Logger logger) Logger logger)
{ {
_mediaFileService = mediaFileService; _mediaFileService = mediaFileService;
_movieService = movieService;
_episodeService = episodeService; _episodeService = episodeService;
_logger = logger; _logger = logger;
} }
@@ -89,61 +92,39 @@ namespace NzbDrone.Core.MediaFiles
public void Clean(Movie movie, List<string> filesOnDisk) public void Clean(Movie movie, List<string> filesOnDisk)
{ {
var movieFiles = _mediaFileService.GetFilesByMovie(movie.Id);
//TODO: Update implementation for movies.
var seriesFiles = _mediaFileService.GetFilesBySeries(movie.Id);
var episodes = _episodeService.GetEpisodeBySeries(movie.Id);
var filesOnDiskKeys = new HashSet<string>(filesOnDisk, PathEqualityComparer.Instance); var filesOnDiskKeys = new HashSet<string>(filesOnDisk, PathEqualityComparer.Instance);
foreach (var seriesFile in seriesFiles) foreach(var movieFile in movieFiles)
{ {
var episodeFile = seriesFile; var movieFilePath = Path.Combine(movie.Path, movieFile.RelativePath);
var episodeFilePath = Path.Combine(movie.Path, episodeFile.RelativePath);
try try
{ {
if (!filesOnDiskKeys.Contains(episodeFilePath)) if (!filesOnDiskKeys.Contains(movieFilePath))
{ {
_logger.Debug("File [{0}] no longer exists on disk, removing from db", episodeFilePath); _logger.Debug("File [{0}] no longer exists on disk, removing from db", movieFilePath);
_mediaFileService.Delete(seriesFile, DeleteMediaFileReason.MissingFromDisk); _mediaFileService.Delete(movieFile, DeleteMediaFileReason.MissingFromDisk);
continue; continue;
} }
if (episodes.None(e => e.EpisodeFileId == episodeFile.Id)) //var localMovie = _parsingService.GetLocalMovie(movieFile.Path, movie);
{
_logger.Debug("File [{0}] is not assigned to any episodes, removing from db", episodeFilePath);
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.NoLinkedEpisodes);
continue;
}
// var localEpsiode = _parsingService.GetLocalEpisode(episodeFile.Path, series); //if (localMovie == null)
// //{
// if (localEpsiode == null || episodes.Count != localEpsiode.Episodes.Count) // _logger.Debug("File [{0}] parsed episodes has changed, removing from db", localMovie.Path);
// { // _mediaFileService.Delete(localMovie);
// _logger.Debug("File [{0}] parsed episodes has changed, removing from db", episodeFile.Path); // continue;
// _mediaFileService.Delete(episodeFile); //}
// continue;
// }
} }
catch (Exception ex) catch (Exception ex)
{ {
var errorMessage = string.Format("Unable to cleanup EpisodeFile in DB: {0}", episodeFile.Id); var errorMessage = string.Format("Unable to cleanup MovieFile in DB: {0}", movieFile.Id);
_logger.Error(ex, errorMessage); _logger.Error(ex, errorMessage);
} }
} }
foreach (var e in episodes)
{
var episode = e;
if (episode.EpisodeFileId > 0 && seriesFiles.None(f => f.Id == episode.EpisodeFileId))
{
episode.EpisodeFileId = 0;
_episodeService.UpdateEpisode(episode);
}
}
} }
} }
} }
@@ -48,7 +48,12 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
return AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? AudioChannels - 1 + 0.1m : AudioChannels; return AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? AudioChannels - 1 + 0.1m : AudioChannels;
} }
return AudioChannelPositions.Split('/').Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture)); return
AudioChannelPositions.Replace("Object Based /", "").Replace(" / ", "$")
.Split('$')
.First()
.Split('/')
.Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture));
} }
} }
} }
@@ -49,7 +49,7 @@ namespace NzbDrone.Core.MediaFiles
switch (_configService.FileDate) switch (_configService.FileDate)
{ {
case FileDateType.LocalAirDate: case FileDateType.Release:
{ {
var airDate = episodes.First().AirDate; var airDate = episodes.First().AirDate;
var airTime = series.AirTime; var airTime = series.AirTime;
@@ -62,7 +62,7 @@ namespace NzbDrone.Core.MediaFiles
return ChangeFileDateToLocalAirDate(episodeFilePath, airDate, airTime); return ChangeFileDateToLocalAirDate(episodeFilePath, airDate, airTime);
} }
case FileDateType.UtcAirDate: case FileDateType.Cinemas:
{ {
var airDateUtc = episodes.First().AirDateUtc; var airDateUtc = episodes.First().AirDateUtc;
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.MediaFiles
} }
public class UpdateMovieFileService : IUpdateMovieFileService, public class UpdateMovieFileService : IUpdateMovieFileService,
IHandle<SeriesScannedEvent> IHandle<MovieScannedEvent>
{ {
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly IConfigService _configService; private readonly IConfigService _configService;
@@ -47,17 +47,67 @@ namespace NzbDrone.Core.MediaFiles
{ {
var movieFilePath = Path.Combine(movie.Path, movieFile.RelativePath); var movieFilePath = Path.Combine(movie.Path, movieFile.RelativePath);
switch (_configService.FileDate)
{
case FileDateType.Release:
{
var airDate = movie.PhysicalRelease;
if (airDate == null)
{
return false;
}
return ChangeFileDate(movieFilePath, airDate.Value);
}
case FileDateType.Cinemas:
{
var airDate = movie.InCinemas;
if (airDate == null)
{
return false;
}
return ChangeFileDate(movieFilePath, airDate.Value);
}
}
return false; return false;
} }
public void Handle(SeriesScannedEvent message) private bool ChangeFileDate(string filePath, DateTime date)
{
DateTime oldDateTime = _diskProvider.FileGetLastWrite(filePath);
if (!DateTime.Equals(date, oldDateTime))
{
try
{
_diskProvider.FileSetLastWriteTime(filePath, date);
_logger.Debug("Date of file [{0}] changed from '{1}' to '{2}'", filePath, oldDateTime, date);
return true;
}
catch (Exception ex)
{
_logger.Warn(ex, "Unable to set date of file [" + filePath + "]");
}
}
return false;
}
public void Handle(MovieScannedEvent message)
{ {
if (_configService.FileDate == FileDateType.None) if (_configService.FileDate == FileDateType.None)
{ {
return; return;
} }
/* var movies = _movieService.MoviesWithFiles(message.Series.Id); var movies = _movieService.MoviesWithFiles(message.Movie.Id);
var movieFiles = new List<MovieFile>(); var movieFiles = new List<MovieFile>();
var updated = new List<MovieFile>(); var updated = new List<MovieFile>();
@@ -69,7 +119,7 @@ namespace NzbDrone.Core.MediaFiles
movieFiles.Add(movieFile); movieFiles.Add(movieFile);
if (ChangeFileDate(movieFile, message.Series, moviesInFile)) if (ChangeFileDate(movieFile, message.Movie))
{ {
updated.Add(movieFile); updated.Add(movieFile);
} }
@@ -77,13 +127,13 @@ namespace NzbDrone.Core.MediaFiles
if (updated.Any()) if (updated.Any())
{ {
_logger.ProgressDebug("Changed file date for {0} files of {1} in {2}", updated.Count, movieFiles.Count, message.Series.Title); _logger.ProgressDebug("Changed file date for {0} files of {1} in {2}", updated.Count, movieFiles.Count, message.Movie.Title);
} }
else else
{ {
_logger.ProgressDebug("No file dates changed for {0}", message.Series.Title); _logger.ProgressDebug("No file dates changed for {0}", message.Movie.Title);
}*/ }
} }
private bool ChangeFileDateToLocalAirDate(string filePath, string fileDate, string fileTime) private bool ChangeFileDateToLocalAirDate(string filePath, string fileDate, string fileTime)
@@ -38,10 +38,13 @@ namespace NzbDrone.Core.MediaFiles
public MovieFileMoveResult UpgradeMovieFile(MovieFile episodeFile, LocalMovie localEpisode, bool copyOnly = false) public MovieFileMoveResult UpgradeMovieFile(MovieFile episodeFile, LocalMovie localEpisode, bool copyOnly = false)
{ {
_logger.Trace("Upgrading existing episode file.");
var moveFileResult = new MovieFileMoveResult(); var moveFileResult = new MovieFileMoveResult();
localEpisode.Movie.MovieFile.LazyLoad();
var existingFile = localEpisode.Movie.MovieFile; var existingFile = localEpisode.Movie.MovieFile;
existingFile.LazyLoad();
if (existingFile.IsLoaded) if (existingFile.IsLoaded && existingFile.Value != null)
{ {
var file = existingFile.Value; var file = existingFile.Value;
var episodeFilePath = Path.Combine(localEpisode.Movie.Path, file.RelativePath); var episodeFilePath = Path.Combine(localEpisode.Movie.Path, file.RelativePath);
@@ -55,6 +58,10 @@ namespace NzbDrone.Core.MediaFiles
moveFileResult.OldFiles.Add(file); moveFileResult.OldFiles.Add(file);
_mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade); _mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
} }
else
{
_logger.Warn("The existing movie file was not lazy loaded.");
}
@@ -66,6 +66,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public int vote_count { get; set; } public int vote_count { get; set; }
public AlternativeTitles alternative_titles { get; set; } public AlternativeTitles alternative_titles { get; set; }
public ReleaseDatesResource release_dates { get; set; } public ReleaseDatesResource release_dates { get; set; }
public VideosResource videos { get; set; }
} }
public class ReleaseDatesResource public class ReleaseDatesResource
@@ -130,4 +131,21 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public string iso_3166_1 { get; set; } public string iso_3166_1 { get; set; }
public string title { get; set; } public string title { get; set; }
} }
public class VideosResource
{
public List<Video> results { get; set; }
}
public class Video
{
public string id { get; set; }
public string iso_639_1 { get; set; }
public string iso_3166_1 { get; set; }
public string key { get; set; }
public string name { get; set; }
public string site { get; set; }
public string size { get; set; }
public string type { get; set; }
}
} }
@@ -73,7 +73,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
.SetSegment("route", "movie") .SetSegment("route", "movie")
.SetSegment("id", TmdbId.ToString()) .SetSegment("id", TmdbId.ToString())
.SetSegment("secondaryRoute", "") .SetSegment("secondaryRoute", "")
.AddQueryParam("append_to_response", "alternative_titles,release_dates") .AddQueryParam("append_to_response", "alternative_titles,release_dates,videos")
.AddQueryParam("country", "US") .AddQueryParam("country", "US")
.Build(); .Build();
@@ -89,9 +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 = ToUrlSlug(movie.Title); movie.TitleSlug = ToUrlSlug(resource.title);
movie.CleanTitle = Parser.Parser.CleanSeriesTitle(movie.Title); movie.CleanTitle = Parser.Parser.CleanSeriesTitle(resource.title);
movie.SortTitle = Parser.Parser.NormalizeTitle(movie.Title); movie.SortTitle = Parser.Parser.NormalizeTitle(resource.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())
@@ -149,6 +149,29 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
{ {
movie.Status = MovieStatusType.Announced; movie.Status = MovieStatusType.Announced;
} }
if (resource.videos != null)
{
foreach (Video video in resource.videos.results)
{
if (video.type == "Trailer" && video.site == "YouTube")
{
if (video.key != null)
{
movie.YouTubeTrailerId = video.key;
break;
}
}
}
}
if (resource.production_companies != null)
{
if (resource.production_companies.Any())
{
movie.Studio = resource.production_companies[0].name;
}
}
return movie; return movie;
} }
@@ -186,6 +209,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
{ {
var lowerTitle = title.ToLower(); var lowerTitle = title.ToLower();
lowerTitle = lowerTitle.Replace(".", "");
var parserResult = Parser.Parser.ParseMovieTitle(title, true); var parserResult = Parser.Parser.ParseMovieTitle(title, true);
var yearTerm = ""; var yearTerm = "";
@@ -193,7 +218,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
if (parserResult != null && parserResult.MovieTitle != title) if (parserResult != null && parserResult.MovieTitle != title)
{ {
//Parser found something interesting! //Parser found something interesting!
lowerTitle = parserResult.MovieTitle.ToLower(); lowerTitle = parserResult.MovieTitle.ToLower().Replace(".", " "); //TODO Update so not every period gets replaced (e.g. R.I.P.D.)
if (parserResult.Year > 1800) if (parserResult.Year > 1800)
{ {
yearTerm = parserResult.Year.ToString(); yearTerm = parserResult.Year.ToString();
@@ -326,25 +351,19 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
{ {
imdbMovie.SortTitle = Parser.Parser.NormalizeTitle(result.title); imdbMovie.SortTitle = Parser.Parser.NormalizeTitle(result.title);
imdbMovie.Title = result.title; imdbMovie.Title = result.title;
string titleSlug = ToUrlSlug(result.title); imdbMovie.TitleSlug = ToUrlSlug(result.title);
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) imdbMovie.TitleSlug += "-" + imdbMovie.Year;
//{
// _logger.Debug("Movie with this title slug already exists. Adding year...");
//}
imdbMovie.TitleSlug += "-" + imdbMovie.Year.ToString();
imdbMovie.Images = new List<MediaCover.MediaCover>(); imdbMovie.Images = new List<MediaCover.MediaCover>();
imdbMovie.Overview = result.overview; imdbMovie.Overview = result.overview;
try try
{ {
string url = result.poster_path;
var imdbPoster = _configService.GetCoverForURL(result.poster_path, MediaCoverTypes.Poster); var imdbPoster = _configService.GetCoverForURL(result.poster_path, MediaCoverTypes.Poster);
imdbMovie.Images.Add(imdbPoster); imdbMovie.Images.Add(imdbPoster);
} }
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Boxcar
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Episode Grabbed"; const string title = "Movie 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 = "Episode Downloaded"; const string title = "Movie Downloaded";
_proxy.SendNotification(title, message.Message, Settings); _proxy.SendNotification(title, message.Message, Settings);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -24,73 +25,73 @@ namespace NzbDrone.Core.Notifications.CustomScript
_logger = logger; _logger = logger;
} }
public override string Link => "https://github.com/Sonarr/Sonarr/wiki/Custom-Post-Processing-Scripts"; public override string Link => "https://github.com/Radarr/Radarr/wiki/Custom-Post-Processing-Scripts";
public override void OnGrab(GrabMessage message) public override void OnGrab(GrabMessage message)
{ {
var series = message.Series; var movie = message.Movie;
var remoteEpisode = message.Episode; var remoteMovie = message.RemoteMovie;
var releaseGroup = remoteEpisode.ParsedEpisodeInfo.ReleaseGroup; var releaseGroup = remoteMovie.ParsedEpisodeInfo.ReleaseGroup;
var environmentVariables = new StringDictionary(); var environmentVariables = new StringDictionary();
environmentVariables.Add("Sonarr_EventType", "Grab"); environmentVariables.Add("Radarr_EventType", "Grab");
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString()); environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
environmentVariables.Add("Sonarr_Series_Title", series.Title); environmentVariables.Add("Radarr_Movie_Title", movie.Title);
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString()); environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId.ToString());
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString()); environmentVariables.Add("Radarr_Release_Title", remoteMovie.Release.Title);
environmentVariables.Add("Sonarr_Release_EpisodeCount", remoteEpisode.Episodes.Count.ToString()); environmentVariables.Add("Radarr_Release_Indexer", remoteMovie.Release.Indexer);
environmentVariables.Add("Sonarr_Release_SeasonNumber", remoteEpisode.ParsedEpisodeInfo.SeasonNumber.ToString()); environmentVariables.Add("Radarr_Release_Size", remoteMovie.Release.Size.ToString());
environmentVariables.Add("Sonarr_Release_EpisodeNumbers", string.Join(",", remoteEpisode.Episodes.Select(e => e.EpisodeNumber))); environmentVariables.Add("Radarr_Release_ReleaseGroup", releaseGroup);
environmentVariables.Add("Sonarr_Release_Title", remoteEpisode.Release.Title);
environmentVariables.Add("Sonarr_Release_Indexer", remoteEpisode.Release.Indexer);
environmentVariables.Add("Sonarr_Release_Size", remoteEpisode.Release.Size.ToString());
environmentVariables.Add("Sonarr_Release_ReleaseGroup", releaseGroup);
ExecuteScript(environmentVariables); ExecuteScript(environmentVariables);
} }
public override void OnDownload(DownloadMessage message) public override void OnDownload(DownloadMessage message)
{ {
var series = message.Series; var movie = message.Movie;
var episodeFile = message.EpisodeFile; var movieFile = message.MovieFile;
var sourcePath = message.SourcePath; var sourcePath = message.SourcePath;
var environmentVariables = new StringDictionary(); var environmentVariables = new StringDictionary();
environmentVariables.Add("Sonarr_EventType", "Download"); environmentVariables.Add("Radarr_EventType", "Download");
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString()); environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
environmentVariables.Add("Sonarr_Series_Title", series.Title); environmentVariables.Add("Radarr_Movie_Title", movie.Title);
environmentVariables.Add("Sonarr_Series_Path", series.Path); environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId.ToString());
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString()); environmentVariables.Add("Radarr_MovieFile_Id", movieFile.Id.ToString());
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString()); environmentVariables.Add("Radarr_MovieFile_RelativePath", movieFile.RelativePath);
environmentVariables.Add("Sonarr_EpisodeFile_Id", episodeFile.Id.ToString()); environmentVariables.Add("Radarr_MovieFile_Path", Path.Combine(movie.Path, movieFile.RelativePath));
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeCount", episodeFile.Episodes.Value.Count.ToString()); environmentVariables.Add("Radarr_MovieFile_Quality", movieFile.Quality.Quality.Name);
environmentVariables.Add("Sonarr_EpisodeFile_RelativePath", episodeFile.RelativePath); environmentVariables.Add("Radarr_MovieFile_QualityVersion", movieFile.Quality.Revision.Version.ToString());
environmentVariables.Add("Sonarr_EpisodeFile_Path", Path.Combine(series.Path, episodeFile.RelativePath)); environmentVariables.Add("Radarr_MovieFile_ReleaseGroup", movieFile.ReleaseGroup ?? string.Empty);
environmentVariables.Add("Sonarr_EpisodeFile_SeasonNumber", episodeFile.SeasonNumber.ToString()); environmentVariables.Add("Radarr_MovieFile_SceneName", movieFile.SceneName ?? string.Empty);
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeNumbers", string.Join(",", episodeFile.Episodes.Value.Select(e => e.EpisodeNumber))); environmentVariables.Add("Radarr_MovieFile_SourcePath", sourcePath);
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeAirDates", string.Join(",", episodeFile.Episodes.Value.Select(e => e.AirDate))); environmentVariables.Add("Radarr_MovieFile_SourceFolder", Path.GetDirectoryName(sourcePath));
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeAirDatesUtc", string.Join(",", episodeFile.Episodes.Value.Select(e => e.AirDateUtc)));
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeTitles", string.Join("|", episodeFile.Episodes.Value.Select(e => e.Title)));
environmentVariables.Add("Sonarr_EpisodeFile_Quality", episodeFile.Quality.Quality.Name);
environmentVariables.Add("Sonarr_EpisodeFile_QualityVersion", episodeFile.Quality.Revision.Version.ToString());
environmentVariables.Add("Sonarr_EpisodeFile_ReleaseGroup", episodeFile.ReleaseGroup ?? string.Empty);
environmentVariables.Add("Sonarr_EpisodeFile_SceneName", episodeFile.SceneName ?? string.Empty);
environmentVariables.Add("Sonarr_EpisodeFile_SourcePath", sourcePath);
environmentVariables.Add("Sonarr_EpisodeFile_SourceFolder", Path.GetDirectoryName(sourcePath));
ExecuteScript(environmentVariables); ExecuteScript(environmentVariables);
} }
public override void OnMovieRename(Movie movie)
{
var environmentVariables = new StringDictionary();
environmentVariables.Add("Radarr_EventType", "Rename");
environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
environmentVariables.Add("Radarr_Movie_Title", movie.Title);
environmentVariables.Add("Radarr_Movie_Path", movie.Path);
environmentVariables.Add("Radarr_Movie_TvdbId", movie.ImdbId.ToString());
ExecuteScript(environmentVariables);
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
var environmentVariables = new StringDictionary(); var environmentVariables = new StringDictionary();
environmentVariables.Add("Sonarr_EventType", "Rename"); environmentVariables.Add("Radarr_EventType", "Rename");
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString()); environmentVariables.Add("Radarr_Series_Id", series.Id.ToString());
environmentVariables.Add("Sonarr_Series_Title", series.Title); environmentVariables.Add("Radarr_Series_Title", series.Title);
environmentVariables.Add("Sonarr_Series_Path", series.Path); environmentVariables.Add("Radarr_Series_Path", series.Path);
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString()); environmentVariables.Add("Radarr_Series_TvdbId", series.TvdbId.ToString());
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString()); environmentVariables.Add("Radarr_Series_Type", series.SeriesType.ToString());
ExecuteScript(environmentVariables); ExecuteScript(environmentVariables);
} }
@@ -8,8 +8,11 @@ namespace NzbDrone.Core.Notifications
{ {
public string Message { get; set; } public string Message { get; set; }
public Series Series { get; set; } public Series Series { get; set; }
public Movie Movie { get; set; }
public EpisodeFile EpisodeFile { get; set; } public EpisodeFile EpisodeFile { get; set; }
public List<EpisodeFile> OldFiles { get; set; } public List<EpisodeFile> OldFiles { get; set; }
public MovieFile MovieFile { get; set; }
public List<MovieFile> OldMovieFiles { get; set; }
public string SourcePath { get; set; } public string SourcePath { get; set; }
public override string ToString() public override string ToString()
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.Email
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string subject = "Radarr [TV] - Grabbed"; const string subject = "Radarr [Movie] - 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,12 +26,16 @@ namespace NzbDrone.Core.Notifications.Email
public override void OnDownload(DownloadMessage message) public override void OnDownload(DownloadMessage message)
{ {
const string subject = "Radarr [TV] - Downloaded"; const string subject = "Radarr [Movie] - 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);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -8,6 +8,8 @@ namespace NzbDrone.Core.Notifications
{ {
public string Message { get; set; } public string Message { get; set; }
public Series Series { get; set; } public Series Series { get; set; }
public Movie Movie { get; set; }
public RemoteMovie RemoteMovie { get; set; }
public RemoteEpisode Episode { get; set; } public RemoteEpisode Episode { get; set; }
public QualityModel Quality { get; set; } public QualityModel Quality { get; set; }
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Growl
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Episode Grabbed"; const string title = "Movie Grabbed";
_growlService.SendNotification(title, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password); _growlService.SendNotification(title, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
} }
public override void OnDownload(DownloadMessage message) public override void OnDownload(DownloadMessage message)
{ {
const string title = "Episode Downloaded"; const string title = "Movie Downloaded";
_growlService.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password); _growlService.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -10,6 +10,7 @@ namespace NzbDrone.Core.Notifications
void OnGrab(GrabMessage grabMessage); void OnGrab(GrabMessage grabMessage);
void OnDownload(DownloadMessage message); void OnDownload(DownloadMessage message);
void OnRename(Series series); void OnRename(Series series);
void OnMovieRename(Movie movie);
bool SupportsOnGrab { get; } bool SupportsOnGrab { get; }
bool SupportsOnDownload { get; } bool SupportsOnDownload { get; }
bool SupportsOnUpgrade { get; } bool SupportsOnUpgrade { get; }
+6 -2
View File
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Join
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Radarr - Episode Grabbed"; const string title = "Radarr - Movie 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 = "Radarr - Episode Downloaded"; const string title = "Radarr - Movie Downloaded";
_proxy.SendNotification(title, message.Message, Settings); _proxy.SendNotification(title, message.Message, Settings);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Radarr - Grabbed"; const string title = "Radarr - Movie 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 = "Radarr - Downloaded"; const string title = "Radarr - Movie Downloaded";
if (Settings.Notify) if (Settings.Notify)
{ {
@@ -41,6 +41,10 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
} }
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
if (Settings.UpdateLibrary) if (Settings.UpdateLibrary)
@@ -24,6 +24,7 @@ namespace NzbDrone.Core.Notifications
public abstract void OnGrab(GrabMessage grabMessage); public abstract void OnGrab(GrabMessage grabMessage);
public abstract void OnDownload(DownloadMessage message); public abstract void OnDownload(DownloadMessage message);
public abstract void OnRename(Series series); public abstract void OnRename(Series series);
public abstract void OnMovieRename(Movie movie);
public virtual bool SupportsOnGrab => true; public virtual bool SupportsOnGrab => true;
public virtual bool SupportsOnDownload => true; public virtual bool SupportsOnDownload => true;
@@ -15,7 +15,11 @@ namespace NzbDrone.Core.Notifications
public class NotificationService public class NotificationService
: IHandle<EpisodeGrabbedEvent>, : IHandle<EpisodeGrabbedEvent>,
IHandle<EpisodeDownloadedEvent>, IHandle<EpisodeDownloadedEvent>,
IHandle<SeriesRenamedEvent> IHandle<SeriesRenamedEvent>,
IHandle<MovieRenamedEvent>,
IHandle<MovieGrabbedEvent>,
IHandle<MovieDownloadedEvent>
{ {
private readonly INotificationFactory _notificationFactory; private readonly INotificationFactory _notificationFactory;
private readonly Logger _logger; private readonly Logger _logger;
@@ -67,6 +71,41 @@ namespace NzbDrone.Core.Notifications
qualityString); qualityString);
} }
private string GetMessage(Movie movie, QualityModel quality)
{
var qualityString = quality.Quality.ToString();
if (quality.Revision.Version > 1)
{
qualityString += " Proper";
}
return string.Format("{0}[{1}]",
movie.Title,
qualityString);
}
private bool ShouldHandleMovie(ProviderDefinition definition, Movie movie)
{
var notificationDefinition = (NotificationDefinition)definition;
if (notificationDefinition.Tags.Empty())
{
_logger.Debug("No tags set for this notification.");
return true;
}
if (notificationDefinition.Tags.Intersect(movie.Tags).Any())
{
_logger.Debug("Notification and series have one or more matching tags.");
return true;
}
//TODO: this message could be more clear
_logger.Debug("{0} does not have any tags that match {1}'s tags", notificationDefinition.Name, movie.Title);
return false;
}
private bool ShouldHandleSeries(ProviderDefinition definition, Series series) private bool ShouldHandleSeries(ProviderDefinition definition, Series series)
{ {
var notificationDefinition = (NotificationDefinition) definition; var notificationDefinition = (NotificationDefinition) definition;
@@ -112,6 +151,33 @@ namespace NzbDrone.Core.Notifications
} }
} }
public void Handle(MovieGrabbedEvent message)
{
var grabMessage = new GrabMessage
{
Message = GetMessage(message.Movie.Movie, message.Movie.ParsedMovieInfo.Quality),
Series = null,
Quality = message.Movie.ParsedMovieInfo.Quality,
Episode = null,
Movie = message.Movie.Movie,
RemoteMovie = message.Movie
};
foreach (var notification in _notificationFactory.OnGrabEnabled())
{
try
{
if (!ShouldHandleMovie(notification.Definition, message.Movie.Movie)) continue;
notification.OnGrab(grabMessage);
}
catch (Exception ex)
{
_logger.Error(ex, "Unable to send OnGrab notification to: " + notification.Definition.Name);
}
}
}
public void Handle(EpisodeDownloadedEvent message) public void Handle(EpisodeDownloadedEvent message)
{ {
var downloadMessage = new DownloadMessage(); var downloadMessage = new DownloadMessage();
@@ -141,6 +207,36 @@ namespace NzbDrone.Core.Notifications
} }
} }
public void Handle(MovieDownloadedEvent message)
{
var downloadMessage = new DownloadMessage();
downloadMessage.Message = GetMessage(message.Movie.Movie, message.Movie.ParsedMovieInfo.Quality);
downloadMessage.Series = null;
downloadMessage.EpisodeFile = null;
downloadMessage.Movie = message.Movie.Movie;
downloadMessage.OldMovieFiles = message.OldFiles;
downloadMessage.SourcePath = message.Movie.Path;
foreach (var notification in _notificationFactory.OnDownloadEnabled())
{
try
{
if (ShouldHandleMovie(notification.Definition, message.Movie.Movie))
{
if (downloadMessage.OldMovieFiles.Empty() || ((NotificationDefinition)notification.Definition).OnUpgrade)
{
notification.OnDownload(downloadMessage);
}
}
}
catch (Exception ex)
{
_logger.Warn(ex, "Unable to send OnDownload notification to: " + notification.Definition.Name);
}
}
}
public void Handle(SeriesRenamedEvent message) public void Handle(SeriesRenamedEvent message)
{ {
foreach (var notification in _notificationFactory.OnRenameEnabled()) foreach (var notification in _notificationFactory.OnRenameEnabled())
@@ -159,5 +255,24 @@ namespace NzbDrone.Core.Notifications
} }
} }
} }
public void Handle(MovieRenamedEvent message)
{
foreach (var notification in _notificationFactory.OnRenameEnabled())
{
try
{
if (ShouldHandleMovie(notification.Definition, message.Movie))
{
notification.OnMovieRename(message.Movie);
}
}
catch (Exception ex)
{
_logger.Warn(ex, "Unable to send OnRename notification to: " + notification.Definition.Name);
}
}
}
} }
} }
@@ -19,18 +19,22 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Episode Grabbed"; const string title = "Movie Grabbed";
_proxy.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority); _proxy.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
} }
public override void OnDownload(DownloadMessage message) public override void OnDownload(DownloadMessage message)
{ {
const string title = "Episode Downloaded"; const string title = "Movie Downloaded";
_proxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority); _proxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -28,6 +28,10 @@ namespace NzbDrone.Core.Notifications.Plex
_plexClientService.Notify(Settings, header, message.Message); _plexClientService.Notify(Settings, header, message.Message);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -35,6 +35,10 @@ namespace NzbDrone.Core.Notifications.Plex
Notify(Settings, header, message.Message); Notify(Settings, header, message.Message);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
@@ -25,6 +25,10 @@ namespace NzbDrone.Core.Notifications.Plex
UpdateIfEnabled(message.Series); UpdateIfEnabled(message.Series);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
UpdateIfEnabled(series); UpdateIfEnabled(series);
@@ -19,18 +19,22 @@ namespace NzbDrone.Core.Notifications.Prowl
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Episode Grabbed"; const string title = "Movie Grabbed";
_prowlService.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority); _prowlService.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
} }
public override void OnDownload(DownloadMessage message) public override void OnDownload(DownloadMessage message)
{ {
const string title = "Episode Downloaded"; const string title = "Movie Downloaded";
_prowlService.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority); _prowlService.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.PushBullet
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Radarr - Episode Grabbed"; const string title = "Radarr - Movie 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 = "Radarr - Episode Downloaded"; const string title = "Radarr - Movie Downloaded";
_proxy.SendNotification(title, message.Message, Settings); _proxy.SendNotification(title, message.Message, Settings);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Pushalot
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Episode Grabbed"; const string title = "Movie 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 = "Episode Downloaded"; const string title = "Movie Downloaded";
_proxy.SendNotification(title, message.Message, Settings); _proxy.SendNotification(title, message.Message, Settings);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Pushover
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Episode Grabbed"; const string title = "Movie 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 = "Episode Downloaded"; const string title = "Movie Downloaded";
_proxy.SendNotification(title, message.Message, Settings); _proxy.SendNotification(title, message.Message, Settings);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -2,7 +2,7 @@
{ {
public enum PushoverPriority public enum PushoverPriority
{ {
Silent = -1, Silent = -2,
Quiet = -1, Quiet = -1,
Normal = 0, Normal = 0,
High = 1, High = 1,
@@ -69,6 +69,10 @@ namespace NzbDrone.Core.Notifications.Slack
NotifySlack(payload); NotifySlack(payload);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
var payload = new SlackPayload var payload = new SlackPayload
@@ -42,6 +42,10 @@ namespace NzbDrone.Core.Notifications.Synology
} }
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
if (Settings.UpdateLibrary) if (Settings.UpdateLibrary)
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Telegram
public override void OnGrab(GrabMessage grabMessage) public override void OnGrab(GrabMessage grabMessage)
{ {
const string title = "Episode Grabbed"; const string title = "Movie 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 = "Episode Downloaded"; const string title = "Movie Downloaded";
_proxy.SendNotification(title, message.Message, Settings); _proxy.SendNotification(title, message.Message, Settings);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -29,6 +29,10 @@ namespace NzbDrone.Core.Notifications.Twitter
_twitterService.SendNotification($"Imported: {message.Message}", Settings); _twitterService.SendNotification($"Imported: {message.Message}", Settings);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
} }
@@ -27,6 +27,10 @@ namespace NzbDrone.Core.Notifications.Webhook
_service.OnDownload(message.Series, message.EpisodeFile, Settings); _service.OnDownload(message.Series, message.EpisodeFile, Settings);
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
_service.OnRename(series, Settings); _service.OnRename(series, Settings);
@@ -36,6 +36,10 @@ namespace NzbDrone.Core.Notifications.Xbmc
UpdateAndClean(message.Series, message.OldFiles.Any()); UpdateAndClean(message.Series, message.OldFiles.Any());
} }
public override void OnMovieRename(Movie movie)
{
}
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
UpdateAndClean(series); UpdateAndClean(series);
+5
View File
@@ -183,6 +183,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\122_add_movieid_to_blacklist.cs" />
<Compile Include="Datastore\Migration\121_update_filedate_config.cs" />
<Compile Include="Datastore\Migration\120_add_studio_to_table.cs" />
<Compile Include="Datastore\Migration\119_add_youtube_trailer_id_table .cs" />
<Compile Include="Datastore\Migration\118_update_movie_slug.cs" /> <Compile Include="Datastore\Migration\118_update_movie_slug.cs" />
<Compile Include="Datastore\Migration\117_update_movie_file.cs" /> <Compile Include="Datastore\Migration\117_update_movie_file.cs" />
<Compile Include="Datastore\Migration\116_update_movie_sorttitle_again.cs" /> <Compile Include="Datastore\Migration\116_update_movie_sorttitle_again.cs" />
@@ -579,6 +583,7 @@
<Compile Include="Http\HttpProxySettingsProvider.cs" /> <Compile Include="Http\HttpProxySettingsProvider.cs" />
<Compile Include="Http\TorcacheHttpInterceptor.cs" /> <Compile Include="Http\TorcacheHttpInterceptor.cs" />
<Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" /> <Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" />
<Compile Include="IndexerSearch\MissingMoviesSearchCommand.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\AwesomeHD\AwesomeHDRssParser.cs" />
File diff suppressed because it is too large Load Diff
@@ -46,8 +46,9 @@ namespace NzbDrone.Core.Organizer
_movie = new Movie _movie = new Movie
{ {
Title = "Movie Title", Title = "The Movie Title",
Year = 2010 Year = 2010,
ImdbId = "tt0066921"
}; };
_standardSeries = new Series _standardSeries = new Series
@@ -124,7 +125,8 @@ namespace NzbDrone.Core.Organizer
RelativePath = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE.mkv", RelativePath = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE.mkv",
SceneName = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE", SceneName = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE",
ReleaseGroup = "RlsGrp", ReleaseGroup = "RlsGrp",
MediaInfo = mediaInfo MediaInfo = mediaInfo,
Edition = "Ultimate extended edition",
}; };
_singleEpisodeFile = new EpisodeFile _singleEpisodeFile = new EpisodeFile
+11 -5
View File
@@ -18,20 +18,20 @@ 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>(\.?((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+|_|$)(?!\\)", 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>((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX))", 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), RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Normal movie format, e.g: Mission.Impossible.3.2011 //Normal movie format, e.g: Mission.Impossible.3.2011
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)", new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled), RegexOptions.IgnoreCase | RegexOptions.Compiled),
//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? //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+|_|$)(?!\\)", new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\W\d+)))+(\W+|_|$)(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled), RegexOptions.IgnoreCase | RegexOptions.Compiled),
}; };
@@ -268,7 +268,7 @@ namespace NzbDrone.Core.Parser
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{9})", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{9})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*", private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|2160[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*",
RegexOptions.IgnoreCase | RegexOptions.Compiled); RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*", private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
@@ -696,6 +696,12 @@ namespace NzbDrone.Core.Parser
private static ParsedMovieInfo ParseMovieMatchCollection(MatchCollection matchCollection) private static ParsedMovieInfo ParseMovieMatchCollection(MatchCollection matchCollection)
{ {
if (!matchCollection[0].Groups["title"].Success)
{
return null;
}
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' '); var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
seriesName = RequestInfoRegex.Replace(seriesName, "").Trim(' '); seriesName = RequestInfoRegex.Replace(seriesName, "").Trim(' ');
+9 -3
View File
@@ -396,9 +396,15 @@ namespace NzbDrone.Core.Parser
if (searchCriteria == null) if (searchCriteria == null)
{ {
if (parsedEpisodeInfo.Year > 1900)
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle); //Todo: same as above! {
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle, parsedEpisodeInfo.Year);
//Todo: same as above!
}
else
{
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle); //Todo: same as above!
}
return movie; return movie;
} }

Some files were not shown because too many files have changed in this diff Show More