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

Compare commits

...

179 Commits

Author SHA1 Message Date
Leonardo Galli
a48793edd2 Fixed: Changes in http redirect logic causing failed grabs and >25% cpu usage. 2018-03-04 16:01:40 +01:00
Leonardo Galli
799a448544 Fixed: http->https redirects do not use the tls1.2 curl fallback.
fixes #1862
2018-03-04 15:57:02 +01:00
Leonardo Galli
57adf0e3a5 Fixed: Dates before 1970 causing an exception.
Fixes #1913
2018-03-04 15:42:15 +01:00
Leonardo Galli
61ee8edb5a Fixed: Browser not updating on Movie File Imported.
Fixes #657
2018-03-04 15:35:12 +01:00
Leonardo Galli
ed1154ec3c @cosmetic Updated Changelog 2018-03-04 15:25:52 +01:00
Paul Kozlovitch
2d99f9268a Added: Copy & Paste now triggers search (#2587) 2018-03-04 15:24:49 +01:00
Simon Chapman
55dde613c2 Fixed: Movies not getting unmonitored when folder gets deleted (#2588)
Fixes #1191, fixes #1590
2018-03-04 15:24:07 +01:00
Leonardo Galli
b83f2ca0ee Merge remote-tracking branch 'origin/develop' into develop 2018-03-04 15:23:15 +01:00
Leonardo Galli
fc61f84522 @cosmetic Updated Changelog 2018-03-04 15:23:09 +01:00
Leonardo Galli
c1692ff84c Merge remote-tracking branch 'origin/develop' into develop 2018-03-03 17:08:31 +01:00
Leonardo Galli
65c3704ff0 Fixed: NLog causing a crash under mono 5.10
Fixes #2585
Merge remote-tracking branch 'origin/develop' into develop


Revert "Fixed: NLog causing a crash under mono 5.10"

This reverts commit d11b565eda.

Added console logging in case NLog fails to initialize.

Fixed: Updated NLog to 4.5 RC6 to handle mono 5.10
Fixed: Messed up merge from Cherry pick


Fixed: Appveyor build.


Revert "Fixed: Appveyor build."

This reverts commit 99282359c4.

Revert "Fixed: Messed up merge from Cherry pick"

This reverts commit 450d90586d.

Revert "Fixed: Updated NLog to 4.5 RC6 to handle mono 5.10"

This reverts commit 1b20cbb5e3.

Fixed: NLog causing issues with mono 5.10
2018-03-03 17:07:50 +01:00
Leonardo Galli
0ab7c19e54 Revert "Fixed: Updated NLog to 4.5 RC6 to handle mono 5.10"
This reverts commit 1b20cbb5e3.
2018-03-03 00:40:31 +01:00
Leonardo Galli
f70c769070 Revert "Fixed: Messed up merge from Cherry pick"
This reverts commit 450d90586d.
2018-03-03 00:40:23 +01:00
Leonardo Galli
702f61213c Revert "Fixed: Appveyor build."
This reverts commit 99282359c4.
2018-03-03 00:40:16 +01:00
Leonardo Galli
99282359c4 Fixed: Appveyor build. 2018-03-03 00:13:28 +01:00
Leonardo Galli
450d90586d Fixed: Messed up merge from Cherry pick 2018-03-02 20:04:16 +01:00
Leonardo Galli
1b20cbb5e3 Fixed: Updated NLog to 4.5 RC6 to handle mono 5.10 2018-03-02 20:00:28 +01:00
Taloth Saldono
400cf0e073 Added console logging in case NLog fails to initialize. 2018-03-02 19:56:48 +01:00
Leonardo Galli
79b3682b0f Revert "Fixed: NLog causing a crash under mono 5.10"
This reverts commit d11b565eda.
2018-03-02 19:55:47 +01:00
Leonardo Galli
cbf8106672 Merge remote-tracking branch 'origin/develop' into develop 2018-03-01 22:37:35 +01:00
Leonardo Galli
d11b565eda Fixed: NLog causing a crash under mono 5.10
Fixes #2585
2018-03-01 22:37:30 +01:00
Leonardo Galli
2ba1af5874 Merge pull request #2590 from Qstick/patch-1
Fixed: Pin Cake and Addin Versions
2018-03-01 08:55:59 +01:00
Qstick
731c9acd94 Fixed: Pin cake and addin versions 2018-02-28 23:08:18 -05:00
Qstick
59a176f03b Fixed: Temp Workaround for Appveyor Cake Issue 2018-02-27 22:43:16 -05:00
Qstick
6482024dc5 Fixed: Poster sliding issues (#2570)
Fixes #2568
2018-02-26 16:08:57 +01:00
Qstick
9e7e8cff11 Fixed: Multiple History Issues (#2571) 2018-02-26 16:08:44 +01:00
Leonardo Galli
15fe7a844c @cosmetic Updated Changelog 2018-02-21 11:04:23 +01:00
thezoggy
68d32e4d31 Fixed: Another Delete modal is fixed. (#2560)
Fixes #2537
2018-02-21 11:02:48 +01:00
thezoggy
29f540c4f2 Changed: Metadata links are now better readable. Also fixed links in the poster view. (#2562)
Fixes #2561
2018-02-21 11:02:04 +01:00
thezoggy
31eed11d1b Fixed: Messed up movie deletion modal (#2552)
Fixes #2537
2018-02-20 14:41:35 +01:00
thezoggy
ba0bbddce9 Fixed: Remove sorting on Monitor/Profile columns to prevent unexpected results until sorting can properly be handled. Quick Fix for #2540 (#2553)
Fixes #2540
2018-02-20 14:41:01 +01:00
thezoggy
a243a886f5 Fixed: OSX app has bundle name of Sonarr (#2555) 2018-02-20 14:40:35 +01:00
Leonardo Galli
033bc24984 @cosmetic update changelog 2018-02-19 16:16:04 +01:00
Leonardo Galli
e071850d4c Fixed: Alt Titles from TMDB not getting added when mappings server throws 404
Fixes #2535
2018-02-19 13:02:55 +01:00
Leonardo Galli
fa212872ab Added: Handle ctrl-c more gracefully.
Finally fixes #2218
2018-02-19 12:48:56 +01:00
Leonardo Galli
c34137c423 Merge remote-tracking branch 'origin/develop' into develop 2018-02-19 08:38:40 +01:00
Leonardo Galli
67848ebff5 Fixed: Omgwtfnbs parsing being too greedy.
Fixes #608
2018-02-19 08:37:47 +01:00
Qstick
d0406ced40 Fixed: Unable to execute custom scripts if IMDB ID is null (#2543)
fixes #1460
2018-02-19 08:19:14 +01:00
Qstick
ae88645180 Added: Device names for Join notifications (#2544)
Closes #2364
2018-02-19 08:18:36 +01:00
Qstick
8519b64947 Cleanup TV related code in API (#2530) 2018-02-19 08:18:14 +01:00
Leonardo Galli
d67d89f54a Merge remote-tracking branch 'origin/develop' into develop 2018-02-19 00:01:11 +01:00
Leonardo Galli
2b2bd16d4d Updated NLog to version 4.4.12. Should fix #2218 2018-02-19 00:00:59 +01:00
Qstick
0c23511b7a Added: Same File Size MediaFile Specification (#2532) 2018-02-18 17:29:41 +01:00
Qstick
4dc3612347 Fixed: Help icon not centered (#2531)
Fixes #2528
2018-02-18 15:06:53 +01:00
Qstick
2139246c4a Fixed: Radarr Changes every file due to timezones (#2533)
Fixes #1741
2018-02-18 15:06:26 +01:00
Leonardo Galli
c1a5e8e759 Fixed: Filters not working. Fuck you backbone. 2018-02-16 17:12:34 +01:00
Qstick
e70e76adcb Cleanup Series Code from UI (#2525) 2018-02-16 10:53:41 +01:00
Leonardo Galli
1dbb856ced Fixed: Apostrophe getting replaced by an empty string causing no search results.
Fixes #1505
2018-02-15 15:21:15 +01:00
Leonardo Galli
74396a7abb @cosmetic Updated changelog 2018-02-15 15:03:33 +01:00
Qstick
e7e9e2b154 Added: Importing extra files from downloaded movies and generate metadata such as .nfo (#2506)
Fixes #121, Fixes #167, Fixes #2262 and Fixes #1104
2018-02-15 13:39:01 +01:00
Qstick
b40423f3a3 Added: Quotes around alternative titles (#2522)
Fixes #2511
2018-02-15 11:16:59 +01:00
Qstick
b3e46d02c6 Fixed: Integration Unit Tests (#2500) 2018-02-13 19:10:49 +01:00
Qstick
081d8a8e53 Added: Backup improvements from Sonarr (#2513)
Fixes #2440
2018-02-13 19:07:26 +01:00
Leonardo Galli
2f271635f9 @cosmetic fixed build 2018-02-12 17:37:11 +01:00
Leonardo Galli
c460153e66 @cosmetic fixed indentation error. 2018-02-12 17:33:14 +01:00
Leonardo Galli
8a674181be @cosmetic Staged builds & upload artifacts. 2018-02-12 17:31:18 +01:00
Leonardo Galli
7537cef93c @cosmetic Fixed junit transformer. 2018-02-12 17:18:25 +01:00
Leonardo Galli
808b6d16e9 @cosmetic added junit transformer 2018-02-12 17:15:14 +01:00
Leonardo Galli
d1189e62c5 @cosmetic custom docker image for circleci 2018-02-12 17:10:44 +01:00
Leonardo Galli
ef86c83799 @cosmetic changed config again. 2018-02-12 16:37:33 +01:00
Leonardo Galli
aeb45e5f7e @cosmetic update test.sh 2018-02-12 16:27:48 +01:00
Leonardo Galli
149c7c534c @cosmetic update config. 2018-02-12 16:21:21 +01:00
Leonardo Galli
74ae66ba14 @cosmetic Wrong filename. 2018-02-12 16:10:53 +01:00
Leonardo Galli
f94e7b562a @cosmetic Testing CircleCI for tests. 2018-02-12 16:06:31 +01:00
Leonardo Galli
f5a7a2f29a @cosmetic 2018-02-11 22:59:11 +01:00
Qstick
1514a00b8f Updated: NzbDrone references in FirewallAdapter.cs (#2504) 2018-02-11 17:22:31 +01:00
Scott
3ed0652feb Fixed: XSS vulnerability in the navbar search. (#2505)
Fixes #2503
2018-02-11 17:20:55 +01:00
Qstick
f4e2a510f2 Fixed: StartNzbDroneService.cs unit test (#2499) 2018-02-10 00:04:22 +01:00
geogolem
8edd15b5f8 Merge pull request #2497 from geogolem/selectAllMovieEditor
selectAll and deselectAll MovieEditor buttons
2018-02-09 11:59:31 -05:00
geogolem
2fdfd0fba5 selectAll and deselectAll MovieEditor buttons 2018-02-09 11:41:31 -05:00
geogolem
8b201af053 Merge pull request #2493 from geogolem/develop
fix build problem on windows
2018-02-08 09:35:41 -05:00
geogolem
976bc1a6a5 fix build problem on windows 2018-02-08 09:22:58 -05:00
Leonardo Galli
16ba7194a9 Merge branch 'develop' of https://github.com/Radarr/Radarr into develop 2018-02-08 11:26:58 +01:00
Leonardo Galli
a151fbbcbe Revert "Fixed: Removed hebrew ISO, since english movies are still in english. (#1922)" 2018-02-08 11:26:43 +01:00
Leonardo Galli
71db67af2c @cosmetic 2018-02-07 17:27:04 +01:00
Leonardo Galli
1d2231a96d @cosmetic 2018-02-07 17:26:43 +01:00
Leonardo Galli
0837d3a8a0 @cosmetic 2018-02-07 17:26:23 +01:00
Leonardo Galli
05e5d610a3 @cosmetic 2018-02-07 17:11:51 +01:00
Leonardo Galli
d2f99f1330 Fixed: Error with deluge when it doesn’t report a Hash.
Fixes #2329
2018-02-07 15:59:14 +01:00
Leonardo Galli
27001b48f6 Fixed: Logging error when accessing mount point
Fixes #2305
2018-02-07 15:26:25 +01:00
Leonardo Galli
97ab4cbcbd Fixed: Invalid runtime from CP causing issues importing.
Fixes #2081
2018-02-07 12:04:27 +01:00
Leonardo Galli
8b3a71a537 Fixed: Typo in TMDB Settings.
Fixes #2077
2018-02-07 11:57:49 +01:00
Leonardo Galli
e22141e2ed Fixed: Hopefully fixed errors with Delay Profiles.
Fixes #1817
2018-02-07 11:24:58 +01:00
Leonardo Galli
11211dc2ed Fixed: Error when importing files and old folder doesn’t exist.
Fixes #2485
2018-02-07 11:08:05 +01:00
Leonardo Galli
e71e518d30 Fixed: Zooqle torrents not getting added, since their torrent file is messed up.
Fixes #1516
2018-02-07 00:10:33 +01:00
Leonardo Galli
f9049566c1 Fixed: No Physical Release Date causing exception when setting last write time.
Fixes #390
2018-02-06 16:51:19 +01:00
Leonardo Galli
0bc61bea38 Fixed: Movies not getting unmonitored when folder gets deleted.
Fixes #1191, Fixes #1590
2018-02-03 16:44:35 +01:00
Leonardo Galli
032fc68892 Added: Include total space with root folders
Closes #2468
2018-02-02 23:13:26 +01:00
Leonardo Galli
33cc228ac1 Fixed: Rare case of null quality causing issues with manual import.
Fixes #2227
2018-02-02 15:01:02 +01:00
Leonardo Galli
d5832a6a07 Added: Manual Import now adds year after movie title for filtering. This should help finding movies such as IT.
By searching e.g. It 2017, movies with short titles should be easily filterable now. Also displays more results (50 instead of 20)
2018-02-02 14:53:03 +01:00
Leonardo Galli
5f8aeeac17 Fixed: Manual Import not automatically choosing right movie.
Fixes #2458, Fixes #2061
Generally improved Manual Import UI
2018-02-02 14:51:18 +01:00
Leonardo Galli
54e57bf16a Merge remote-tracking branch 'origin/develop' into develop 2018-02-02 13:23:36 +01:00
Leonardo Galli
b1f76082b2 Added: Dynamic paths cleanup old folders now!
Old folder is now only left behind if extra files are also present in new dir and cannot be overwritten. Generally Dynamic Paths should be more stable now. Fixes #2048
2018-02-02 13:23:29 +01:00
Leonardo Galli
73fed04228 Fixed: Rare case of RequiredIndexerFlags failing with old Newznab indexers. 2018-02-01 16:00:55 +01:00
Leonardo Galli
ca3d5c184e Merge branch 'develop' of https://github.com/Radarr/Radarr into develop 2018-02-01 14:20:01 +01:00
Leonardo Galli
861962d06c Added: Option to require indexer flags per indexer. (e.g. only download freeleech torrents from a private tracker) (#2460) 2018-02-01 14:18:52 +01:00
Leonardo Galli
5057fcc40f Fixed: Folder name getting messed up when adding movies via a list.
Fixes #2465
2018-02-01 14:14:45 +01:00
Leonardo Galli
78e5fdf3bc Added: Files downloaded with different quality than grabbed will get rejected.
Fixes #1779, Fixes #2087, Fixes #1321
2018-01-31 20:09:04 +01:00
Leonardo Galli
aab14d02f9 Fixed: Error when adding an already excluded movie to the exclusion list.
Fixes #2462
2018-01-31 15:03:29 +01:00
Leonardo Galli
eb1c3c8b82 Fixed: Last commit still not compiling (whoops squared) 2018-01-30 18:33:30 +01:00
Leonardo Galli
4025af7895 Fixed: Last commit not compiling (whoops) 2018-01-30 18:31:07 +01:00
Leonardo Galli
95ca863697 Fixed: Clean Library being to agressive when lists are having failures.
Fixes #2455
2018-01-30 18:29:07 +01:00
Leonardo Galli
74e0db2829 @cosmetic Fixed all erroring tests. 2018-01-30 15:09:19 +01:00
Leonardo Galli
2459ddb6f4 Fixed: Error when nno quality was associated with a movie file.
Fixes #1991
2018-01-30 13:16:06 +01:00
Leonardo Galli
3e2e085b6b Fixed: Allowing in use Profiles to be Deleted.
Fixes #2030
2018-01-30 13:11:16 +01:00
Leonardo Galli
931cdacf66 Fixed: Error when Movie has no imdbid when searching Rargb
Fixes #2090
2018-01-30 12:59:45 +01:00
Leonardo Galli
18c622de40 Fixed: Rargb failing when imdbid is not found
Fixes #1845, Fixes #2319
2018-01-30 12:56:14 +01:00
Leonardo Galli
53e6fa7cf1 Fixed: {Original Filename} not allowed in Movie Filename
Fixes #1248
2018-01-30 12:42:06 +01:00
Qstick
4afd3f3bfe Fixed: Look for changes to package.json before using old build cache (#2445) 2018-01-26 08:54:59 +01:00
crhammock
da425b04b1 Updated: TMDbSettings.cs to allow pipe for or for genre ids (#2389) 2018-01-11 17:06:26 +01:00
Pieter Janssens
663ac972cd Fixed: HistoryDetailsLayoutTemplate.hbs (#2361) 2017-12-21 13:42:02 +01:00
Taloth Saldono
efbb587290 Fixed MediaCover endpoint. 2017-12-13 21:28:42 +01:00
Mark McDowall
72a12a73af Fixed: Don't handle content requests in IndexHtmlMapper 2017-12-13 21:28:21 +01:00
fhscholl
95bc93042c Added: Separate naming tags for AudioLanguage and SubtitleLanguage (#2261) (Fixes #2257) 2017-12-12 23:53:11 +01:00
Leonardo Galli
172cf4d06e Fixed: Movies parsed from lists with no year and only title getting added mutliple times. 2017-12-12 23:26:16 +01:00
Taloth Saldono
5ac0f28fff Fixed: Security Vulnerabilities allowing authentication to be bypassed (discovered by Kyle Neideck) 2017-12-12 23:15:46 +01:00
Leonardo Galli
948af901da Added: Include APFS disks in disk space calculation. 2017-12-12 22:46:00 +01:00
Leonardo Galli
f36716135b Added: Upgrade MediaInfo to 17.10 (Windows/macOS) 2017-12-12 22:44:14 +01:00
kriegalex
b70016d082 Added: Support for VF2 french tag. (#2291) (Fixes #2290) 2017-12-12 22:28:36 +01:00
grokdesigns
6a1b099117 Added: Customize Slack Channel (#2308) (Fixes #2298) 2017-12-04 09:07:42 +01:00
Leonardo Galli
ffb098357d Fixed: Movie Editor Path screwed up. Might also fix some other movie editor issues. (Fixes #2170) 2017-11-19 15:11:53 +01:00
Leonardo Galli
1a22486aba Fixed: Tags disappearing (Fixes #2204) 2017-11-19 14:57:15 +01:00
Fish2
72631eab8f Fixed: moment.js deprecated zone and add functions (Fixes #2232) (Fixes #2231) (#2264) 2017-11-16 20:20:41 +01:00
Mike
e4a3e63c44 Fixed: CPU locking at a 100% in certain instances. (#2258) (Fixes #2218) 2017-11-12 12:25:46 +01:00
Fish2
5dc2df3d49 Revert "Fixed: moment.js deprecated zone and Added: and lossless compression of images (#2232) (Fixes #2231)"
This reverts commit 32b1f75eb3.
2017-11-10 17:11:42 +01:00
fhscholl
01f0c6d85f Added: SceneName to MovieFile API output (#2250) (Fixes #2245) 2017-11-10 16:13:14 +01:00
fhscholl
c7c423b13d Added: Functionality to XBMC and Plex to update indivdual titles. Also: Notification Cleanup (#2240) 2017-11-10 16:11:09 +01:00
Fish2
32b1f75eb3 Fixed: moment.js deprecated zone and Added: and lossless compression of images (#2232) (Fixes #2231) 2017-11-10 16:08:02 +01:00
adnanklink
29909db604 Added: FolderPath to the Movie Webhook (#2230) 2017-11-10 16:06:45 +01:00
Mike
ec3f094d12 Fixes #2218. (#2254)
* Fixed: Raise ApplicationStartupEvent after Owin is running.

* Actually inject the container.
2017-11-08 19:39:50 +01:00
adnanklink
cb857934c4 Added: Download_Id to On Download/On Upgrade (#2229) 2017-10-29 19:19:30 +01:00
Leonardo Galli
d0174c7b7b Merge remote-tracking branch 'origin/develop' into develop 2017-10-29 12:24:41 +01:00
Leonardo Galli
9d19c4ec21 Fixed: Manual Import. Fixes #2160 2017-10-29 12:24:35 +01:00
fhscholl
0a030386f2 Added: Movie_Quality to onGrab (#2221) (Fixes #1833) 2017-10-28 17:19:49 +02:00
fhscholl
5e121c78e1 Updated: Webhook Improvements (#2220) (Fixes #1751) 2017-10-28 17:18:52 +02:00
James White
b521ffb588 Added: Message about adblockers preventing the log table from loading (#2213) (Fixes #2209) 2017-10-23 21:50:03 +02:00
James White
386a434aeb Changed: Sabnzbd Update test cases and rename to MovieCategory (#2212) 2017-10-23 21:49:02 +02:00
James White
5674d8ad60 Changed: Nzbget Rename TvCategory references to MovieCategory (#2211) 2017-10-23 21:47:49 +02:00
Oliver Rivett-Carnac
b313dd1845 Minor error message tweak (#1778)
* Added: some tips to how to build. Gave some info to Windows developers.

* Fixed: Alignment of validation errors in labels

* Fixed: error message mentioning 'series'
2017-10-22 20:58:25 -04:00
James White
dffa50a82f uTorrent initial state feature (#2192)
* New: Initial state for torrents added to UTorrent

Closes #409

(cherry picked from commit 19a4d3536b)

* Change default port

* Rename TvCategory to MovieCategory
2017-10-22 20:51:07 -04:00
James White
5337f79281 Change default port of qBittorrent download client config (#2187) 2017-10-22 20:49:54 -04:00
fhscholl
8861c8d8a4 Add IsUpgrade and related deleted file paths for CustomScript (#2205)
* Add IsUpgrade flag and deleted file paths for updates

* use OldMovieFiles instead of OldFiles
2017-10-22 20:49:37 -04:00
James White
4574ff5f6d Fixed: typo on margin-bottom (#2182) 2017-10-15 16:11:27 +02:00
James White
dd53e51468 @cosmetic Fix jshint warnings on MoviesCollection.js (#2180) 2017-10-15 13:37:19 +02:00
James White
7ae2d455c3 Fixed: Remove unit on zero values (#2178) 2017-10-15 13:29:32 +02:00
James White
e2e6630b69 Added: Initial state for torrents added to qBittorrent (#2176) 2017-10-15 12:35:53 +02:00
James White
ed744b5702 Fixed: Jackett apikey cleaned from log again. (#2177) 2017-10-15 12:35:04 +02:00
Leonardo Galli
5ffa27ec29 @cosmetic changed title 2017-10-14 12:05:17 +02:00
Leonardo Galli
53bfe61eb6 @cosmetic Added status images for websites and update api. 2017-10-14 12:04:22 +02:00
Leonardo Galli
a4a8e4547f Merge remote-tracking branch 'origin/develop' into develop 2017-10-11 23:09:36 +02:00
Leonardo Galli
e2bda29737 Fixed: Manual Movie Page Filtering. 2017-10-11 23:09:29 +02:00
James White
ab117082ed @cosmetic Stop commented out code appearing in HTML source (#2158) 2017-10-11 22:55:33 +02:00
Leonardo Galli
c708c3f5a1 Merge remote-tracking branch 'origin/develop' into develop 2017-10-11 22:54:51 +02:00
Leonardo Galli
a98494ab63 Fixed: MediaInfo not getting read when quality isn't Bluray, Web-dl or HDTV. Fixes #1465. Fixes #1572. 2017-10-11 22:54:45 +02:00
James White
779a722175 Changed: Adjust ambiguous date options (#2165)
(cherry picked from commit 00c3074216)
2017-10-11 22:45:15 +02:00
James White
805927205c @cosmetic Simplify ical ProductId code since adding properties (#2164) 2017-10-11 21:11:16 +02:00
James White
1d8eec42ef Added: a default name for Radarr.ics (#2163) 2017-10-11 19:19:57 +02:00
Leonardo Galli
a951ad811d @cosmetic Updated changelog. 2017-10-09 21:51:21 +02:00
James White
27c58f6151 Fixed: Alignment and buttons position of Trakt Auth (#2153) 2017-10-09 21:39:14 +02:00
Leonardo Galli
a5dd426dd7 Fixed: SUBBED in release name not recognized as hardcoded subs. Fixes #1520 2017-10-07 23:54:24 +02:00
Leonardo Galli
c30a681aea Fixed: 1080i not correctly recognized as 1080p. Fixes #1622 2017-10-07 23:47:22 +02:00
Leonardo Galli
4d712d7760 Fixed: Releases with UHD not getting correct resolution label. Fixes #2134 2017-10-07 20:24:50 +02:00
Leonardo Galli
63645c81bb Fixed: WebDL gets marked as Remux. Fixes #1954 2017-10-07 20:21:59 +02:00
Leonardo Galli
dc55eba74f Merge remote-tracking branch 'origin/develop' into develop 2017-10-07 20:20:47 +02:00
Leonardo Galli
b6be297093 Fixed: Parsing of TSRip and HDTSRip. Fixes #1998 2017-10-07 20:16:21 +02:00
Leonardo Galli
5ff9dc3500 Added: Option to omit year from indexer searches when searching by title. Also added option to force a movie search by title instead of imdb id. Fixes #1912 2017-10-07 20:09:22 +02:00
Wyall
4789f80df2 Added new codec HEVC with ID=5 for HDBits (#2146)
According to LSL1337 on Discord there's a new codec option HEVC with ID=5
2017-10-07 19:57:09 +02:00
Leonardo Galli
e77d9ce848 Added: Last round of optimisation. Large libraries should load around 2x faster again compared to the last version. 2017-10-07 18:16:15 +02:00
Leonardo Galli
a9b244bf75 Added: Improved load times of very large libraries again (around x5) 2017-10-05 23:31:12 +02:00
Leonardo Galli
628c044c46 Added: Movie files are now eager loaded. This should speed up the loading process a lot as well as RSS Sync and other tasks. It should also prevent some other bugs. 2017-10-01 18:41:19 +02:00
Leonardo Galli
ecd25dddf1 Merge remote-tracking branch 'origin/develop' into develop 2017-09-24 16:17:52 +02:00
Leonardo Galli
25b0a52ba6 Fixed: Alternative Titles appearing multiple times. Duplicate alt titles will be deleted. Fixes #2040 2017-09-24 16:17:43 +02:00
James White
321ba98e49 Fixed: unclosed <span> tag on BulkImportView (#2110) 2017-09-24 13:19:39 +02:00
James White
9178a0aa1b @cosmetic Convert backticks (#2112) 2017-09-24 13:16:05 +02:00
James White
6942fb892d Fixed: Change to correct provider of search results (#2113) 2017-09-24 13:15:35 +02:00
James White
f64d349119 Fixed: Icon not being hidden on Discover New Movies button in X-Small breakpoint (#2114) 2017-09-24 13:14:44 +02:00
James White
926dbdf2cd Fixed: Font folder case fix (#2066) 2017-09-21 22:37:10 +02:00
Adam Dangoor
645a3dca64 Fixed: Add space in confirmation message (#2101) 2017-09-20 07:55:44 +02:00
Leonardo Galli
2b2a1265ad Create LICENSE 2017-09-10 16:10:48 +02:00
611 changed files with 20832 additions and 18118 deletions

5
.circleci/Dockerfile Normal file
View File

@@ -0,0 +1,5 @@
FROM mono:4.8
RUN apt-get update && apt-get install -y git ssh tar gzip ca-certificates
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -E -
RUN apt-get install -y nodejs npm

40
.circleci/config.yml Normal file
View File

@@ -0,0 +1,40 @@
version: 2
jobs:
build:
docker:
- image: gallileo/radarr-cci-primary:4.8
steps:
- checkout
- run: git submodule update --init --recursive
- run:
name: Clean Build
command: ./build.sh Clean
- run:
name: Restore Nuget
command: ./build.sh NugetMono
- run:
name: Build
command: ./build.sh Build
- run:
name: Gulp
command: ./build.sh Gulp
- run:
name: Package
command: ./build.sh Package
- run:
name: Preparing Tests
command: mkdir _tests/reports
- run:
name: Testing
command: ./test.sh Linux Unit
- store_test_results:
path: _tests/reports/
- store_artifacts:
path: _output
- store_artifacts:
path: _output_mono
- store_artifacts:
path: _output_osx
- store_artifacts:
path: _output_osx_app

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/test-run">
<testsuites tests="{@testcasecount}" failures="{@failed}" disabled="{@skipped}" time="{@duration}">
<xsl:apply-templates/>
</testsuites>
</xsl:template>
<xsl:template match="test-suite">
<xsl:if test="test-case">
<testsuite tests="{@testcasecount}" time="{@duration}" errors="{@testcasecount - @passed - @skipped - @failed}" failures="{@failed}" skipped="{@skipped}" timestamp="{@start-time}">
<xsl:attribute name="name">
<xsl:for-each select="ancestor-or-self::test-suite/@name">
<xsl:value-of select="concat(., '.')"/>
</xsl:for-each>
</xsl:attribute>
<xsl:apply-templates select="test-case"/>
</testsuite>
<xsl:apply-templates select="test-suite"/>
</xsl:if>
<xsl:if test="not(test-case)">
<xsl:apply-templates/>
</xsl:if>
</xsl:template>
<xsl:template match="test-case">
<testcase name="{@name}" assertions="{@asserts}" time="{@duration}" status="{@result}" classname="{@classname}">
<xsl:if test="@runstate = 'Skipped' or @runstate = 'Ignored'">
<skipped/>
</xsl:if>
<xsl:apply-templates/>
</testcase>
</xsl:template>
<xsl:template match="command-line"/>
<xsl:template match="settings"/>
<xsl:template match="output">
<system-out>
<xsl:value-of select="."/>
</system-out>
</xsl:template>
<xsl:template match="stack-trace">
</xsl:template>
<xsl:template match="test-case/failure">
<failure message="{./message}">
<xsl:value-of select="./stack-trace"/>
</failure>
</xsl:template>
<xsl:template match="test-suite/failure"/>
<xsl:template match="test-case/reason">
<skipped message="{./message}"/>
</xsl:template>
<xsl:template match="test-case/assertions">
</xsl:template>
<xsl:template match="test-suite/reason"/>
<xsl:template match="properties"/>
</xsl:stylesheet>

View File

@@ -82,7 +82,7 @@ ignore_regexps = [
## whenever you are tweaking this variable.
##
section_regexps = [
('**New Features**', [
('**New features**', [
r'^[aA]dded?\s*:?\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
r'^[uU]pdated?\s*:?\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
r'^[cC]hanged?\s*:?\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',

View File

@@ -4,13 +4,17 @@ Check first that your problem is not listed in our wiki section:
* https://github.com/Radarr/Radarr/wiki/Common-Problems
* https://github.com/Radarr/Radarr/wiki/FAQ
**Just because you receive an exception in your logs, doesn't mean it's a bug and should be reported here. Often it's something else, such as a permission error. If you are unsure ask on the Discord or Subreddit first.**
Visit our [Discord server](https://discord.gg/NWYch8M) or [Subreddit](https://reddit.com/r/radarr) for support or longer discussions. Support questions posed on here will be closed immediately.
Provide a description of the feature request or bug here, the more details the better.
Please also try to include the following if you are reporting a bug
Please also include the following if you are reporting a bug. If you do not include it, the issue will probably be closed as we cannot help you.
**Radarr Version:**
**Logs:**
**Mono Version:**
**Debug Logs:**
Please use the search bar and make sure you are not submitting an already submitted issue.
Visit our [Discord server](https://discord.gg/NWYch8M) for support or longer discussions.

6
.gitignore vendored
View File

@@ -148,5 +148,9 @@ _temp_*/**/*
Thumbs.db
# AppVeyor
/tools-cake/
/tools/cake/
/_artifacts/
# Cake
/tools/Addins/*
packages.config.md5sum

File diff suppressed because it is too large Load Diff

674
LICENSE Normal file
View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@@ -50,6 +50,13 @@ The project was inspired by other Usenet/BitTorrent movie downloaders such as Co
| 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) |
### [Site and API Status](https://status.radarr.video)
| API | Updates | Sites |
|-------|:----:|:----:|
| [![API V2](http://status.radarr.video/component/1/shield?style=flat-square)](https://api.radarr.video/v2/) | [![Update Server](http://status.radarr.video/component/4/shield?style=flat-square)](https://radarr.aeonlucid.com) | [![Radarr Mappings](http://status.radarr.video/component/6/shield?style=flat-square)](https://mappings.radarr.video/)
| [![API Staging](http://status.radarr.video/component/2/shield?style=flat-square)](https://staging.api.radarr.video/) | [![Github Updates](http://status.radarr.video/component/5/shield?style=flat-square)](https://api.github.com/v3/) | [![Main Site](http://status.radarr.video/component/7/shield?style=flat-square)](https://radarr.video/)
Radarr is currently undergoing rapid development and pull requests are actively added into the repository.
## Features
@@ -78,7 +85,7 @@ Radarr is currently undergoing rapid development and pull requests are actively
### Planned Features
* Downloading Metadata such as trailers or subtitles (\*)
* Importing Metadata such as trailers or subtitles (\*)
* Adding metadata such as posters and information for Kodi and others to use (\*)
* Dynamically renaming folders with quality info, etc. (\*)
* Supporting custom folder structures, such as all movie files in one folder (\*)
@@ -108,10 +115,17 @@ Radarr is currently undergoing rapid development and pull requests are actively
> **Notice**
> Gulp must be running at all times while you are working with Radarr client source files.
### Build
* To build run `sh build.sh`
**Note:** Windows users must have bash available to do this. [cmder](http://cmder.net/) which is a console emulator for windows has bash as part of it's default installation.
### 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
* Run `build.sh` before running
### License

View File

@@ -32,7 +32,7 @@ artifacts:
cache:
- '%USERPROFILE%\.nuget\packages'
- node_modules
- node_modules -> package.json
pull_requests:
do_not_increment_build_number: true

View File

@@ -1,6 +1,6 @@
#addin "Cake.Npm"
#addin "SharpZipLib"
#addin "Cake.Compression"
#addin nuget:?package=Cake.Npm&version=0.12.1
#addin nuget:?package=SharpZipLib&version=0.86.0
#addin nuget:?package=Cake.Compression&version=0.1.4
// Build variables
var outputFolder = "./_output";

View File

@@ -81,8 +81,8 @@ if(!$PSScriptRoot){
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
}
$TOOLS_DIR = Join-Path $PSScriptRoot "tools-cake"
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget/nuget.exe"
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
@@ -156,7 +156,12 @@ if(-Not $SkipToolPackageRestore.IsPresent) {
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
Write-Verbose -Message "Missing or changed package.config hash..."
Remove-Item * -Recurse -Exclude packages.config,nuget.exe
Get-ChildItem -Path $TOOLS_DIR -Recurse -Exclude packages.config |
Select -ExpandProperty FullName |
Where {$_ -notlike (Join-Path $TOOLS_DIR "pdb2mdb*")} |
Where {$_ -notlike (Join-Path $TOOLS_DIR "nuget*")} |
sort length -Descending |
Remove-Item -Recurse
}
Write-Verbose -Message "Restoring tools from NuGet..."
@@ -181,4 +186,4 @@ if (!(Test-Path $CAKE_EXE)) {
# Start Cake
Write-Host "Running build script..."
Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs"
exit $LASTEXITCODE
exit $LASTEXITCODE

View File

@@ -69,11 +69,21 @@ BuildWithMSBuild()
CheckExitCode MSBuild.exe $slnFile //p:Configuration=Release //p:Platform=x86 //t:Build //m //p:AllowedReferenceRelatedFileExtensions=.pdb
}
BuildWithXbuild()
RestoreNuget()
{
export MONO_IOMAP=case
mono $nuget restore $slnFile
}
CleanWithXbuild()
{
export MONO_IOMAP=case
CheckExitCode xbuild /t:Clean $slnFile
mono $nuget restore $slnFile
}
BuildWithXbuild()
{
export MONO_IOMAP=case
CheckExitCode xbuild /p:Configuration=Release /p:Platform=x86 /t:Build /p:AllowedReferenceRelatedFileExtensions=.pdb $slnFile
}
@@ -86,6 +96,8 @@ Build()
if [ $runtime = "dotnet" ] ; then
BuildWithMSBuild
else
CleanWithXbuild
RestoreNuget
BuildWithXbuild
fi
@@ -256,10 +268,42 @@ case "$(uname -s)" in
;;
esac
Build
RunGulp
PackageMono
PackageOsx
PackageOsxApp
PackageTests
CleanupWindowsPackage
if [ $# -eq 0 ]
then
Build
RunGulp
PackageMono
PackageOsx
PackageOsxApp
PackageTests
CleanupWindowsPackage
fi
if [ "$1" = "CleanXbuild" ]
then rm -rf $outputFolder
CleanWithXbuild
fi
if [ "$1" = "NugetMono" ]
then rm -rf $outputFolder
RestoreNuget
fi
if [ "$1" = "Build" ]
then BuildWithXbuild
CleanFolder $outputFolder false
AddJsonNet
rm $outputFolder/Mono.Posix.dll
fi
if [ "$1" = "Gulp" ]
then RunGulp
fi
if [ "$1" = "Package" ]
then PackageMono
PackageOsx
PackageOsxApp
PackageTests
CleanupWindowsPackage
fi

View File

@@ -5,11 +5,10 @@
{{#sections}}
### {{{label}}}
{{#commits}}
- {{{subject}}} [{{{author}}}]
{{/commits}}
{{/sections}}
{{/versions}}

View File

@@ -19,7 +19,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Sonarr</string>
<string>Radarr</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>

View File

@@ -17,10 +17,10 @@ case "$(uname -s)" in
esac
if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
VERSION="`date +%H:%M:%S`"
YEAR="`date +%Y`"
MONTH="`date +%m`"
DAY="`date +%d`"
VERSION="$(date +%H:%M:%S)"
YEAR="$(date +%Y)"
MONTH="$(date +%m)"
DAY="$(date +%d)"
else
VERSION=$1
BRANCH=$2

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ContentModelUserStore">
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@@ -1,97 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9DC31DE3-79FF-47A8-96B4-6BA18F6BB1CB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LogentriesNLog</RootNamespace>
<AssemblyName>LogentriesNLog</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="fastJSON\Getters.cs" />
<Compile Include="fastJSON\JSON.cs" />
<Compile Include="fastJSON\JsonParser.cs" />
<Compile Include="fastJSON\JsonSerializer.cs" />
<Compile Include="fastJSON\SafeDictionary.cs" />
<Compile Include="LogentriesTarget.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LogentriesCore\LogentriesCore.csproj">
<Project>{90D6E9FC-7B88-4E1B-B018-8FA742274558}</Project>
<Name>LogentriesCore</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="fastJSON\license.txt" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9DC31DE3-79FF-47A8-96B4-6BA18F6BB1CB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LogentriesNLog</RootNamespace>
<AssemblyName>LogentriesNLog</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.5.0-rc06\lib\net40-client\NLog.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="fastJSON\Getters.cs" />
<Compile Include="fastJSON\JSON.cs" />
<Compile Include="fastJSON\JsonParser.cs" />
<Compile Include="fastJSON\JsonSerializer.cs" />
<Compile Include="fastJSON\SafeDictionary.cs" />
<Compile Include="LogentriesTarget.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LogentriesCore\LogentriesCore.csproj">
<Project>{90D6E9FC-7B88-4E1B-B018-8FA742274558}</Project>
<Name>LogentriesCore</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="fastJSON\license.txt" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
-->
</Project>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NLog" version="4.3.11" targetFramework="net40" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NLog" version="4.5.0-rc06" targetFramework="net40" />
</packages>

View File

@@ -96,7 +96,7 @@ namespace MonoTorrent.BEncoding
if (stream == null)
throw new ArgumentNullException("stream");
return Decode(new RawReader(stream));
return Decode(new RawReader(stream, false));
}

View File

@@ -1,9 +1,8 @@
using System;
using System;
using System.Collections.Generic;
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Api.REST;
using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series;
using NzbDrone.Core.Indexers;
namespace NzbDrone.Api.Blacklist
@@ -20,7 +19,6 @@ namespace NzbDrone.Api.Blacklist
public string Indexer { get; set; }
public string Message { get; set; }
public MovieResource Movie { get; set; }
public SeriesResource Series { get; set; }
}
public static class BlacklistResourceMapper
@@ -41,8 +39,7 @@ namespace NzbDrone.Api.Blacklist
Protocol = model.Protocol,
Indexer = model.Indexer,
Message = model.Message,
Movie = model.Movie.ToResource(),
Series = model.Series.ToResource()
Movie = model.Movie.ToResource()
};
}
}

View File

@@ -1,9 +1,10 @@
using Nancy;
using Nancy;
using System;
using System.Collections.Generic;
using System.Linq;
using Ical.Net;
using Ical.Net.DataTypes;
using Ical.Net.General;
using Ical.Net.Interfaces.Serialization;
using Ical.Net.Serialization;
using Ical.Net.Serialization.iCalendar.Factory;
@@ -86,6 +87,10 @@ namespace NzbDrone.Api.Calendar
ProductId = "-//radarr.video//Radarr//EN"
};
var calendarName = "Radarr Movies Calendar";
calendar.AddProperty(new CalendarProperty("NAME", calendarName));
calendar.AddProperty(new CalendarProperty("X-WR-CALNAME", calendarName));
foreach (var movie in movies.OrderBy(v => v.Added))
{
if (tags.Any() && tags.None(movie.Tags.Contains))
@@ -114,8 +119,10 @@ namespace NzbDrone.Api.Calendar
occurrence.End = new CalDateTime(movie.InCinemas.Value.AddMinutes(movie.Runtime)) { HasTime = true };
}
break;
case MovieStatusType.Announced:
continue; // no date
default:
if (movie.PhysicalRelease != null)
{

View File

@@ -1,10 +1,8 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Nancy;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.Movie;
using NzbDrone.Api.Series;
using NzbDrone.Api.Movies;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MediaFiles;
@@ -17,7 +15,6 @@ using NzbDrone.Core.Validation.Paths;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.Validation;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv;
using NzbDrone.SignalR;
namespace NzbDrone.Api.Calendar

View File

@@ -41,6 +41,16 @@ namespace NzbDrone.Api.ClientSchema
};
var value = propertyInfo.GetValue(model, null);
if (propertyInfo.PropertyType.HasAttribute<FlagsAttribute>())
{
int intVal = (int)value;
value = Enum.GetValues(propertyInfo.PropertyType)
.Cast<int>()
.Where(f=> (f & intVal) == f)
.ToList();
}
if (value != null)
{
field.Value = value;
@@ -131,6 +141,12 @@ namespace NzbDrone.Api.ClientSchema
propertyInfo.SetValue(target, value, null);
}
else if (propertyInfo.PropertyType.HasAttribute<FlagsAttribute>())
{
int value = field.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToInt32(s)).Sum();
propertyInfo.SetValue(target, value, null);
}
else
{

View File

@@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using NzbDrone.Api.REST;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles;
@@ -22,6 +22,7 @@ namespace NzbDrone.Api.Config
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
public bool CopyUsingHardlinks { get; set; }
public bool ImportExtraFiles { get; set; }
public string ExtraFileExtensions { get; set; }
public bool EnableMediaInfo { get; set; }
}
@@ -48,6 +49,7 @@ namespace NzbDrone.Api.Config
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
CopyUsingHardlinks = model.CopyUsingHardlinks,
ImportExtraFiles = model.ImportExtraFiles,
ExtraFileExtensions = model.ExtraFileExtensions,
EnableMediaInfo = model.EnableMediaInfo
};

View File

@@ -1,88 +0,0 @@
using System.Collections.Generic;
using System.IO;
using NLog;
using NzbDrone.Api.REST;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.SignalR;
namespace NzbDrone.Api.EpisodeFiles
{
public class EpisodeFileModule : NzbDroneRestModuleWithSignalR<EpisodeFileResource, EpisodeFile>,
IHandle<EpisodeFileAddedEvent>
{
private readonly IMediaFileService _mediaFileService;
private readonly IRecycleBinProvider _recycleBinProvider;
private readonly ISeriesService _seriesService;
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
private readonly Logger _logger;
public EpisodeFileModule(IBroadcastSignalRMessage signalRBroadcaster,
IMediaFileService mediaFileService,
IRecycleBinProvider recycleBinProvider,
ISeriesService seriesService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
Logger logger)
: base(signalRBroadcaster)
{
_mediaFileService = mediaFileService;
_recycleBinProvider = recycleBinProvider;
_seriesService = seriesService;
_qualityUpgradableSpecification = qualityUpgradableSpecification;
_logger = logger;
GetResourceById = GetEpisodeFile;
GetResourceAll = GetEpisodeFiles;
UpdateResource = SetQuality;
DeleteResource = DeleteEpisodeFile;
}
private EpisodeFileResource GetEpisodeFile(int id)
{
var episodeFile = _mediaFileService.Get(id);
var series = _seriesService.GetSeries(episodeFile.SeriesId);
return episodeFile.ToResource(series, _qualityUpgradableSpecification);
}
private List<EpisodeFileResource> GetEpisodeFiles()
{
if (!Request.Query.SeriesId.HasValue)
{
throw new BadRequestException("seriesId is missing");
}
var seriesId = (int)Request.Query.SeriesId;
var series = _seriesService.GetSeries(seriesId);
return _mediaFileService.GetFilesBySeries(seriesId).ConvertAll(f => f.ToResource(series, _qualityUpgradableSpecification));
}
private void SetQuality(EpisodeFileResource episodeFileResource)
{
var episodeFile = _mediaFileService.Get(episodeFileResource.Id);
episodeFile.Quality = episodeFileResource.Quality;
_mediaFileService.Update(episodeFile);
}
private void DeleteEpisodeFile(int id)
{
var episodeFile = _mediaFileService.Get(id);
var series = _seriesService.GetSeries(episodeFile.SeriesId);
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
_logger.Info("Deleting episode file: {0}", fullPath);
_recycleBinProvider.DeleteFile(fullPath);
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
}
public void Handle(EpisodeFileAddedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
}
}
}

View File

@@ -1,64 +0,0 @@
using System;
using System.IO;
using NzbDrone.Api.REST;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Api.EpisodeFiles
{
public class EpisodeFileResource : RestResource
{
public int SeriesId { get; set; }
public int SeasonNumber { get; set; }
public string RelativePath { get; set; }
public string Path { get; set; }
public long Size { get; set; }
public DateTime DateAdded { get; set; }
public string SceneName { get; set; }
public QualityModel Quality { get; set; }
public bool QualityCutoffNotMet { get; set; }
}
public static class EpisodeFileResourceMapper
{
private static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model)
{
if (model == null) return null;
return new EpisodeFileResource
{
Id = model.Id,
SeriesId = model.SeriesId,
SeasonNumber = model.SeasonNumber,
RelativePath = model.RelativePath,
//Path
Size = model.Size,
DateAdded = model.DateAdded,
SceneName = model.SceneName,
Quality = model.Quality,
//QualityCutoffNotMet
};
}
public static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model, Core.Tv.Series series, Core.DecisionEngine.IQualityUpgradableSpecification qualityUpgradableSpecification)
{
if (model == null) return null;
return new EpisodeFileResource
{
Id = model.Id,
SeriesId = model.SeriesId,
SeasonNumber = model.SeasonNumber,
RelativePath = model.RelativePath,
Path = Path.Combine(series.Path, model.RelativePath),
Size = model.Size,
DateAdded = model.DateAdded,
SceneName = model.SceneName,
Quality = model.Quality,
QualityCutoffNotMet = qualityUpgradableSpecification.CutoffNotMet(series.Profile.Value, model.Quality)
};
}
}
}

View File

@@ -1,41 +0,0 @@
using System.Collections.Generic;
using NzbDrone.Api.REST;
using NzbDrone.Core.Tv;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.SignalR;
using Nancy;
namespace NzbDrone.Api.Episodes
{
public class EpisodeModule : EpisodeModuleWithSignalR
{
public EpisodeModule(ISeriesService seriesService,
IEpisodeService episodeService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
IBroadcastSignalRMessage signalRBroadcaster)
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster)
{
GetResourceAll = GetEpisodes;
UpdateResource = SetMonitored;
}
private List<EpisodeResource> GetEpisodes()
{
if (!Request.Query.SeriesId.HasValue)
{
throw new BadRequestException("seriesId is missing");
}
var seriesId = (int)Request.Query.SeriesId;
var resources = MapToResource(_episodeService.GetEpisodeBySeries(seriesId), false, true);
return resources;
}
private void SetMonitored(EpisodeResource episodeResource)
{
_episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored);
}
}
}

View File

@@ -1,126 +0,0 @@
using System.Collections.Generic;
using NzbDrone.Common.Extensions;
using NzbDrone.Api.EpisodeFiles;
using NzbDrone.Api.Series;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv;
using NzbDrone.SignalR;
namespace NzbDrone.Api.Episodes
{
public abstract class EpisodeModuleWithSignalR : NzbDroneRestModuleWithSignalR<EpisodeResource, Episode>,
IHandle<EpisodeGrabbedEvent>,
IHandle<EpisodeDownloadedEvent>
{
protected readonly IEpisodeService _episodeService;
protected readonly ISeriesService _seriesService;
protected readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
protected EpisodeModuleWithSignalR(IEpisodeService episodeService,
ISeriesService seriesService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
IBroadcastSignalRMessage signalRBroadcaster)
: base(signalRBroadcaster)
{
_episodeService = episodeService;
_seriesService = seriesService;
_qualityUpgradableSpecification = qualityUpgradableSpecification;
GetResourceById = GetEpisode;
}
protected EpisodeModuleWithSignalR(IEpisodeService episodeService,
ISeriesService seriesService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
IBroadcastSignalRMessage signalRBroadcaster,
string resource)
: base(signalRBroadcaster, resource)
{
_episodeService = episodeService;
_seriesService = seriesService;
_qualityUpgradableSpecification = qualityUpgradableSpecification;
GetResourceById = GetEpisode;
}
protected EpisodeResource GetEpisode(int id)
{
var episode = _episodeService.GetEpisode(id);
var resource = MapToResource(episode, true, true);
return resource;
}
protected EpisodeResource MapToResource(Episode episode, bool includeSeries, bool includeEpisodeFile)
{
var resource = episode.ToResource();
if (includeSeries || includeEpisodeFile)
{
var series = episode.Series ?? _seriesService.GetSeries(episode.SeriesId);
if (includeSeries)
{
resource.Series = series.ToResource();
}
if (includeEpisodeFile && episode.EpisodeFileId != 0)
{
resource.EpisodeFile = episode.EpisodeFile.Value.ToResource(series, _qualityUpgradableSpecification);
}
}
return resource;
}
protected List<EpisodeResource> MapToResource(List<Episode> episodes, bool includeSeries, bool includeEpisodeFile)
{
var result = episodes.ToResource();
if (includeSeries || includeEpisodeFile)
{
var seriesDict = new Dictionary<int, Core.Tv.Series>();
for (var i = 0; i < episodes.Count; i++)
{
var episode = episodes[i];
var resource = result[i];
var series = episode.Series ?? seriesDict.GetValueOrDefault(episodes[i].SeriesId) ?? _seriesService.GetSeries(episodes[i].SeriesId);
seriesDict[series.Id] = series;
if (includeSeries)
{
resource.Series = series.ToResource();
}
if (includeEpisodeFile && episodes[i].EpisodeFileId != 0)
{
resource.EpisodeFile = episodes[i].EpisodeFile.Value.ToResource(series, _qualityUpgradableSpecification);
}
}
}
return result;
}
public void Handle(EpisodeGrabbedEvent message)
{
foreach (var episode in message.Episode.Episodes)
{
var resource = episode.ToResource();
resource.Grabbed = true;
BroadcastResourceChange(ModelAction.Updated, resource);
}
}
public void Handle(EpisodeDownloadedEvent message)
{
foreach (var episode in message.Episode.Episodes)
{
BroadcastResourceChange(ModelAction.Updated, episode.Id);
}
}
}
}

View File

@@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using NzbDrone.Api.EpisodeFiles;
using NzbDrone.Api.REST;
using NzbDrone.Api.Series;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Episodes
{
public class EpisodeResource : RestResource
{
public int SeriesId { get; set; }
public int EpisodeFileId { get; set; }
public int SeasonNumber { get; set; }
public int EpisodeNumber { get; set; }
public string Title { get; set; }
public string AirDate { get; set; }
public DateTime? AirDateUtc { get; set; }
public string Overview { get; set; }
public EpisodeFileResource EpisodeFile { get; set; }
public bool HasFile { get; set; }
public bool Monitored { get; set; }
public int? AbsoluteEpisodeNumber { get; set; }
public int? SceneAbsoluteEpisodeNumber { get; set; }
public int? SceneEpisodeNumber { get; set; }
public int? SceneSeasonNumber { get; set; }
public bool UnverifiedSceneNumbering { get; set; }
public string SeriesTitle { get; set; }
public SeriesResource Series { get; set; }
//Hiding this so people don't think its usable (only used to set the initial state)
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public bool Grabbed { get; set; }
}
public static class EpisodeResourceMapper
{
public static EpisodeResource ToResource(this Episode model)
{
if (model == null) return null;
return new EpisodeResource
{
Id = model.Id,
SeriesId = model.SeriesId,
EpisodeFileId = model.EpisodeFileId,
SeasonNumber = model.SeasonNumber,
EpisodeNumber = model.EpisodeNumber,
Title = model.Title,
AirDate = model.AirDate,
AirDateUtc = model.AirDateUtc,
Overview = model.Overview,
//EpisodeFile
HasFile = model.HasFile,
Monitored = model.Monitored,
AbsoluteEpisodeNumber = model.AbsoluteEpisodeNumber,
SceneAbsoluteEpisodeNumber = model.SceneAbsoluteEpisodeNumber,
SceneEpisodeNumber = model.SceneEpisodeNumber,
SceneSeasonNumber = model.SceneSeasonNumber,
UnverifiedSceneNumbering = model.UnverifiedSceneNumbering,
SeriesTitle = model.SeriesTitle,
//Series = model.Series.MapToResource(),
};
}
public static List<EpisodeResource> ToResource(this IEnumerable<Episode> models)
{
if (models == null) return null;
return models.Select(ToResource).ToList();
}
}
}

View File

@@ -1,37 +0,0 @@
using System.Collections.Generic;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaFiles;
namespace NzbDrone.Api.Episodes
{
public class RenameEpisodeModule : NzbDroneRestModule<RenameEpisodeResource>
{
private readonly IRenameEpisodeFileService _renameEpisodeFileService;
public RenameEpisodeModule(IRenameEpisodeFileService renameEpisodeFileService)
: base("rename")
{
_renameEpisodeFileService = renameEpisodeFileService;
GetResourceAll = GetEpisodes;
}
private List<RenameEpisodeResource> GetEpisodes()
{
if (!Request.Query.SeriesId.HasValue)
{
throw new BadRequestException("seriesId is missing");
}
var seriesId = (int)Request.Query.SeriesId;
if (Request.Query.SeasonNumber.HasValue)
{
var seasonNumber = (int)Request.Query.SeasonNumber;
return _renameEpisodeFileService.GetRenamePreviews(seriesId, seasonNumber).ToResource();
}
return _renameEpisodeFileService.GetRenamePreviews(seriesId).ToResource();
}
}
}

View File

@@ -1,39 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
namespace NzbDrone.Api.Episodes
{
public class RenameEpisodeResource : RestResource
{
public int SeriesId { get; set; }
public int SeasonNumber { get; set; }
public List<int> EpisodeNumbers { get; set; }
public int EpisodeFileId { get; set; }
public string ExistingPath { get; set; }
public string NewPath { get; set; }
}
public static class RenameEpisodeResourceMapper
{
public static RenameEpisodeResource ToResource(this Core.MediaFiles.RenameEpisodeFilePreview model)
{
if (model == null) return null;
return new RenameEpisodeResource
{
SeriesId = model.SeriesId,
SeasonNumber = model.SeasonNumber,
EpisodeNumbers = model.EpisodeNumbers.ToList(),
EpisodeFileId = model.EpisodeFileId,
ExistingPath = model.ExistingPath,
NewPath = model.NewPath
};
}
public static List<RenameEpisodeResource> ToResource(this IEnumerable<Core.MediaFiles.RenameEpisodeFilePreview> models)
{
return models.Select(ToResource).ToList();
}
}
}

View File

@@ -23,6 +23,8 @@ namespace NzbDrone.Api.Extensions.Pipelines
private void Handle(NancyContext context)
{
if (context.Request.Method == "OPTIONS") return;
if (_cacheableSpecification.IsCacheable(context))
{
context.Response.Headers.EnableCache();
@@ -33,4 +35,4 @@ namespace NzbDrone.Api.Extensions.Pipelines
}
}
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Linq;
using Nancy;
using Nancy.Bootstrapper;
using NzbDrone.Common.Extensions;
namespace NzbDrone.Api.Extensions.Pipelines
{
@@ -11,10 +12,25 @@ namespace NzbDrone.Api.Extensions.Pipelines
public void Register(IPipelines pipelines)
{
pipelines.AfterRequest.AddItemToEndOfPipeline((Action<NancyContext>) Handle);
pipelines.BeforeRequest.AddItemToEndOfPipeline(HandleRequest);
pipelines.AfterRequest.AddItemToEndOfPipeline(HandleResponse);
}
private void Handle(NancyContext context)
private Response HandleRequest(NancyContext context)
{
if (context == null || context.Request.Method != "OPTIONS")
{
return null;
}
var response = new Response()
.WithStatusCode(HttpStatusCode.OK)
.WithContentType("");
ApplyResponseHeaders(response, context.Request);
return response;
}
private void HandleResponse(NancyContext context)
{
if (context == null || context.Response.Headers.ContainsKey(AccessControlHeaders.AllowOrigin))
{
@@ -26,21 +42,39 @@ namespace NzbDrone.Api.Extensions.Pipelines
private static void ApplyResponseHeaders(Response response, Request request)
{
var allowedMethods = "GET, OPTIONS, PATCH, POST, PUT, DELETE";
if (response.Headers.ContainsKey("Allow"))
if (request.IsApiRequest())
{
allowedMethods = response.Headers["Allow"];
// Allow Cross-Origin access to the API since it's protected with the apikey, and nothing else.
ApplyCorsResponseHeaders(response, request, "*", "GET, OPTIONS, PATCH, POST, PUT, DELETE");
}
var requestedHeaders = string.Join(", ", request.Headers[AccessControlHeaders.RequestHeaders]);
response.Headers.Add(AccessControlHeaders.AllowOrigin, "*");
response.Headers.Add(AccessControlHeaders.AllowMethods, allowedMethods);
if (request.Headers[AccessControlHeaders.RequestHeaders].Any())
else if (request.IsSharedContentRequest())
{
response.Headers.Add(AccessControlHeaders.AllowHeaders, requestedHeaders);
// Allow Cross-Origin access to specific shared content such as mediacovers and images.
ApplyCorsResponseHeaders(response, request, "*", "GET, OPTIONS");
}
// Disallow Cross-Origin access for any other route.
}
private static void ApplyCorsResponseHeaders(Response response, Request request, string allowOrigin, string allowedMethods)
{
response.Headers.Add(AccessControlHeaders.AllowOrigin, allowOrigin);
if (request.Method == "OPTIONS")
{
if (response.Headers.ContainsKey("Allow"))
{
allowedMethods = response.Headers["Allow"];
}
response.Headers.Add(AccessControlHeaders.AllowMethods, allowedMethods);
if (request.Headers[AccessControlHeaders.RequestHeaders].Any())
{
var requestedHeaders = string.Join(", ", request.Headers[AccessControlHeaders.RequestHeaders]);
response.Headers.Add(AccessControlHeaders.AllowHeaders, requestedHeaders);
}
}
}
}

View File

@@ -33,7 +33,8 @@ namespace NzbDrone.Api.Extensions.Pipelines
try
{
if (
!response.ContentType.Contains("image")
response.Contents != Response.NoBody
&& !response.ContentType.Contains("image")
&& !response.ContentType.Contains("font")
&& request.Headers.AcceptEncoding.Any(x => x.Contains("gzip"))
&& !AlreadyGzipEncoded(response)
@@ -80,4 +81,4 @@ namespace NzbDrone.Api.Extensions.Pipelines
return false;
}
}
}
}

View File

@@ -36,5 +36,11 @@ namespace NzbDrone.Api.Extensions
{
return request.Path.StartsWith("/Content/", StringComparison.InvariantCultureIgnoreCase);
}
public static bool IsSharedContentRequest(this Request request)
{
return request.Path.StartsWith("/MediaCover/", StringComparison.InvariantCultureIgnoreCase) ||
request.Path.StartsWith("/Content/Images/", StringComparison.InvariantCultureIgnoreCase);
}
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
using NzbDrone.Api.REST;
using NzbDrone.Core.Extras.Files;
using NzbDrone.Core.Extras.Metadata.Files;
using NzbDrone.Core.Extras.Others;
using NzbDrone.Core.Extras.Subtitles;
namespace NzbDrone.Api.ExtraFiles
{
public class ExtraFileModule : NzbDroneRestModule<ExtraFileResource>
{
private readonly IExtraFileService<SubtitleFile> _subtitleFileService;
private readonly IExtraFileService<MetadataFile> _metadataFileService;
private readonly IExtraFileService<OtherExtraFile> _otherFileService;
public ExtraFileModule(IExtraFileService<SubtitleFile> subtitleFileService, IExtraFileService<MetadataFile> metadataFileService, IExtraFileService<OtherExtraFile> otherExtraFileService)
: base("/extrafile")
{
_subtitleFileService = subtitleFileService;
_metadataFileService = metadataFileService;
_otherFileService = otherExtraFileService;
GetResourceAll = GetFiles;
}
private List<ExtraFileResource> GetFiles()
{
if (!Request.Query.MovieId.HasValue)
{
throw new BadRequestException("MovieId is missing");
}
var extraFiles = new List<ExtraFileResource>();
List<SubtitleFile> subtitleFiles = _subtitleFileService.GetFilesByMovie(Request.Query.MovieId);
List<MetadataFile> metadataFiles = _metadataFileService.GetFilesByMovie(Request.Query.MovieId);
List<OtherExtraFile> otherExtraFiles = _otherFileService.GetFilesByMovie(Request.Query.MovieId);
extraFiles.AddRange(subtitleFiles.ToResource());
extraFiles.AddRange(metadataFiles.ToResource());
extraFiles.AddRange(otherExtraFiles.ToResource());
return extraFiles;
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.Extras.Files;
using NzbDrone.Core.Extras.Metadata.Files;
using NzbDrone.Core.Extras.Others;
using NzbDrone.Core.Extras.Subtitles;
namespace NzbDrone.Api.ExtraFiles
{
public class ExtraFileResource : RestResource
{
public int MovieId { get; set; }
public int? MovieFileId { get; set; }
public string RelativePath { get; set; }
public string Extension { get; set; }
public ExtraFileType Type { get; set; }
}
public static class ExtraFileResourceMapper
{
public static ExtraFileResource ToResource(this MetadataFile model)
{
if (model == null) return null;
return new ExtraFileResource
{
Id = model.Id,
MovieId = model.MovieId,
MovieFileId = model.MovieFileId,
RelativePath = model.RelativePath,
Extension = model.Extension,
Type = ExtraFileType.Metadata
};
}
public static ExtraFileResource ToResource(this SubtitleFile model)
{
if (model == null) return null;
return new ExtraFileResource
{
Id = model.Id,
MovieId = model.MovieId,
MovieFileId = model.MovieFileId,
RelativePath = model.RelativePath,
Extension = model.Extension,
Type = ExtraFileType.Subtitle
};
}
public static ExtraFileResource ToResource(this OtherExtraFile model)
{
if (model == null) return null;
return new ExtraFileResource
{
Id = model.Id,
MovieId = model.MovieId,
MovieFileId = model.MovieFileId,
RelativePath = model.RelativePath,
Extension = model.Extension,
Type = ExtraFileType.Other
};
}
public static List<ExtraFileResource> ToResource(this IEnumerable<SubtitleFile> movies)
{
return movies.Select(ToResource).ToList();
}
public static List<ExtraFileResource> ToResource(this IEnumerable<MetadataFile> movies)
{
return movies.Select(ToResource).ToList();
}
public static List<ExtraFileResource> ToResource(this IEnumerable<OtherExtraFile> movies)
{
return movies.Select(ToResource).ToList();
}
}
}

View File

@@ -49,7 +49,12 @@ namespace NzbDrone.Api.Frontend.Mappers
public override bool CanHandle(string resourceUrl)
{
return !resourceUrl.Contains(".") && !resourceUrl.StartsWith("/login");
resourceUrl = resourceUrl.ToLowerInvariant();
return !resourceUrl.StartsWith("/content") &&
!resourceUrl.StartsWith("/mediacover") &&
!resourceUrl.Contains(".") &&
!resourceUrl.StartsWith("/login");
}
public override Response GetResponse(string resourceUrl)
@@ -113,4 +118,4 @@ namespace NzbDrone.Api.Frontend.Mappers
return _generatedContent;
}
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using NLog;
@@ -42,7 +43,7 @@ namespace NzbDrone.Api.Frontend.Mappers
public override bool CanHandle(string resourceUrl)
{
return resourceUrl.StartsWith("/MediaCover");
return resourceUrl.StartsWith("/MediaCover", StringComparison.InvariantCultureIgnoreCase);
}
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.IO;
using NLog;
using NzbDrone.Common.Disk;
@@ -28,7 +29,9 @@ namespace NzbDrone.Api.Frontend.Mappers
public override bool CanHandle(string resourceUrl)
{
return resourceUrl.StartsWith("/Content") ||
resourceUrl = resourceUrl.ToLowerInvariant();
return resourceUrl.StartsWith("/content") ||
resourceUrl.EndsWith(".js") ||
resourceUrl.EndsWith(".map") ||
resourceUrl.EndsWith(".css") ||
@@ -37,4 +40,4 @@ namespace NzbDrone.Api.Frontend.Mappers
resourceUrl.EndsWith("oauth.html");
}
}
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Nancy.Responses;
using NLog;
using Nancy;
using NzbDrone.Api.Frontend.Mappers;

View File

@@ -1,7 +1,7 @@
using System;
using System;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;

View File

@@ -1,9 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.REST;
using NzbDrone.Api.Series;
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Core.History;
using NzbDrone.Core.Qualities;
@@ -12,9 +10,7 @@ namespace NzbDrone.Api.History
{
public class HistoryResource : RestResource
{
public int EpisodeId { get; set; }
public int MovieId { get; set; }
public int SeriesId { get; set; }
public string SourceTitle { get; set; }
public QualityModel Quality { get; set; }
public bool QualityCutoffNotMet { get; set; }
@@ -25,8 +21,6 @@ namespace NzbDrone.Api.History
public Dictionary<string, string> Data { get; set; }
public MovieResource Movie { get; set; }
public EpisodeResource Episode { get; set; }
public SeriesResource Series { get; set; }
}
public static class HistoryResourceMapper
@@ -38,9 +32,6 @@ namespace NzbDrone.Api.History
return new HistoryResource
{
Id = model.Id,
EpisodeId = model.EpisodeId,
SeriesId = model.SeriesId,
MovieId = model.MovieId,
SourceTitle = model.SourceTitle,
Quality = model.Quality,
@@ -51,8 +42,6 @@ namespace NzbDrone.Api.History
EventType = model.EventType,
Data = model.Data
//Episode
//Series
};
}
}

View File

@@ -1,8 +1,7 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.Movies;
using NzbDrone.Api.REST;
using NzbDrone.Api.Series;
using NzbDrone.Common.Crypto;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Qualities;
@@ -15,9 +14,7 @@ namespace NzbDrone.Api.ManualImport
public string RelativePath { get; set; }
public string Name { get; set; }
public long Size { get; set; }
public SeriesResource Series { get; set; }
public int? SeasonNumber { get; set; }
public List<EpisodeResource> Episodes { get; set; }
public MovieResource Movie { get; set; }
public QualityModel Quality { get; set; }
public int QualityWeight { get; set; }
public string DownloadId { get; set; }
@@ -38,9 +35,7 @@ namespace NzbDrone.Api.ManualImport
RelativePath = model.RelativePath,
Name = model.Name,
Size = model.Size,
Series = model.Series.ToResource(),
SeasonNumber = model.SeasonNumber,
Episodes = model.Episodes.ToResource(),
Movie = model.Movie.ToResource(),
Quality = model.Quality,
//QualityWeight
DownloadId = model.DownloadId,

View File

@@ -1,8 +1,7 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using NLog;
using NzbDrone.Api.REST;
using NzbDrone.Api.Movie;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
@@ -11,7 +10,7 @@ using NzbDrone.Core.Tv;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.SignalR;
namespace NzbDrone.Api.EpisodeFiles
namespace NzbDrone.Api.MovieFiles
{
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>, IHandle<MovieFileAddedEvent>
{
@@ -72,4 +71,4 @@ namespace NzbDrone.Api.EpisodeFiles
BroadcastResourceChange(ModelAction.Updated, message.MovieFile.Id);
}
}
}
}

View File

@@ -1,14 +1,14 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Api.Movies;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series;
using NzbDrone.Core.MediaFiles;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.MovieFiles
{
public class MovieFileResource : RestResource
{
@@ -44,14 +44,14 @@ namespace NzbDrone.Api.Movie
MovieResource movie = null;
if (model.Movie != null)
/*if (model.Movie != null)
{
model.Movie.LazyLoad();
//model.Movie.LazyLoad();
if (model.Movie.Value != null)
{
//movie = model.Movie.Value.ToResource();
}
}
}*/
return new MovieFileResource
{
@@ -60,6 +60,7 @@ namespace NzbDrone.Api.Movie
Path = model.Path,
Size = model.Size,
DateAdded = model.DateAdded,
SceneName = model.SceneName,
ReleaseGroup = model.ReleaseGroup,
Quality = model.Quality,
Movie = movie,

View File

@@ -4,7 +4,6 @@ using System.Linq;
using Marr.Data;
using Nancy;
using NzbDrone.Api;
using NzbDrone.Api.Movie;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaCover;
@@ -18,7 +17,7 @@ using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class AlternativeTitleModule : NzbDroneRestModule<AlternativeTitleResource>
{
@@ -54,4 +53,4 @@ namespace NzbDrone.Api.Movie
return _altTitleService.GetById(id).ToResource();
}
}
}
}

View File

@@ -1,16 +1,15 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies.AlternativeTitles;
using NzbDrone.Core.Parser;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class AlternativeTitleResource : RestResource
{

View File

@@ -4,7 +4,6 @@ using System.Linq;
using Marr.Data;
using Nancy;
using NzbDrone.Api;
using NzbDrone.Api.Movie;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Messaging;
@@ -19,7 +18,7 @@ using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class AlternativeYearModule : NzbDroneRestModule<AlternativeYearResource>
{
@@ -60,4 +59,4 @@ namespace NzbDrone.Api.Movie
};
}
}
}
}

View File

@@ -1,16 +1,15 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies.AlternativeTitles;
using NzbDrone.Core.Parser;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class AlternativeYearResource : RestResource
{

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core.MediaCover;
@@ -6,7 +6,7 @@ using NzbDrone.Core.MetadataSource;
using System.Linq;
using NzbDrone.Core.NetImport;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class FetchMovieListModule : NzbDroneRestModule<MovieResource>
{
@@ -57,4 +57,4 @@ namespace NzbDrone.Api.Movie
}
}
}
}
}

View File

@@ -1,4 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using Nancy;
using NzbDrone.Api.Extensions;
@@ -16,7 +15,7 @@ using NzbDrone.Core.RootFolders;
using NzbDrone.Common.Cache;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class UnmappedComparer : IComparer<UnmappedFolder>

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core.MediaCover;
@@ -9,7 +9,7 @@ using NzbDrone.Api.REST;
using NzbDrone.Core.NetImport;
using NzbDrone.Api.NetImport;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class MovieDiscoverModule : NzbDroneRestModule<MovieResource>
{
@@ -60,4 +60,4 @@ namespace NzbDrone.Api.Movie
}
}
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Nancy;
@@ -7,7 +7,7 @@ using NzbDrone.Api.Extensions;
using NzbDrone.Api.REST;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class MovieEditorModule : NzbDroneApiModule
{

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core.MediaCover;
@@ -7,7 +7,7 @@ using System.Linq;
using System;
using NzbDrone.Api.REST;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class MovieLookupModule : NzbDroneRestModule<MovieResource>
{
@@ -15,7 +15,7 @@ namespace NzbDrone.Api.Movie
private readonly IProvideMovieInfo _movieInfo;
public MovieLookupModule(ISearchForNewMovie searchProxy, IProvideMovieInfo movieInfo)
: base("/movies/lookup")
: base("/movie/lookup")
{
_movieInfo = movieInfo;
_searchProxy = searchProxy;
@@ -64,4 +64,4 @@ namespace NzbDrone.Api.Movie
}
}
}
}
}

View File

@@ -1,11 +1,298 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Api.Extensions;
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.SignalR;
using NzbDrone.Core.Datastore;
using Microsoft.CSharp.RuntimeBinder;
using Nancy;
namespace NzbDrone.Api.Movies
{
class MovieModule
public class MovieModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
IHandle<MovieImportedEvent>,
IHandle<MovieFileDeletedEvent>,
IHandle<MovieUpdatedEvent>,
IHandle<MovieEditedEvent>,
IHandle<MovieDeletedEvent>,
IHandle<MovieRenamedEvent>,
IHandle<MediaCoversUpdatedEvent>
{
protected readonly IMovieService _moviesService;
private readonly IMovieStatisticsService _moviesStatisticsService;
private readonly IMapCoversToLocal _coverMapper;
private const string TITLE_SLUG_ROUTE = "/titleslug/(?<slug>[^/]+)";
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
IMovieService moviesService,
IMovieStatisticsService moviesStatisticsService,
ISceneMappingService sceneMappingService,
IMapCoversToLocal coverMapper,
RootFolderValidator rootFolderValidator,
MoviePathValidator moviesPathValidator,
MovieExistsValidator moviesExistsValidator,
DroneFactoryValidator droneFactoryValidator,
MovieAncestorValidator moviesAncestorValidator,
ProfileExistsValidator profileExistsValidator
)
: base(signalRBroadcaster)
{
_moviesService = moviesService;
_moviesStatisticsService = moviesStatisticsService;
_coverMapper = coverMapper;
GetResourceAll = AllMovie;
GetResourcePaged = GetMoviePaged;
GetResourceById = GetMovie;
Get[TITLE_SLUG_ROUTE] = GetByTitleSlug; /*(options) => {
return ReqResExtensions.AsResponse(GetByTitleSlug(options.slug), Nancy.HttpStatusCode.OK);
};*/
CreateResource = AddMovie;
UpdateResource = UpdateMovie;
DeleteResource = DeleteMovie;
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
SharedValidator.RuleFor(s => s.Path)
.Cascade(CascadeMode.StopOnFirstFailure)
.IsValidPath()
.SetValidator(rootFolderValidator)
.SetValidator(moviesPathValidator)
.SetValidator(droneFactoryValidator)
.SetValidator(moviesAncestorValidator)
.When(s => !s.Path.IsNullOrWhiteSpace());
SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator);
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
PostValidator.RuleFor(s => s.Title).NotEmpty();
PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
PutValidator.RuleFor(s => s.Path).IsValidPath();
}
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
IMovieService moviesService,
IMovieStatisticsService moviesStatisticsService,
ISceneMappingService sceneMappingService,
IMapCoversToLocal coverMapper,
string resource)
: base(signalRBroadcaster, resource)
{
_moviesService = moviesService;
_moviesStatisticsService = moviesStatisticsService;
_coverMapper = coverMapper;
GetResourceAll = AllMovie;
GetResourceById = GetMovie;
CreateResource = AddMovie;
UpdateResource = UpdateMovie;
DeleteResource = DeleteMovie;
}
private MovieResource GetMovie(int id)
{
var movies = _moviesService.GetMovie(id);
return MapToResource(movies);
}
private PagingResource<MovieResource> GetMoviePaged(PagingResource<MovieResource> pagingResource)
{
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>();
pagingSpec.FilterExpression = _moviesService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue, pagingResource.FilterType);
return ApplyToPage(_moviesService.Paged, pagingSpec, MapToResource);
}
protected MovieResource MapToResource(Core.Tv.Movie movies)
{
if (movies == null) return null;
var resource = movies.ToResource();
MapCoversToLocal(resource);
//FetchAndLinkMovieStatistics(resource);
//PopulateAlternateTitles(resource);
return resource;
}
private List<MovieResource> AllMovie()
{
var moviesStats = _moviesStatisticsService.MovieStatistics();
var moviesResources = _moviesService.GetAllMovies().ToResource();
MapCoversToLocal(moviesResources.ToArray());
LinkMovieStatistics(moviesResources, moviesStats);
PopulateAlternateTitles(moviesResources);
return moviesResources;
}
private Response GetByTitleSlug(dynamic options)
{
var slug = "";
try
{
slug = options.slug;
// do stuff with x
}
catch (RuntimeBinderException)
{
return new NotFoundResponse();
}
try
{
return MapToResource(_moviesService.FindByTitleSlug(slug)).AsResponse(Nancy.HttpStatusCode.OK);
}
catch (ModelNotFoundException)
{
return new NotFoundResponse();
}
}
private int AddMovie(MovieResource moviesResource)
{
var model = moviesResource.ToModel();
return _moviesService.AddMovie(model).Id;
}
private void UpdateMovie(MovieResource moviesResource)
{
var model = moviesResource.ToModel(_moviesService.GetMovie(moviesResource.Id));
_moviesService.UpdateMovie(model);
BroadcastResourceChange(ModelAction.Updated, moviesResource);
}
private void DeleteMovie(int id)
{
var deleteFiles = false;
var addExclusion = false;
var deleteFilesQuery = Request.Query.deleteFiles;
var addExclusionQuery = Request.Query.addExclusion;
if (deleteFilesQuery.HasValue)
{
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
}
if (addExclusionQuery.HasValue)
{
addExclusion = Convert.ToBoolean(addExclusionQuery.Value);
}
_moviesService.DeleteMovie(id, deleteFiles, addExclusion);
}
private void MapCoversToLocal(params MovieResource[] movies)
{
foreach (var moviesResource in movies)
{
_coverMapper.ConvertToLocalUrls(moviesResource.Id, moviesResource.Images);
}
}
private void FetchAndLinkMovieStatistics(MovieResource resource)
{
LinkMovieStatistics(resource, _moviesStatisticsService.MovieStatistics(resource.Id));
}
private void LinkMovieStatistics(List<MovieResource> resources, List<MovieStatistics> moviesStatistics)
{
var dictMovieStats = moviesStatistics.ToDictionary(v => v.MovieId);
foreach (var movies in resources)
{
var stats = dictMovieStats.GetValueOrDefault(movies.Id);
if (stats == null) continue;
LinkMovieStatistics(movies, stats);
}
}
private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics)
{
//resource.SizeOnDisk = 0;//TODO: incorporate movie statistics moviesStatistics.SizeOnDisk;
}
private void PopulateAlternateTitles(List<MovieResource> resources)
{
foreach (var resource in resources)
{
PopulateAlternateTitles(resource);
}
}
private void PopulateAlternateTitles(MovieResource resource)
{
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
//if (mappings == null) return;
//Not necessary anymore
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
}
public void Handle(MovieImportedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.ImportedMovie.MovieId);
}
public void Handle(MovieFileDeletedEvent message)
{
if (message.Reason == DeleteMediaFileReason.Upgrade) return;
BroadcastResourceChange(ModelAction.Updated, message.MovieFile.MovieId);
}
public void Handle(MovieUpdatedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MovieEditedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MovieDeletedEvent message)
{
BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource());
}
public void Handle(MovieRenamedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MediaCoversUpdatedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
}
}

View File

@@ -1,4 +1,4 @@
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;

View File

@@ -1,12 +1,12 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
using NzbDrone.Api.Series;
using NzbDrone.Api.MovieFiles;
namespace NzbDrone.Api.Movie
namespace NzbDrone.Api.Movies
{
public class MovieResource : RestResource
{
@@ -93,12 +93,13 @@ namespace NzbDrone.Api.Movie
if (model == null) return null;
long size = 0;
bool downloaded = false;
MovieFileResource movieFile = null;
long size = model.MovieFile?.Size ?? 0;
bool downloaded = model.MovieFile != null;
MovieFileResource movieFile = model.MovieFile?.ToResource();
if(model.MovieFile != null)
/*if(model.MovieFile != null)
{
model.MovieFile.LazyLoad();
}
@@ -108,7 +109,7 @@ namespace NzbDrone.Api.Movie
size = model.MovieFile.Value.Size;
downloaded = true;
movieFile = model.MovieFile.Value.ToResource();
}
}*/
//model.AlternativeTitles.LazyLoad();

View File

@@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaFiles;
using System;
using System.Collections.Generic;

View File

@@ -1,4 +1,4 @@
using NzbDrone.Api.REST;
using NzbDrone.Api.REST;
using System.Collections.Generic;
using System.Linq;

View File

@@ -34,7 +34,6 @@ namespace NzbDrone.Api
RegisterPipelines(pipelines);
container.Resolve<DatabaseTarget>().Register();
container.Resolve<IEventAggregator>().PublishEvent(new ApplicationStartedEvent());
}
private void RegisterPipelines(IPipelines pipelines)
@@ -56,4 +55,4 @@ namespace NzbDrone.Api
protected override byte[] FavIcon => null;
}
}
}

View File

@@ -1,34 +1,34 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Core.NetImport;
using NzbDrone.Core.NetImport.ImportExclusions;
using NzbDrone.Core.Validation.Paths;
namespace NzbDrone.Api.NetImport
{
public class ImportExclusionsModule : NzbDroneRestModule<ImportExclusionsResource>
{
private readonly IImportExclusionsService _exclusionService;
public ImportExclusionsModule(NetImportFactory netImportFactory, IImportExclusionsService exclusionService) : base("exclusions")
{
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Core.NetImport;
using NzbDrone.Core.NetImport.ImportExclusions;
using NzbDrone.Core.Validation.Paths;
namespace NzbDrone.Api.NetImport
{
public class ImportExclusionsModule : NzbDroneRestModule<ImportExclusionsResource>
{
private readonly IImportExclusionsService _exclusionService;
public ImportExclusionsModule(NetImportFactory netImportFactory, IImportExclusionsService exclusionService) : base("exclusions")
{
_exclusionService = exclusionService;
GetResourceAll = GetAll;
CreateResource = AddExclusion;
DeleteResource = RemoveExclusion;
GetResourceById = GetById;
}
public List<ImportExclusionsResource> GetAll()
{
return _exclusionService.GetAllExclusions().ToResource();
GetResourceById = GetById;
}
public List<ImportExclusionsResource> GetAll()
{
return _exclusionService.GetAllExclusions().ToResource();
}
public ImportExclusionsResource GetById(int id)
{
return _exclusionService.GetById(id).ToResource();
}
}
public int AddExclusion(ImportExclusionsResource exclusionResource)
{
@@ -40,6 +40,6 @@ namespace NzbDrone.Api.NetImport
public void RemoveExclusion (int id)
{
_exclusionService.RemoveExclusion(new ImportExclusion { Id = id });
}
}
}
}
}
}

View File

@@ -1,46 +1,46 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.NetImport;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.NetImport
{
public class ImportExclusionsResource : ProviderResource
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.NetImport;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.NetImport
{
public class ImportExclusionsResource : ProviderResource
{
//public int Id { get; set; }
public int TmdbId { get; set; }
public string MovieTitle { get; set; }
public int MovieYear { get; set; }
}
public static class ImportExclusionsResourceMapper
{
public static ImportExclusionsResource ToResource(this Core.NetImport.ImportExclusions.ImportExclusion model)
{
if (model == null) return null;
return new ImportExclusionsResource
//public int Id { get; set; }
public int TmdbId { get; set; }
public string MovieTitle { get; set; }
public int MovieYear { get; set; }
}
public static class ImportExclusionsResourceMapper
{
public static ImportExclusionsResource ToResource(this Core.NetImport.ImportExclusions.ImportExclusion model)
{
if (model == null) return null;
return new ImportExclusionsResource
{
Id = model.Id,
TmdbId = model.TmdbId,
MovieTitle = model.MovieTitle,
MovieYear = model.MovieYear
};
}
public static List<ImportExclusionsResource> ToResource(this IEnumerable<Core.NetImport.ImportExclusions.ImportExclusion> exclusions)
{
return exclusions.Select(ToResource).ToList();
Id = model.Id,
TmdbId = model.TmdbId,
MovieTitle = model.MovieTitle,
MovieYear = model.MovieYear
};
}
public static List<ImportExclusionsResource> ToResource(this IEnumerable<Core.NetImport.ImportExclusions.ImportExclusion> exclusions)
{
return exclusions.Select(ToResource).ToList();
}
public static Core.NetImport.ImportExclusions.ImportExclusion ToModel(this ImportExclusionsResource resource)
{
return new Core.NetImport.ImportExclusions.ImportExclusion
{
return new Core.NetImport.ImportExclusions.ImportExclusion
{
TmdbId = resource.TmdbId,
MovieTitle = resource.MovieTitle,
MovieYear = resource.MovieYear
MovieYear = resource.MovieYear
};
}
}
}
}
}
}

View File

@@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Nancy;
using Nancy.Extensions;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Tv;

View File

@@ -1,4 +1,3 @@
using NzbDrone.Core.NetImport;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.NetImport

View File

@@ -1,314 +1,305 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{FD286DF8-2D3A-4394-8AD5-443FADE55FB2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.Api</RootNamespace>
<AssemblyName>NzbDrone.Api</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<ProductVersion>12.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\_output\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\..\_output\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="antlr.runtime, Version=2.7.6.2, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\antlr.runtime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentValidation, Version=6.2.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\FluentValidation.6.2.1.0\lib\portable-net40+sl50+wp80+win8+wpa81\FluentValidation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Ical.Net, Version=2.1.0.30332, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\Ical.Net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Ical.Net.Collections, Version=2.1.0.30331, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\Ical.Net.Collections.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nancy, Version=1.4.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nancy.1.4.3\lib\net40\Nancy.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nancy.Authentication.Basic, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nancy.Authentication.Basic.1.4.1\lib\net40\Nancy.Authentication.Basic.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nancy.Authentication.Forms, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nancy.Authentication.Forms.1.4.1\lib\net40\Nancy.Authentication.Forms.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NodaTime, Version=1.3.0.0, Culture=neutral, PublicKeyToken=4226afe0d9b296d1, processorArchitecture=MSIL">
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\NodaTime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data.SQLite, Version=1.0.84.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Authentication\AuthenticationService.cs" />
<Compile Include="Authentication\EnableAuthInNancy.cs" />
<Compile Include="Authentication\AuthenticationModule.cs" />
<Compile Include="Authentication\LoginResource.cs" />
<Compile Include="Authentication\NzbDroneUser.cs" />
<Compile Include="Blacklist\BlacklistModule.cs" />
<Compile Include="Blacklist\BlacklistResource.cs" />
<Compile Include="Calendar\CalendarFeedModule.cs" />
<Compile Include="Calendar\CalendarModule.cs" />
<Compile Include="ClientSchema\Field.cs" />
<Compile Include="ClientSchema\FieldDefinitionAttribute.cs" />
<Compile Include="ClientSchema\SchemaBuilder.cs" />
<Compile Include="ClientSchema\SchemaDeserializer.cs" />
<Compile Include="ClientSchema\SelectOption.cs" />
<Compile Include="Commands\CommandModule.cs" />
<Compile Include="Commands\CommandResource.cs" />
<Compile Include="Config\NetImportConfigModule.cs" />
<Compile Include="Config\NetImportConfigResource.cs" />
<Compile Include="Extensions\AccessControlHeaders.cs" />
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
<Compile Include="Extensions\Pipelines\UrlBasePipeline.cs" />
<Compile Include="Extensions\Pipelines\RequestLoggingPipeline.cs" />
<Compile Include="Frontend\Mappers\LoginHtmlMapper.cs" />
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
<Compile Include="Indexers\ReleaseModuleBase.cs" />
<Compile Include="Indexers\ReleasePushModule.cs" />
<Compile Include="Movies\AlternativeTitleModule.cs" />
<Compile Include="Movies\AlternativeYearResource.cs" />
<Compile Include="Movies\AlternativeYearModule.cs" />
<Compile Include="Movies\MovieModuleWithSignalR.cs" />
<Compile Include="Movies\MovieBulkImportModule.cs" />
<Compile Include="Movies\MovieFileModule.cs" />
<Compile Include="Series\MovieModule.cs" />
<Compile Include="Movies\RenameMovieModule.cs" />
<Compile Include="Movies\RenameMovieResource.cs" />
<Compile Include="Movies\MovieEditorModule.cs" />
<Compile Include="NetImport\ListImportModule.cs" />
<Compile Include="NetImport\NetImportModule.cs" />
<Compile Include="NetImport\NetImportResource.cs" />
<Compile Include="Parse\ParseModule.cs" />
<Compile Include="Parse\ParseResource.cs" />
<Compile Include="ManualImport\ManualImportModule.cs" />
<Compile Include="ManualImport\ManualImportResource.cs" />
<Compile Include="Profiles\Delay\DelayProfileModule.cs" />
<Compile Include="Profiles\Delay\DelayProfileResource.cs" />
<Compile Include="Queue\QueueActionModule.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingModule.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingResource.cs" />
<Compile Include="Config\UiConfigModule.cs" />
<Compile Include="Config\UiConfigResource.cs" />
<Compile Include="Config\DownloadClientConfigModule.cs" />
<Compile Include="Config\DownloadClientConfigResource.cs" />
<Compile Include="Config\HostConfigModule.cs" />
<Compile Include="Config\HostConfigResource.cs" />
<Compile Include="Config\IndexerConfigModule.cs" />
<Compile Include="Config\IndexerConfigResource.cs" />
<Compile Include="Config\MediaManagementConfigModule.cs" />
<Compile Include="Config\MediaManagementConfigResource.cs" />
<Compile Include="Config\NamingConfigModule.cs" />
<Compile Include="Config\NamingConfigResource.cs" />
<Compile Include="Config\NamingSampleResource.cs" />
<Compile Include="Config\NzbDroneConfigModule.cs" />
<Compile Include="FileSystem\FileSystemModule.cs" />
<Compile Include="DiskSpace\DiskSpaceModule.cs" />
<Compile Include="DiskSpace\DiskSpaceResource.cs" />
<Compile Include="DownloadClient\DownloadClientModule.cs" />
<Compile Include="DownloadClient\DownloadClientResource.cs" />
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
<Compile Include="EpisodeFiles\EpisodeFileResource.cs" />
<Compile Include="Episodes\EpisodeModule.cs" />
<Compile Include="Episodes\EpisodeModuleWithSignalR.cs" />
<Compile Include="Episodes\EpisodeResource.cs" />
<Compile Include="Episodes\RenameEpisodeModule.cs" />
<Compile Include="Episodes\RenameEpisodeResource.cs" />
<Compile Include="ErrorManagement\ApiException.cs" />
<Compile Include="ErrorManagement\ErrorHandler.cs" />
<Compile Include="ErrorManagement\ErrorModel.cs" />
<Compile Include="ErrorManagement\NzbDroneErrorPipeline.cs" />
<Compile Include="Exceptions\InvalidApiKeyException.cs" />
<Compile Include="Extensions\NancyJsonSerializer.cs" />
<Compile Include="Extensions\Pipelines\CacheHeaderPipeline.cs" />
<Compile Include="Extensions\Pipelines\GZipPipeline.cs" />
<Compile Include="Extensions\Pipelines\IfModifiedPipeline.cs" />
<Compile Include="Extensions\Pipelines\IRegisterNancyPipeline.cs" />
<Compile Include="Extensions\Pipelines\NzbDroneVersionPipeline.cs" />
<Compile Include="Extensions\ReqResExtensions.cs" />
<Compile Include="Extensions\RequestExtensions.cs" />
<Compile Include="Frontend\CacheableSpecification.cs" />
<Compile Include="Frontend\Mappers\BackupFileMapper.cs" />
<Compile Include="Frontend\Mappers\CacheBreakerProvider.cs" />
<Compile Include="Frontend\Mappers\FaviconMapper.cs" />
<Compile Include="Frontend\Mappers\IMapHttpRequestsToDisk.cs" />
<Compile Include="Frontend\Mappers\IndexHtmlMapper.cs" />
<Compile Include="Frontend\Mappers\LogFileMapper.cs" />
<Compile Include="Frontend\Mappers\MediaCoverMapper.cs" />
<Compile Include="Frontend\Mappers\StaticResourceMapper.cs" />
<Compile Include="Frontend\Mappers\StaticResourceMapperBase.cs" />
<Compile Include="Frontend\Mappers\UpdateLogFileMapper.cs" />
<Compile Include="Frontend\StaticResourceModule.cs" />
<Compile Include="Health\HealthModule.cs" />
<Compile Include="Health\HealthResource.cs" />
<Compile Include="History\HistoryModule.cs" />
<Compile Include="History\HistoryResource.cs" />
<Compile Include="Indexers\IndexerModule.cs" />
<Compile Include="Indexers\IndexerResource.cs" />
<Compile Include="Indexers\ReleaseModule.cs" />
<Compile Include="Indexers\ReleaseResource.cs" />
<Compile Include="Logs\LogFileModule.cs" />
<Compile Include="Logs\LogFileModuleBase.cs" />
<Compile Include="Logs\LogFileResource.cs" />
<Compile Include="Logs\LogModule.cs" />
<Compile Include="Logs\LogResource.cs" />
<Compile Include="Logs\UpdateLogFileModule.cs" />
<Compile Include="MediaCovers\MediaCoverModule.cs" />
<Compile Include="Metadata\MetadataModule.cs" />
<Compile Include="Metadata\MetadataResource.cs" />
<Compile Include="NancyBootstrapper.cs" />
<Compile Include="Notifications\NotificationModule.cs" />
<Compile Include="Notifications\NotificationResource.cs" />
<Compile Include="NzbDroneApiModule.cs" />
<Compile Include="NzbDroneFeedModule.cs" />
<Compile Include="NzbDroneRestModule.cs" />
<Compile Include="NzbDroneRestModuleWithSignalR.cs" />
<Compile Include="PagingResource.cs" />
<Compile Include="Profiles\Languages\LanguageModule.cs" />
<Compile Include="Profiles\Languages\LanguageResource.cs" />
<Compile Include="Profiles\LegacyProfileModule.cs" />
<Compile Include="Profiles\ProfileModule.cs" />
<Compile Include="Profiles\ProfileResource.cs" />
<Compile Include="Profiles\ProfileSchemaModule.cs" />
<Compile Include="Profiles\ProfileValidation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProviderModuleBase.cs" />
<Compile Include="ProviderResource.cs" />
<Compile Include="Qualities\QualityDefinitionModule.cs" />
<Compile Include="Qualities\QualityDefinitionResource.cs" />
<Compile Include="Queue\QueueModule.cs" />
<Compile Include="Queue\QueueResource.cs" />
<Compile Include="ResourceChangeMessage.cs" />
<Compile Include="Restrictions\RestrictionModule.cs" />
<Compile Include="Restrictions\RestrictionResource.cs" />
<Compile Include="REST\NotFoundException.cs" />
<Compile Include="REST\BadRequestException.cs" />
<Compile Include="REST\MethodNotAllowedException.cs" />
<Compile Include="REST\ResourceValidator.cs" />
<Compile Include="REST\RestModule.cs" />
<Compile Include="REST\RestResource.cs" />
<Compile Include="RootFolders\RootFolderModule.cs" />
<Compile Include="RootFolders\RootFolderResource.cs" />
<Compile Include="SeasonPass\SeasonPassResource.cs" />
<Compile Include="Series\AlternativeTitleResource.cs" />
<Compile Include="Series\MovieFileResource.cs" />
<Compile Include="Series\FetchMovieListModule.cs" />
<Compile Include="Series\SeasonResource.cs" />
<Compile Include="SeasonPass\SeasonPassModule.cs" />
<Compile Include="Series\SeriesEditorModule.cs" />
<Compile Include="Series\MovieLookupModule.cs" />
<Compile Include="Series\SeriesLookupModule.cs" />
<Compile Include="Series\SeriesModule.cs" />
<Compile Include="Series\MovieResource.cs" />
<Compile Include="Series\SeriesResource.cs" />
<Compile Include="Series\SeasonStatisticsResource.cs" />
<Compile Include="System\Backup\BackupModule.cs" />
<Compile Include="System\Backup\BackupResource.cs" />
<Compile Include="System\Tasks\TaskModule.cs" />
<Compile Include="System\Tasks\TaskResource.cs" />
<Compile Include="System\SystemModule.cs" />
<Compile Include="Tags\TagModule.cs" />
<Compile Include="Tags\TagResource.cs" />
<Compile Include="TinyIoCNancyBootstrapper.cs" />
<Compile Include="Update\UpdateModule.cs" />
<Compile Include="Update\UpdateResource.cs" />
<Compile Include="Validation\NetImportSyncIntervalValidator.cs" />
<Compile Include="Validation\RssSyncIntervalValidator.cs" />
<Compile Include="Validation\EmptyCollectionValidator.cs" />
<Compile Include="Validation\RuleBuilderExtensions.cs" />
<Compile Include="Wanted\CutoffModule.cs" />
<Compile Include="Wanted\LegacyMissingModule.cs" />
<Compile Include="Wanted\MissingModule.cs" />
<Compile Include="Wanted\MovieCutoffModule.cs" />
<Compile Include="Wanted\MovieMissingModule.cs" />
<Compile Include="Series\MovieDiscoverModule.cs" />
<Compile Include="NetImport\ImportExclusionsModule.cs" />
<Compile Include="NetImport\ImportExclusionsResource.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Marr.Data\Marr.Data.csproj">
<Project>{F6FC6BE7-0847-4817-A1ED-223DC647C3D7}</Project>
<Name>Marr.Data</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
<Project>{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}</Project>
<Name>NzbDrone.Core</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.SignalR\NzbDrone.SignalR.csproj">
<Project>{7C2CC69F-5CA0-4E5C-85CB-983F9F6C3B36}</Project>
<Name>NzbDrone.SignalR</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{FD286DF8-2D3A-4394-8AD5-443FADE55FB2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.Api</RootNamespace>
<AssemblyName>NzbDrone.Api</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<ProductVersion>12.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\_output\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\..\_output\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="antlr.runtime, Version=2.7.6.2, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\antlr.runtime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentValidation, Version=6.2.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\FluentValidation.6.2.1.0\lib\portable-net40+sl50+wp80+win8+wpa81\FluentValidation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Ical.Net, Version=2.1.0.30332, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\Ical.Net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Ical.Net.Collections, Version=2.1.0.30331, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\Ical.Net.Collections.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nancy, Version=1.4.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nancy.1.4.3\lib\net40\Nancy.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nancy.Authentication.Basic, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nancy.Authentication.Basic.1.4.1\lib\net40\Nancy.Authentication.Basic.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nancy.Authentication.Forms, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nancy.Authentication.Forms.1.4.1\lib\net40\Nancy.Authentication.Forms.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.5.0-rc06\lib\net40-client\NLog.dll</HintPath>
</Reference>
<Reference Include="NodaTime, Version=1.3.0.0, Culture=neutral, PublicKeyToken=4226afe0d9b296d1, processorArchitecture=MSIL">
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\NodaTime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data.SQLite, Version=1.0.84.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Authentication\AuthenticationService.cs" />
<Compile Include="Authentication\EnableAuthInNancy.cs" />
<Compile Include="Authentication\AuthenticationModule.cs" />
<Compile Include="Authentication\LoginResource.cs" />
<Compile Include="Authentication\NzbDroneUser.cs" />
<Compile Include="Blacklist\BlacklistModule.cs" />
<Compile Include="Blacklist\BlacklistResource.cs" />
<Compile Include="Calendar\CalendarFeedModule.cs" />
<Compile Include="Calendar\CalendarModule.cs" />
<Compile Include="ClientSchema\Field.cs" />
<Compile Include="ClientSchema\FieldDefinitionAttribute.cs" />
<Compile Include="ClientSchema\SchemaBuilder.cs" />
<Compile Include="ClientSchema\SchemaDeserializer.cs" />
<Compile Include="ClientSchema\SelectOption.cs" />
<Compile Include="Commands\CommandModule.cs" />
<Compile Include="Commands\CommandResource.cs" />
<Compile Include="Config\NetImportConfigModule.cs" />
<Compile Include="Config\NetImportConfigResource.cs" />
<Compile Include="Extensions\AccessControlHeaders.cs" />
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
<Compile Include="Extensions\Pipelines\UrlBasePipeline.cs" />
<Compile Include="Extensions\Pipelines\RequestLoggingPipeline.cs" />
<Compile Include="ExtraFiles\ExtraFileResource.cs" />
<Compile Include="Frontend\Mappers\LoginHtmlMapper.cs" />
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
<Compile Include="Indexers\ReleaseModuleBase.cs" />
<Compile Include="Indexers\ReleasePushModule.cs" />
<Compile Include="ExtraFiles\ExtraFileModule.cs" />
<Compile Include="Movies\AlternativeTitleModule.cs" />
<Compile Include="Movies\AlternativeYearResource.cs" />
<Compile Include="Movies\AlternativeYearModule.cs" />
<Compile Include="Movies\MovieModuleWithSignalR.cs" />
<Compile Include="Movies\MovieBulkImportModule.cs" />
<Compile Include="MovieFiles\MovieFileModule.cs" />
<Compile Include="Movies\MovieModule.cs" />
<Compile Include="Movies\RenameMovieModule.cs" />
<Compile Include="Movies\RenameMovieResource.cs" />
<Compile Include="Movies\MovieEditorModule.cs" />
<Compile Include="NetImport\ListImportModule.cs" />
<Compile Include="NetImport\NetImportModule.cs" />
<Compile Include="NetImport\NetImportResource.cs" />
<Compile Include="Parse\ParseModule.cs" />
<Compile Include="Parse\ParseResource.cs" />
<Compile Include="ManualImport\ManualImportModule.cs" />
<Compile Include="ManualImport\ManualImportResource.cs" />
<Compile Include="Profiles\Delay\DelayProfileModule.cs" />
<Compile Include="Profiles\Delay\DelayProfileResource.cs" />
<Compile Include="Queue\QueueActionModule.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingModule.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingResource.cs" />
<Compile Include="Config\UiConfigModule.cs" />
<Compile Include="Config\UiConfigResource.cs" />
<Compile Include="Config\DownloadClientConfigModule.cs" />
<Compile Include="Config\DownloadClientConfigResource.cs" />
<Compile Include="Config\HostConfigModule.cs" />
<Compile Include="Config\HostConfigResource.cs" />
<Compile Include="Config\IndexerConfigModule.cs" />
<Compile Include="Config\IndexerConfigResource.cs" />
<Compile Include="Config\MediaManagementConfigModule.cs" />
<Compile Include="Config\MediaManagementConfigResource.cs" />
<Compile Include="Config\NamingConfigModule.cs" />
<Compile Include="Config\NamingConfigResource.cs" />
<Compile Include="Config\NamingSampleResource.cs" />
<Compile Include="Config\NzbDroneConfigModule.cs" />
<Compile Include="FileSystem\FileSystemModule.cs" />
<Compile Include="DiskSpace\DiskSpaceModule.cs" />
<Compile Include="DiskSpace\DiskSpaceResource.cs" />
<Compile Include="DownloadClient\DownloadClientModule.cs" />
<Compile Include="DownloadClient\DownloadClientResource.cs" />
<Compile Include="ErrorManagement\ApiException.cs" />
<Compile Include="ErrorManagement\ErrorHandler.cs" />
<Compile Include="ErrorManagement\ErrorModel.cs" />
<Compile Include="ErrorManagement\NzbDroneErrorPipeline.cs" />
<Compile Include="Exceptions\InvalidApiKeyException.cs" />
<Compile Include="Extensions\NancyJsonSerializer.cs" />
<Compile Include="Extensions\Pipelines\CacheHeaderPipeline.cs" />
<Compile Include="Extensions\Pipelines\GZipPipeline.cs" />
<Compile Include="Extensions\Pipelines\IfModifiedPipeline.cs" />
<Compile Include="Extensions\Pipelines\IRegisterNancyPipeline.cs" />
<Compile Include="Extensions\Pipelines\NzbDroneVersionPipeline.cs" />
<Compile Include="Extensions\ReqResExtensions.cs" />
<Compile Include="Extensions\RequestExtensions.cs" />
<Compile Include="Frontend\CacheableSpecification.cs" />
<Compile Include="Frontend\Mappers\BackupFileMapper.cs" />
<Compile Include="Frontend\Mappers\CacheBreakerProvider.cs" />
<Compile Include="Frontend\Mappers\FaviconMapper.cs" />
<Compile Include="Frontend\Mappers\IMapHttpRequestsToDisk.cs" />
<Compile Include="Frontend\Mappers\IndexHtmlMapper.cs" />
<Compile Include="Frontend\Mappers\LogFileMapper.cs" />
<Compile Include="Frontend\Mappers\MediaCoverMapper.cs" />
<Compile Include="Frontend\Mappers\StaticResourceMapper.cs" />
<Compile Include="Frontend\Mappers\StaticResourceMapperBase.cs" />
<Compile Include="Frontend\Mappers\UpdateLogFileMapper.cs" />
<Compile Include="Frontend\StaticResourceModule.cs" />
<Compile Include="Health\HealthModule.cs" />
<Compile Include="Health\HealthResource.cs" />
<Compile Include="History\HistoryModule.cs" />
<Compile Include="History\HistoryResource.cs" />
<Compile Include="Indexers\IndexerModule.cs" />
<Compile Include="Indexers\IndexerResource.cs" />
<Compile Include="Indexers\ReleaseModule.cs" />
<Compile Include="Indexers\ReleaseResource.cs" />
<Compile Include="Logs\LogFileModule.cs" />
<Compile Include="Logs\LogFileModuleBase.cs" />
<Compile Include="Logs\LogFileResource.cs" />
<Compile Include="Logs\LogModule.cs" />
<Compile Include="Logs\LogResource.cs" />
<Compile Include="Logs\UpdateLogFileModule.cs" />
<Compile Include="MediaCovers\MediaCoverModule.cs" />
<Compile Include="Metadata\MetadataModule.cs" />
<Compile Include="Metadata\MetadataResource.cs" />
<Compile Include="NancyBootstrapper.cs" />
<Compile Include="Notifications\NotificationModule.cs" />
<Compile Include="Notifications\NotificationResource.cs" />
<Compile Include="NzbDroneApiModule.cs" />
<Compile Include="NzbDroneFeedModule.cs" />
<Compile Include="NzbDroneRestModule.cs" />
<Compile Include="NzbDroneRestModuleWithSignalR.cs" />
<Compile Include="PagingResource.cs" />
<Compile Include="Profiles\Languages\LanguageModule.cs" />
<Compile Include="Profiles\Languages\LanguageResource.cs" />
<Compile Include="Profiles\LegacyProfileModule.cs" />
<Compile Include="Profiles\ProfileModule.cs" />
<Compile Include="Profiles\ProfileResource.cs" />
<Compile Include="Profiles\ProfileSchemaModule.cs" />
<Compile Include="Profiles\ProfileValidation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProviderModuleBase.cs" />
<Compile Include="ProviderResource.cs" />
<Compile Include="Qualities\QualityDefinitionModule.cs" />
<Compile Include="Qualities\QualityDefinitionResource.cs" />
<Compile Include="Queue\QueueModule.cs" />
<Compile Include="Queue\QueueResource.cs" />
<Compile Include="ResourceChangeMessage.cs" />
<Compile Include="Restrictions\RestrictionModule.cs" />
<Compile Include="Restrictions\RestrictionResource.cs" />
<Compile Include="REST\NotFoundException.cs" />
<Compile Include="REST\BadRequestException.cs" />
<Compile Include="REST\MethodNotAllowedException.cs" />
<Compile Include="REST\ResourceValidator.cs" />
<Compile Include="REST\RestModule.cs" />
<Compile Include="REST\RestResource.cs" />
<Compile Include="RootFolders\RootFolderModule.cs" />
<Compile Include="RootFolders\RootFolderResource.cs" />
<Compile Include="Movies\AlternativeTitleResource.cs" />
<Compile Include="MovieFiles\MovieFileResource.cs" />
<Compile Include="Movies\FetchMovieListModule.cs" />
<Compile Include="Movies\MovieLookupModule.cs" />
<Compile Include="Series\SeriesModule.cs" />
<Compile Include="Movies\MovieResource.cs" />
<Compile Include="Series\SeriesResource.cs" />
<Compile Include="System\Backup\BackupModule.cs" />
<Compile Include="System\Backup\BackupResource.cs" />
<Compile Include="System\Tasks\TaskModule.cs" />
<Compile Include="System\Tasks\TaskResource.cs" />
<Compile Include="System\SystemModule.cs" />
<Compile Include="Tags\TagModule.cs" />
<Compile Include="Tags\TagResource.cs" />
<Compile Include="TinyIoCNancyBootstrapper.cs" />
<Compile Include="Update\UpdateModule.cs" />
<Compile Include="Update\UpdateResource.cs" />
<Compile Include="Validation\NetImportSyncIntervalValidator.cs" />
<Compile Include="Validation\RssSyncIntervalValidator.cs" />
<Compile Include="Validation\EmptyCollectionValidator.cs" />
<Compile Include="Validation\RuleBuilderExtensions.cs" />
<Compile Include="Wanted\LegacyMissingModule.cs" />
<Compile Include="Wanted\MovieCutoffModule.cs" />
<Compile Include="Wanted\MovieMissingModule.cs" />
<Compile Include="Movies\MovieDiscoverModule.cs" />
<Compile Include="NetImport\ImportExclusionsModule.cs" />
<Compile Include="NetImport\ImportExclusionsResource.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Marr.Data\Marr.Data.csproj">
<Project>{F6FC6BE7-0847-4817-A1ED-223DC647C3D7}</Project>
<Name>Marr.Data</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
<Project>{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}</Project>
<Name>NzbDrone.Core</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.SignalR\NzbDrone.SignalR.csproj">
<Project>{7C2CC69F-5CA0-4E5C-85CB-983F9F6C3B36}</Project>
<Name>NzbDrone.SignalR</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
-->
</Project>

View File

@@ -1,5 +1,4 @@
using NzbDrone.Api.Episodes;
using NzbDrone.Api.Series;
using NzbDrone.Api.Movies;
using NzbDrone.Core.Parser;
namespace NzbDrone.Api.Parse
@@ -18,23 +17,22 @@ namespace NzbDrone.Api.Parse
private ParseResource Parse()
{
var title = Request.Query.Title.Value as string;
var parsedEpisodeInfo = Parser.ParseTitle(title);
var parsedMovieInfo = Parser.ParseMovieTitle(title, false);
if (parsedEpisodeInfo == null)
if (parsedMovieInfo == null)
{
return null;
}
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
var remoteMovie = _parsingService.Map(parsedMovieInfo, "");
if (remoteEpisode != null)
if (remoteMovie != null)
{
return new ParseResource
{
Title = title,
ParsedEpisodeInfo = remoteEpisode.ParsedEpisodeInfo,
Series = remoteEpisode.Series.ToResource(),
Episodes = remoteEpisode.Episodes.ToResource()
ParsedMovieInfo = remoteMovie.RemoteMovie.ParsedMovieInfo,
Movie = remoteMovie.Movie.ToResource()
};
}
else
@@ -42,9 +40,9 @@ namespace NzbDrone.Api.Parse
return new ParseResource
{
Title = title,
ParsedEpisodeInfo = parsedEpisodeInfo
ParsedMovieInfo = parsedMovieInfo
};
}
}
}
}
}

View File

@@ -1,7 +1,6 @@
using System.Collections.Generic;
using NzbDrone.Api.Episodes;
using System.Collections.Generic;
using NzbDrone.Api.Movies;
using NzbDrone.Api.REST;
using NzbDrone.Api.Series;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Api.Parse
@@ -9,8 +8,7 @@ namespace NzbDrone.Api.Parse
public class ParseResource : RestResource
{
public string Title { get; set; }
public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; }
public SeriesResource Series { get; set; }
public List<EpisodeResource> Episodes { get; set; }
public ParsedMovieInfo ParsedMovieInfo { get; set; }
public MovieResource Movie { get; set; }
}
}
}

View File

@@ -1,10 +1,8 @@
using System;
using System;
using System.Collections.Generic;
using NzbDrone.Api.REST;
using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Core.Download.TrackedDownloads;
using NzbDrone.Core.Indexers;
using System.Linq;
@@ -13,8 +11,6 @@ namespace NzbDrone.Api.Queue
{
public class QueueResource : RestResource
{
public SeriesResource Series { get; set; }
public EpisodeResource Episode { get; set; }
public MovieResource Movie { get; set; }
public QualityModel Quality { get; set; }
public decimal Size { get; set; }
@@ -38,9 +34,6 @@ namespace NzbDrone.Api.Queue
return new QueueResource
{
Id = model.Id,
Series = model.Series.ToResource(),
Episode = model.Episode.ToResource(),
Quality = model.Quality,
Size = model.Size,
Title = model.Title,

View File

@@ -124,7 +124,7 @@ namespace NzbDrone.Api.REST
Get[ROOT_ROUTE] = options =>
{
var pagingSpec = ReadPagingResourceFromRequest();
if (pagingSpec.Page == 0 && pagingSpec.PageSize == 0)
if ((pagingSpec.Page == 0 && pagingSpec.PageSize == 0) || pagingSpec.PageSize == -1)
{
var all = GetResourceAll();
return all.AsResponse();

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.RootFolders;
@@ -9,6 +9,7 @@ namespace NzbDrone.Api.RootFolders
{
public string Path { get; set; }
public long? FreeSpace { get; set; }
public long? TotalSpace { get; set; }
public List<UnmappedFolder> UnmappedFolders { get; set; }
}
@@ -25,6 +26,7 @@ namespace NzbDrone.Api.RootFolders
Path = model.Path,
FreeSpace = model.FreeSpace,
TotalSpace = model.TotalSpace,
UnmappedFolders = model.UnmappedFolders
};
}
@@ -48,4 +50,4 @@ namespace NzbDrone.Api.RootFolders
return models.Select(ToResource).ToList();
}
}
}
}

View File

@@ -1,31 +0,0 @@
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.SeasonPass
{
public class SeasonPassModule : NzbDroneApiModule
{
private readonly IEpisodeMonitoredService _episodeMonitoredService;
public SeasonPassModule(IEpisodeMonitoredService episodeMonitoredService)
: base("/seasonpass")
{
_episodeMonitoredService = episodeMonitoredService;
Post["/"] = series => UpdateAll();
}
private Response UpdateAll()
{
//Read from request
var request = Request.Body.FromJson<SeasonPassResource>();
foreach (var s in request.Series)
{
_episodeMonitoredService.SetEpisodeMonitoredStatus(s, request.MonitoringOptions);
}
return "ok".AsResponse(HttpStatusCode.Accepted);
}
}
}

View File

@@ -1,11 +0,0 @@
using System.Collections.Generic;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.SeasonPass
{
public class SeasonPassResource
{
public List<Core.Tv.Series> Series { get; set; }
public MonitoringOptions MonitoringOptions { get; set; }
}
}

View File

@@ -1,298 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Api.Extensions;
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.SignalR;
using NzbDrone.Core.Datastore;
using Microsoft.CSharp.RuntimeBinder;
using Nancy;
namespace NzbDrone.Api.Movie
{
public class MovieModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
IHandle<EpisodeImportedEvent>,
IHandle<EpisodeFileDeletedEvent>,
IHandle<MovieUpdatedEvent>,
IHandle<MovieEditedEvent>,
IHandle<MovieDeletedEvent>,
IHandle<MovieRenamedEvent>,
IHandle<MediaCoversUpdatedEvent>
{
protected readonly IMovieService _moviesService;
private readonly IMovieStatisticsService _moviesStatisticsService;
private readonly IMapCoversToLocal _coverMapper;
private const string TITLE_SLUG_ROUTE = "/titleslug/(?<slug>[^/]+)";
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
IMovieService moviesService,
IMovieStatisticsService moviesStatisticsService,
ISceneMappingService sceneMappingService,
IMapCoversToLocal coverMapper,
RootFolderValidator rootFolderValidator,
MoviePathValidator moviesPathValidator,
MovieExistsValidator moviesExistsValidator,
DroneFactoryValidator droneFactoryValidator,
MovieAncestorValidator moviesAncestorValidator,
ProfileExistsValidator profileExistsValidator
)
: base(signalRBroadcaster)
{
_moviesService = moviesService;
_moviesStatisticsService = moviesStatisticsService;
_coverMapper = coverMapper;
GetResourceAll = AllMovie;
GetResourcePaged = GetMoviePaged;
GetResourceById = GetMovie;
Get[TITLE_SLUG_ROUTE] = GetByTitleSlug; /*(options) => {
return ReqResExtensions.AsResponse(GetByTitleSlug(options.slug), Nancy.HttpStatusCode.OK);
};*/
CreateResource = AddMovie;
UpdateResource = UpdateMovie;
DeleteResource = DeleteMovie;
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
SharedValidator.RuleFor(s => s.Path)
.Cascade(CascadeMode.StopOnFirstFailure)
.IsValidPath()
.SetValidator(rootFolderValidator)
.SetValidator(moviesPathValidator)
.SetValidator(droneFactoryValidator)
.SetValidator(moviesAncestorValidator)
.When(s => !s.Path.IsNullOrWhiteSpace());
SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator);
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
PostValidator.RuleFor(s => s.Title).NotEmpty();
PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
PutValidator.RuleFor(s => s.Path).IsValidPath();
}
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
IMovieService moviesService,
IMovieStatisticsService moviesStatisticsService,
ISceneMappingService sceneMappingService,
IMapCoversToLocal coverMapper,
string resource)
: base(signalRBroadcaster, resource)
{
_moviesService = moviesService;
_moviesStatisticsService = moviesStatisticsService;
_coverMapper = coverMapper;
GetResourceAll = AllMovie;
GetResourceById = GetMovie;
CreateResource = AddMovie;
UpdateResource = UpdateMovie;
DeleteResource = DeleteMovie;
}
private MovieResource GetMovie(int id)
{
var movies = _moviesService.GetMovie(id);
return MapToResource(movies);
}
private PagingResource<MovieResource> GetMoviePaged(PagingResource<MovieResource> pagingResource)
{
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>();
pagingSpec.FilterExpression = _moviesService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue, pagingResource.FilterType);
return ApplyToPage(_moviesService.Paged, pagingSpec, MapToResource);
}
protected MovieResource MapToResource(Core.Tv.Movie movies)
{
if (movies == null) return null;
var resource = movies.ToResource();
MapCoversToLocal(resource);
FetchAndLinkMovieStatistics(resource);
PopulateAlternateTitles(resource);
return resource;
}
private List<MovieResource> AllMovie()
{
var moviesStats = _moviesStatisticsService.MovieStatistics();
var moviesResources = _moviesService.GetAllMovies().ToResource();
MapCoversToLocal(moviesResources.ToArray());
LinkMovieStatistics(moviesResources, moviesStats);
PopulateAlternateTitles(moviesResources);
return moviesResources;
}
private Response GetByTitleSlug(dynamic options)
{
var slug = "";
try
{
slug = options.slug;
// do stuff with x
}
catch (RuntimeBinderException)
{
return new NotFoundResponse();
}
try
{
return MapToResource(_moviesService.FindByTitleSlug(slug)).AsResponse(Nancy.HttpStatusCode.OK);
}
catch (ModelNotFoundException)
{
return new NotFoundResponse();
}
}
private int AddMovie(MovieResource moviesResource)
{
var model = moviesResource.ToModel();
return _moviesService.AddMovie(model).Id;
}
private void UpdateMovie(MovieResource moviesResource)
{
var model = moviesResource.ToModel(_moviesService.GetMovie(moviesResource.Id));
_moviesService.UpdateMovie(model);
BroadcastResourceChange(ModelAction.Updated, moviesResource);
}
private void DeleteMovie(int id)
{
var deleteFiles = false;
var addExclusion = false;
var deleteFilesQuery = Request.Query.deleteFiles;
var addExclusionQuery = Request.Query.addExclusion;
if (deleteFilesQuery.HasValue)
{
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
}
if (addExclusionQuery.HasValue)
{
addExclusion = Convert.ToBoolean(addExclusionQuery.Value);
}
_moviesService.DeleteMovie(id, deleteFiles, addExclusion);
}
private void MapCoversToLocal(params MovieResource[] movies)
{
foreach (var moviesResource in movies)
{
_coverMapper.ConvertToLocalUrls(moviesResource.Id, moviesResource.Images);
}
}
private void FetchAndLinkMovieStatistics(MovieResource resource)
{
LinkMovieStatistics(resource, _moviesStatisticsService.MovieStatistics(resource.Id));
}
private void LinkMovieStatistics(List<MovieResource> resources, List<MovieStatistics> moviesStatistics)
{
var dictMovieStats = moviesStatistics.ToDictionary(v => v.MovieId);
foreach (var movies in resources)
{
var stats = dictMovieStats.GetValueOrDefault(movies.Id);
if (stats == null) continue;
LinkMovieStatistics(movies, stats);
}
}
private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics)
{
//resource.SizeOnDisk = 0;//TODO: incorporate movie statistics moviesStatistics.SizeOnDisk;
}
private void PopulateAlternateTitles(List<MovieResource> resources)
{
foreach (var resource in resources)
{
PopulateAlternateTitles(resource);
}
}
private void PopulateAlternateTitles(MovieResource resource)
{
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
//if (mappings == null) return;
//Not necessary anymore
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
}
public void Handle(EpisodeImportedEvent message)
{
//BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.MovieId);
}
public void Handle(EpisodeFileDeletedEvent message)
{
if (message.Reason == DeleteMediaFileReason.Upgrade) return;
//BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.MovieId);
}
public void Handle(MovieUpdatedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MovieEditedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MovieDeletedEvent message)
{
BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource());
}
public void Handle(MovieRenamedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MediaCoversUpdatedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
}
}

View File

@@ -1,47 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Series
{
public class SeasonResource
{
public int SeasonNumber { get; set; }
public bool Monitored { get; set; }
public SeasonStatisticsResource Statistics { get; set; }
}
public static class SeasonResourceMapper
{
public static SeasonResource ToResource(this Season model)
{
if (model == null) return null;
return new SeasonResource
{
SeasonNumber = model.SeasonNumber,
Monitored = model.Monitored
};
}
public static Season ToModel(this SeasonResource resource)
{
if (resource == null) return null;
return new Season
{
SeasonNumber = resource.SeasonNumber,
Monitored = resource.Monitored
};
}
public static List<SeasonResource> ToResource(this IEnumerable<Season> models)
{
return models.Select(ToResource).ToList();
}
public static List<Season> ToModel(this IEnumerable<SeasonResource> resources)
{
return resources.Select(ToModel).ToList();
}
}
}

View File

@@ -1,43 +0,0 @@
using System;
using NzbDrone.Core.SeriesStats;
namespace NzbDrone.Api.Series
{
public class SeasonStatisticsResource
{
public DateTime? NextAiring { get; set; }
public DateTime? PreviousAiring { get; set; }
public int EpisodeFileCount { get; set; }
public int EpisodeCount { get; set; }
public int TotalEpisodeCount { get; set; }
public long SizeOnDisk { get; set; }
public decimal PercentOfEpisodes
{
get
{
if (EpisodeCount == 0) return 0;
return (decimal)EpisodeFileCount / (decimal)EpisodeCount * 100;
}
}
}
public static class SeasonStatisticsResourceMapper
{
public static SeasonStatisticsResource ToResource(this SeasonStatistics model)
{
if (model == null) return null;
return new SeasonStatisticsResource
{
NextAiring = model.NextAiring,
PreviousAiring = model.PreviousAiring,
EpisodeFileCount = model.EpisodeFileCount,
EpisodeCount = model.EpisodeFileCount,
TotalEpisodeCount = model.TotalEpisodeCount,
SizeOnDisk = model.SizeOnDisk
};
}
}
}

View File

@@ -1,31 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Series
{
public class SeriesEditorModule : NzbDroneApiModule
{
private readonly ISeriesService _seriesService;
public SeriesEditorModule(ISeriesService seriesService)
: base("/series/editor")
{
_seriesService = seriesService;
Put["/"] = series => SaveAll();
}
private Response SaveAll()
{
var resources = Request.Body.FromJson<List<SeriesResource>>();
var series = resources.Select(seriesResource => seriesResource.ToModel(_seriesService.GetSeries(seriesResource.Id))).ToList();
return _seriesService.UpdateSeries(series)
.ToResource()
.AsResponse(HttpStatusCode.Accepted);
}
}
}

View File

@@ -1,44 +0,0 @@
using System.Collections.Generic;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource;
using System.Linq;
namespace NzbDrone.Api.Series
{
public class SeriesLookupModule : NzbDroneRestModule<SeriesResource>
{
private readonly ISearchForNewSeries _searchProxy;
public SeriesLookupModule(ISearchForNewSeries searchProxy)
: base("/series/lookup")
{
_searchProxy = searchProxy;
Get["/"] = x => Search();
}
private Response Search()
{
var tvDbResults = _searchProxy.SearchForNewSeries((string)Request.Query.term);
return MapToResource(tvDbResults).AsResponse();
}
private static IEnumerable<SeriesResource> MapToResource(IEnumerable<Core.Tv.Series> series)
{
foreach (var currentSeries in series)
{
var resource = currentSeries.ToResource();
var poster = currentSeries.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster);
if (poster != null)
{
resource.RemotePoster = poster.Url;
}
yield return resource;
}
}
}
}

View File

@@ -1,242 +1,47 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using NzbDrone.Common.Extensions;
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.SeriesStats;
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.SignalR;
namespace NzbDrone.Api.Series
{
public class SeriesModule : NzbDroneRestModuleWithSignalR<SeriesResource, Core.Tv.Series>,
IHandle<EpisodeImportedEvent>,
IHandle<EpisodeFileDeletedEvent>,
IHandle<SeriesUpdatedEvent>,
IHandle<SeriesEditedEvent>,
IHandle<SeriesDeletedEvent>,
IHandle<SeriesRenamedEvent>,
IHandle<MediaCoversUpdatedEvent>
[Obsolete("SeriesModule is Obsolete, Remove with new UI")]
public class SeriesModule : NzbDroneRestModuleWithSignalR<SeriesResource, Core.Tv.Series>
{
private readonly ISeriesService _seriesService;
private readonly ISeriesStatisticsService _seriesStatisticsService;
private readonly ISceneMappingService _sceneMappingService;
private readonly IMapCoversToLocal _coverMapper;
public SeriesModule(IBroadcastSignalRMessage signalRBroadcaster,
ISeriesService seriesService,
ISeriesStatisticsService seriesStatisticsService,
ISceneMappingService sceneMappingService,
IMapCoversToLocal coverMapper,
RootFolderValidator rootFolderValidator,
SeriesPathValidator seriesPathValidator,
SeriesExistsValidator seriesExistsValidator,
DroneFactoryValidator droneFactoryValidator,
SeriesAncestorValidator seriesAncestorValidator,
ProfileExistsValidator profileExistsValidator
)
public SeriesModule(IBroadcastSignalRMessage signalRBroadcaster
)
: base(signalRBroadcaster)
{
_seriesService = seriesService;
_seriesStatisticsService = seriesStatisticsService;
_sceneMappingService = sceneMappingService;
_coverMapper = coverMapper;
GetResourceAll = AllSeries;
GetResourceById = GetSeries;
CreateResource = AddSeries;
UpdateResource = UpdateSeries;
DeleteResource = DeleteSeries;
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
SharedValidator.RuleFor(s => s.Path)
.Cascade(CascadeMode.StopOnFirstFailure)
.IsValidPath()
.SetValidator(rootFolderValidator)
.SetValidator(seriesPathValidator)
.SetValidator(droneFactoryValidator)
.SetValidator(seriesAncestorValidator)
.When(s => !s.Path.IsNullOrWhiteSpace());
SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator);
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
PostValidator.RuleFor(s => s.Title).NotEmpty();
PostValidator.RuleFor(s => s.TvdbId).GreaterThan(0).SetValidator(seriesExistsValidator);
PutValidator.RuleFor(s => s.Path).IsValidPath();
}
private SeriesResource GetSeries(int id)
{
var series = _seriesService.GetSeries(id);
return MapToResource(series);
}
private SeriesResource MapToResource(Core.Tv.Series series)
{
if (series == null) return null;
var resource = series.ToResource();
MapCoversToLocal(resource);
FetchAndLinkSeriesStatistics(resource);
PopulateAlternateTitles(resource);
return resource;
return new SeriesResource();
}
private List<SeriesResource> AllSeries()
{
var seriesStats = _seriesStatisticsService.SeriesStatistics();
var seriesResources = _seriesService.GetAllSeries().ToResource();
MapCoversToLocal(seriesResources.ToArray());
LinkSeriesStatistics(seriesResources, seriesStats);
PopulateAlternateTitles(seriesResources);
return seriesResources;
return new List<SeriesResource>();
}
private int AddSeries(SeriesResource seriesResource)
{
var model = seriesResource.ToModel();
return _seriesService.AddSeries(model).Id;
return 0;
}
private void UpdateSeries(SeriesResource seriesResource)
{
var model = seriesResource.ToModel(_seriesService.GetSeries(seriesResource.Id));
_seriesService.UpdateSeries(model);
BroadcastResourceChange(ModelAction.Updated, seriesResource);
throw new NotImplementedException();
}
private void DeleteSeries(int id)
{
var deleteFiles = false;
var deleteFilesQuery = Request.Query.deleteFiles;
if (deleteFilesQuery.HasValue)
{
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
}
_seriesService.DeleteSeries(id, deleteFiles);
}
private void MapCoversToLocal(params SeriesResource[] series)
{
foreach (var seriesResource in series)
{
_coverMapper.ConvertToLocalUrls(seriesResource.Id, seriesResource.Images);
}
}
private void FetchAndLinkSeriesStatistics(SeriesResource resource)
{
LinkSeriesStatistics(resource, _seriesStatisticsService.SeriesStatistics(resource.Id));
}
private void LinkSeriesStatistics(List<SeriesResource> resources, List<SeriesStatistics> seriesStatistics)
{
var dictSeriesStats = seriesStatistics.ToDictionary(v => v.SeriesId);
foreach (var series in resources)
{
var stats = dictSeriesStats.GetValueOrDefault(series.Id);
if (stats == null) continue;
LinkSeriesStatistics(series, stats);
}
}
private void LinkSeriesStatistics(SeriesResource resource, SeriesStatistics seriesStatistics)
{
resource.TotalEpisodeCount = seriesStatistics.TotalEpisodeCount;
resource.EpisodeCount = seriesStatistics.EpisodeCount;
resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount;
resource.NextAiring = seriesStatistics.NextAiring;
resource.PreviousAiring = seriesStatistics.PreviousAiring;
resource.SizeOnDisk = seriesStatistics.SizeOnDisk;
if (seriesStatistics.SeasonStatistics != null)
{
var dictSeasonStats = seriesStatistics.SeasonStatistics.ToDictionary(v => v.SeasonNumber);
foreach (var season in resource.Seasons)
{
season.Statistics = SeasonStatisticsResourceMapper.ToResource(dictSeasonStats.GetValueOrDefault(season.SeasonNumber));
}
}
}
private void PopulateAlternateTitles(List<SeriesResource> resources)
{
foreach (var resource in resources)
{
PopulateAlternateTitles(resource);
}
}
private void PopulateAlternateTitles(SeriesResource resource)
{
var mappings = _sceneMappingService.FindByTvdbId(resource.TvdbId);
if (mappings == null) return;
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
}
public void Handle(EpisodeImportedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.SeriesId);
}
public void Handle(EpisodeFileDeletedEvent message)
{
if (message.Reason == DeleteMediaFileReason.Upgrade) return;
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.SeriesId);
}
public void Handle(SeriesUpdatedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
}
public void Handle(SeriesEditedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
}
public void Handle(SeriesDeletedEvent message)
{
BroadcastResourceChange(ModelAction.Deleted, message.Series.ToResource());
}
public void Handle(SeriesRenamedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
}
public void Handle(MediaCoversUpdatedEvent message)
{
//BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
throw new NotImplementedException();
}
}
}

View File

@@ -1,232 +1,19 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Series
{
[Obsolete("SeriesResource is Obsolete, Remove with new UI")]
public class SeriesResource : RestResource
{
public SeriesResource()
{
Monitored = true;
Title = "Series Endpoint Obsolete";
}
//Todo: Sorters should be done completely on the client
//Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing?
//Todo: We should get the entire Profile instead of ID and Name separately
//View Only
public string Title { get; set; }
//public List<AlternativeTitleResource> AlternateTitles { get; set; }
public string SortTitle { get; set; }
public int SeasonCount
{
get
{
if (Seasons == null) return 0;
return Seasons.Where(s => s.SeasonNumber > 0).Count();
}
}
public int? TotalEpisodeCount { get; set; }
public int? EpisodeCount { get; set; }
public int? EpisodeFileCount { get; set; }
public long? SizeOnDisk { get; set; }
public SeriesStatusType Status { get; set; }
public string Overview { get; set; }
public DateTime? NextAiring { get; set; }
public DateTime? PreviousAiring { get; set; }
public string Network { get; set; }
public string AirTime { get; set; }
public List<MediaCover> Images { get; set; }
public string RemotePoster { get; set; }
public List<SeasonResource> Seasons { get; set; }
public int Year { get; set; }
//View & Edit
public string Path { get; set; }
public int ProfileId { get; set; }
//Editing Only
public bool SeasonFolder { get; set; }
public bool Monitored { get; set; }
public bool UseSceneNumbering { get; set; }
public int Runtime { get; set; }
public int TvdbId { get; set; }
public int TvRageId { get; set; }
public int TvMazeId { get; set; }
public DateTime? FirstAired { get; set; }
public DateTime? LastInfoSync { get; set; }
public SeriesTypes SeriesType { get; set; }
public string CleanTitle { get; set; }
public string ImdbId { get; set; }
public string TitleSlug { get; set; }
public string RootFolderPath { get; set; }
public string Certification { get; set; }
public List<string> Genres { get; set; }
public HashSet<int> Tags { get; set; }
public DateTime Added { get; set; }
public AddSeriesOptions AddOptions { get; set; }
public Ratings Ratings { get; set; }
//TODO: Add series statistics as a property of the series (instead of individual properties)
//Used to support legacy consumers
public int QualityProfileId
{
get
{
return ProfileId;
}
set
{
if (value > 0 && ProfileId == 0)
{
ProfileId = value;
}
}
}
}
public static class SeriesResourceMapper
{
public static SeriesResource ToResource(this Core.Tv.Series model)
{
if (model == null) return null;
return new SeriesResource
{
Id = model.Id,
Title = model.Title,
//AlternateTitles
SortTitle = model.SortTitle,
//TotalEpisodeCount
//EpisodeCount
//EpisodeFileCount
//SizeOnDisk
Status = model.Status,
Overview = model.Overview,
//NextAiring
//PreviousAiring
Network = model.Network,
AirTime = model.AirTime,
Images = model.Images,
Seasons = model.Seasons.ToResource(),
Year = model.Year,
Path = model.Path,
ProfileId = model.ProfileId,
SeasonFolder = model.SeasonFolder,
Monitored = model.Monitored,
UseSceneNumbering = model.UseSceneNumbering,
Runtime = model.Runtime,
TvdbId = model.TvdbId,
TvRageId = model.TvRageId,
TvMazeId = model.TvMazeId,
FirstAired = model.FirstAired,
LastInfoSync = model.LastInfoSync,
SeriesType = model.SeriesType,
CleanTitle = model.CleanTitle,
ImdbId = model.ImdbId,
TitleSlug = model.TitleSlug,
RootFolderPath = model.RootFolderPath,
Certification = model.Certification,
Genres = model.Genres,
Tags = model.Tags,
Added = model.Added,
AddOptions = model.AddOptions,
Ratings = model.Ratings
};
}
public static Core.Tv.Series ToModel(this SeriesResource resource)
{
if (resource == null) return null;
return new Core.Tv.Series
{
Id = resource.Id,
Title = resource.Title,
//AlternateTitles
SortTitle = resource.SortTitle,
//TotalEpisodeCount
//EpisodeCount
//EpisodeFileCount
//SizeOnDisk
Status = resource.Status,
Overview = resource.Overview,
//NextAiring
//PreviousAiring
Network = resource.Network,
AirTime = resource.AirTime,
Images = resource.Images,
Seasons = resource.Seasons.ToModel(),
Year = resource.Year,
Path = resource.Path,
ProfileId = resource.ProfileId,
SeasonFolder = resource.SeasonFolder,
Monitored = resource.Monitored,
UseSceneNumbering = resource.UseSceneNumbering,
Runtime = resource.Runtime,
TvdbId = resource.TvdbId,
TvRageId = resource.TvRageId,
TvMazeId = resource.TvMazeId,
FirstAired = resource.FirstAired,
LastInfoSync = resource.LastInfoSync,
SeriesType = resource.SeriesType,
CleanTitle = resource.CleanTitle,
ImdbId = resource.ImdbId,
TitleSlug = resource.TitleSlug,
RootFolderPath = resource.RootFolderPath,
Certification = resource.Certification,
Genres = resource.Genres,
Tags = resource.Tags,
Added = resource.Added,
AddOptions = resource.AddOptions,
Ratings = resource.Ratings
};
}
public static Core.Tv.Series ToModel(this SeriesResource resource, Core.Tv.Series series)
{
series.TvdbId = resource.TvdbId;
series.Seasons = resource.Seasons.ToModel();
series.Path = resource.Path;
series.ProfileId = resource.ProfileId;
series.SeasonFolder = resource.SeasonFolder;
series.Monitored = resource.Monitored;
series.SeriesType = resource.SeriesType;
series.RootFolderPath = resource.RootFolderPath;
series.Tags = resource.Tags;
series.AddOptions = resource.AddOptions;
return series;
}
public static List<SeriesResource> ToResource(this IEnumerable<Core.Tv.Series> series)
{
return series.Select(ToResource).ToList();
}
}
}

View File

@@ -21,9 +21,9 @@ namespace NzbDrone.Api.System.Backup
return backups.Select(b => new BackupResource
{
Id = b.Path.GetHashCode(),
Name = Path.GetFileName(b.Path),
Path = b.Path,
Id = b.Name.GetHashCode(),
Name = b.Name,
Path = $"/backup/{b.Type.ToString().ToLower()}/{b.Name}",
Type = b.Type,
Time = b.Time
}).ToList();

View File

@@ -1,42 +0,0 @@
using NzbDrone.Api.Episodes;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv;
using NzbDrone.SignalR;
namespace NzbDrone.Api.Wanted
{
public class CutoffModule : EpisodeModuleWithSignalR
{
private readonly IEpisodeCutoffService _episodeCutoffService;
public CutoffModule(IEpisodeCutoffService episodeCutoffService,
IEpisodeService episodeService,
ISeriesService seriesService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
IBroadcastSignalRMessage signalRBroadcaster)
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff-old")
{
_episodeCutoffService = episodeCutoffService;
GetResourcePaged = GetCutoffUnmetEpisodes;
}
private PagingResource<EpisodeResource> GetCutoffUnmetEpisodes(PagingResource<EpisodeResource> pagingResource)
{
var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>("airDateUtc", SortDirection.Descending);
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
{
pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false;
}
else
{
pagingSpec.FilterExpression = v => v.Monitored == true && v.Series.Monitored == true;
}
var resource = ApplyToPage(_episodeCutoffService.EpisodesWhereCutoffUnmet, pagingSpec, v => MapToResource(v, true, true));
return resource;
}
}
}

View File

@@ -1,38 +0,0 @@
using NzbDrone.Api.Episodes;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv;
using NzbDrone.SignalR;
namespace NzbDrone.Api.Wanted
{
public class MissingModule : EpisodeModuleWithSignalR
{
public MissingModule(IEpisodeService episodeService,
ISeriesService seriesService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
IBroadcastSignalRMessage signalRBroadcaster)
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing_episodes")
{
GetResourcePaged = GetMissingEpisodes;
}
private PagingResource<EpisodeResource> GetMissingEpisodes(PagingResource<EpisodeResource> pagingResource)
{
var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>("airDateUtc", SortDirection.Descending);
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
{
pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false;
}
else
{
pagingSpec.FilterExpression = v => v.Monitored == true && v.Series.Monitored == true;
}
var resource = ApplyToPage(_episodeService.EpisodesWithoutFiles, pagingSpec, v => MapToResource(v, true, false));
return resource;
}
}
}

View File

@@ -1,4 +1,3 @@
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv;
@@ -32,4 +31,4 @@ namespace NzbDrone.Api.Wanted
return resource;
}
}
}
}

View File

@@ -1,4 +1,3 @@
using NzbDrone.Api.Movie;
using NzbDrone.Api.Movies;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Tv;

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentValidation" version="6.2.1.0" targetFramework="net40" />
<package id="Ical.Net" version="2.2.25" targetFramework="net40" />
<package id="Nancy" version="1.4.3" targetFramework="net40" />
<package id="Nancy.Authentication.Basic" version="1.4.1" targetFramework="net40" />
<package id="Nancy.Authentication.Forms" version="1.4.1" targetFramework="net40" />
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
<package id="NLog" version="4.3.11" targetFramework="net40" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentValidation" version="6.2.1.0" targetFramework="net40" />
<package id="Ical.Net" version="2.2.25" targetFramework="net40" />
<package id="Nancy" version="1.4.3" targetFramework="net40" />
<package id="Nancy.Authentication.Basic" version="1.4.1" targetFramework="net40" />
<package id="Nancy.Authentication.Forms" version="1.4.1" targetFramework="net40" />
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
<package id="NLog" version="4.5.0-rc06" targetFramework="net40" />
</packages>

View File

@@ -1,126 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.App.Test</RootNamespace>
<AssemblyName>NzbDrone.App.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FizzWare.NBuilder, Version=4.0.0.115, Culture=neutral, PublicKeyToken=5651b03e12e42c12, processorArchitecture=MSIL">
<HintPath>..\packages\NBuilder.4.0.0\lib\net40\FizzWare.NBuilder.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Moq">
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ContainerFixture.cs" />
<Compile Include="NzbDroneProcessServiceFixture.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RouterTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\NzbDrone.Test.Common\App.config">
<Link>App.config</Link>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
<Project>{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}</Project>
<Name>NzbDrone.Core</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Host\NzbDrone.Host.csproj">
<Project>{95C11A9E-56ED-456A-8447-2C89C1139266}</Project>
<Name>NzbDrone.Host</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
<Name>NzbDrone.Test.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="..\Libraries\Sqlite\sqlite3.dll">
<Link>sqlite3.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.App.Test</RootNamespace>
<AssemblyName>NzbDrone.App.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FizzWare.NBuilder, Version=4.0.0.115, Culture=neutral, PublicKeyToken=5651b03e12e42c12, processorArchitecture=MSIL">
<HintPath>..\packages\NBuilder.4.0.0\lib\net40\FizzWare.NBuilder.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.5.0-rc06\lib\net40-client\NLog.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Moq">
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ContainerFixture.cs" />
<Compile Include="NzbDroneProcessServiceFixture.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RouterTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\NzbDrone.Test.Common\App.config">
<Link>App.config</Link>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
<Project>{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}</Project>
<Name>NzbDrone.Core</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Host\NzbDrone.Host.csproj">
<Project>{95C11A9E-56ED-456A-8447-2C89C1139266}</Project>
<Name>NzbDrone.Host</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
<Name>NzbDrone.Test.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="..\Libraries\Sqlite\sqlite3.dll">
<Link>sqlite3.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent Condition="('$(OS)' == 'Windows_NT')">
xcopy /s /y "$(SolutionDir)\..\_output\NzbDrone.Mono.*" "$(TargetDir)"
xcopy /s /y "$(SolutionDir)\..\_output\NzbDrone.Windows.*" "$(TargetDir)"
</PostBuildEvent>
</PostBuildEvent>
<PostBuildEvent Condition="('$(OS)' != 'Windows_NT')">
cp -rv $(SolutionDir)\..\_output\NzbDrone.Mono.* $(TargetDir)
cp -rv $(SolutionDir)\..\_output\NzbDrone.Windows.* $(TargetDir)
</PostBuildEvent>
</PropertyGroup>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
-->
</Project>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
<package id="Moq" version="4.0.10827" />
<package id="NBuilder" version="4.0.0" targetFramework="net40" />
<package id="NLog" version="4.3.11" targetFramework="net40" />
<package id="NUnit" version="3.5.0" targetFramework="net40" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
<package id="Moq" version="4.0.10827" />
<package id="NBuilder" version="4.0.0" targetFramework="net40" />
<package id="NLog" version="4.5.0-rc06" targetFramework="net40" />
<package id="NUnit" version="3.5.0" targetFramework="net40" />
</packages>

View File

@@ -1,106 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{CC26800D-F67E-464B-88DE-8EB1A0C227A3}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.Automation.Test</RootNamespace>
<AssemblyName>NzbDrone.Automation.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<ProductVersion>12.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="WebDriver, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Selenium.WebDriver.3.0.1\lib\net40\WebDriver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="WebDriver.Support, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Selenium.Support.3.0.1\lib\net40\WebDriver.Support.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AutomationTest.cs" />
<Compile Include="AutomationTestAttribute.cs" />
<Compile Include="MainPagesTest.cs" />
<Compile Include="PageModel\PageBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
<Name>NzbDrone.Test.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{CC26800D-F67E-464B-88DE-8EB1A0C227A3}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.Automation.Test</RootNamespace>
<AssemblyName>NzbDrone.Automation.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<ProductVersion>12.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.5.0-rc06\lib\net40-client\NLog.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="WebDriver, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Selenium.WebDriver.3.0.1\lib\net40\WebDriver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="WebDriver.Support, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Selenium.Support.3.0.1\lib\net40\WebDriver.Support.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AutomationTest.cs" />
<Compile Include="AutomationTestAttribute.cs" />
<Compile Include="MainPagesTest.cs" />
<Compile Include="PageModel\PageBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
<Name>NzbDrone.Test.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
-->
</Project>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
<package id="NLog" version="4.3.11" targetFramework="net40" />
<package id="NUnit" version="3.5.0" targetFramework="net40" />
<package id="Selenium.Support" version="3.0.1" targetFramework="net40" />
<package id="Selenium.WebDriver" version="3.0.1" targetFramework="net40" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
<package id="NLog" version="4.5.0-rc06" targetFramework="net40" />
<package id="NUnit" version="3.5.0" targetFramework="net40" />
<package id="Selenium.Support" version="3.0.1" targetFramework="net40" />
<package id="Selenium.WebDriver" version="3.0.1" targetFramework="net40" />
</packages>

View File

@@ -54,7 +54,7 @@ namespace NzbDrone.Common.Test.Http
response.Content.Should().NotBeNullOrWhiteSpace();
}
[Test]
public void should_execute_https_get()
{
@@ -132,7 +132,49 @@ namespace NzbDrone.Common.Test.Http
var request = new HttpRequest(string.Format("http://{0}/redirect/1", _httpBinHost));
request.AllowAutoRedirect = true;
Subject.Get(request);
var response = Subject.Get(request);
response.StatusCode.Should().Be(HttpStatusCode.OK);
ExceptionVerification.ExpectedErrors(0);
}
[Test]
public void should_not_follow_redirects()
{
var request = new HttpRequest($"http://{_httpBinHost}/redirect/1");
request.AllowAutoRedirect = false;
var response = Subject.Get(request);
response.StatusCode.Should().Be(HttpStatusCode.Found);
ExceptionVerification.ExpectedErrors(1);
}
[Test]
public void should_follow_redirects_to_https()
{
var request = new HttpRequestBuilder($"http://{_httpBinHost}/redirect-to")
.AddQueryParam("url", $"https://sonarr.tv/")
.Build();
request.AllowAutoRedirect = true;
var response = Subject.Get(request);
response.StatusCode.Should().Be(HttpStatusCode.OK);
response.Content.Should().Contain("Sonarr");
ExceptionVerification.ExpectedErrors(0);
}
[Test]
public void should_throw_on_too_many_redirects()
{
var request = new HttpRequest($"http://{_httpBinHost}/redirect/4");
request.AllowAutoRedirect = true;
Assert.Throws<WebException>(() => Subject.Get(request));
ExceptionVerification.ExpectedErrors(0);
}
@@ -400,4 +442,4 @@ namespace NzbDrone.Common.Test.Http
public string Url { get; set; }
public string Data { get; set; }
}
}
}

View File

@@ -15,6 +15,7 @@ namespace NzbDrone.Common.Test.InstrumentationTests
[TestCase(@"https://rss.omgwtfnzbs.org/rss-search.php?catid=19,20&user=sonarr&api=mySecret&eng=1")]
[TestCase(@"https://dognzb.cr/fetch/2b51db35e1912ffc138825a12b9933d2/2b51db35e1910123321025a12b9933d2")]
[TestCase(@"https://baconbits.org/feeds.php?feed=torrents_tv&user=12345&auth=2b51db35e1910123321025a12b9933d2&passkey=mySecret&authkey=2b51db35e1910123321025a12b9933d2")]
[TestCase(@"http://127.0.0.1:9117/dl/indexername?jackett_apikey=flwjiefewklfjacketmySecretsdfldskjfsdlk&path=we0re9f0sdfbase64sfdkfjsdlfjk&file=The+Torrent+File+Name.torrent")]
// NzbGet
[TestCase(@"{ ""Name"" : ""ControlUsername"", ""Value"" : ""mySecret"" }, { ""Name"" : ""ControlPassword"", ""Value"" : ""mySecret"" }, ")]
[TestCase(@"{ ""Name"" : ""Server1.Username"", ""Value"" : ""mySecret"" }, { ""Name"" : ""Server1.Password"", ""Value"" : ""mySecret"" }, ")]

View File

@@ -1,161 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{BEC74619-DDBB-4FBA-B517-D3E20AFC9997}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.Common.Test</RootNamespace>
<AssemblyName>NzbDrone.Common.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="Moq">
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CacheTests\CachedDictionaryFixture.cs" />
<Compile Include="CacheTests\CachedFixture.cs" />
<Compile Include="CacheTests\CachedManagerFixture.cs" />
<Compile Include="ConfigFileProviderTest.cs" />
<Compile Include="DiskTests\DirectoryLookupServiceFixture.cs" />
<Compile Include="DiskTests\DiskProviderFixtureBase.cs" />
<Compile Include="DiskTests\FreeSpaceFixtureBase.cs" />
<Compile Include="DiskTests\IsParentFixtureBase.cs" />
<Compile Include="DiskTests\DiskTransferServiceFixture.cs" />
<Compile Include="EnsureTest\PathExtensionFixture.cs" />
<Compile Include="EnvironmentProviderTest.cs" />
<Compile Include="EnvironmentTests\EnvironmentProviderTest.cs" />
<Compile Include="EnvironmentTests\StartupArgumentsFixture.cs" />
<Compile Include="ExtensionTests\FromOctalStringFixture.cs" />
<Compile Include="ExtensionTests\IEnumerableExtensionTests\ExceptByFixture.cs" />
<Compile Include="ExtensionTests\IEnumerableExtensionTests\IntersectByFixture.cs" />
<Compile Include="ExtensionTests\Int64ExtensionFixture.cs" />
<Compile Include="Http\HttpClientFixture.cs" />
<Compile Include="Http\HttpHeaderFixture.cs" />
<Compile Include="Http\HttpRequestBuilderFixture.cs" />
<Compile Include="Http\HttpRequestFixture.cs" />
<Compile Include="Http\HttpUriFixture.cs" />
<Compile Include="InstrumentationTests\CleanseLogMessageFixture.cs" />
<Compile Include="LevenshteinDistanceFixture.cs" />
<Compile Include="OsPathFixture.cs" />
<Compile Include="PathExtensionFixture.cs" />
<Compile Include="ProcessProviderTests.cs" />
<Compile Include="ReflectionExtensions.cs" />
<Compile Include="ReflectionTests\ReflectionExtensionFixture.cs" />
<Compile Include="ServiceFactoryFixture.cs" />
<Compile Include="ServiceProviderTests.cs" />
<Compile Include="TPLTests\DebouncerFixture.cs" />
<Compile Include="TPLTests\RateLimitServiceFixture.cs" />
<Compile Include="WebClientTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\NzbDrone.Test.Common\App.config">
<Link>App.config</Link>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
<Project>{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}</Project>
<Name>NzbDrone.Core</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Host\NzbDrone.Host.csproj">
<Project>{95C11A9E-56ED-456A-8447-2C89C1139266}</Project>
<Name>NzbDrone.Host</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Mono\NzbDrone.Mono.csproj">
<Project>{15ad7579-a314-4626-b556-663f51d97cd1}</Project>
<Name>NzbDrone.Mono</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Windows\NzbDrone.Windows.csproj">
<Project>{911284d3-f130-459e-836c-2430b6fbf21d}</Project>
<Name>NzbDrone.Windows</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone\NzbDrone.csproj">
<Project>{D12F7F2F-8A3C-415F-88FA-6DD061A84869}</Project>
<Name>NzbDrone</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
<Name>NzbDrone.Test.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Dummy\NzbDrone.Test.Dummy.csproj">
<Project>{FAFB5948-A222-4CF6-AD14-026BE7564802}</Project>
<Name>NzbDrone.Test.Dummy</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent Condition="'$(Configuration)|$(OS)' == 'Debug|Windows_NT'">xcopy /s /y "$(SolutionDir)\ExternalModules\CurlSharp\libs\i386\*" "$(TargetDir)"</PostBuildEvent>
</PropertyGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{BEC74619-DDBB-4FBA-B517-D3E20AFC9997}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.Common.Test</RootNamespace>
<AssemblyName>NzbDrone.Common.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.5.0-rc06\lib\net40-client\NLog.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="Moq">
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CacheTests\CachedDictionaryFixture.cs" />
<Compile Include="CacheTests\CachedFixture.cs" />
<Compile Include="CacheTests\CachedManagerFixture.cs" />
<Compile Include="ConfigFileProviderTest.cs" />
<Compile Include="DiskTests\DirectoryLookupServiceFixture.cs" />
<Compile Include="DiskTests\DiskProviderFixtureBase.cs" />
<Compile Include="DiskTests\FreeSpaceFixtureBase.cs" />
<Compile Include="DiskTests\IsParentFixtureBase.cs" />
<Compile Include="DiskTests\DiskTransferServiceFixture.cs" />
<Compile Include="EnsureTest\PathExtensionFixture.cs" />
<Compile Include="EnvironmentProviderTest.cs" />
<Compile Include="EnvironmentTests\EnvironmentProviderTest.cs" />
<Compile Include="EnvironmentTests\StartupArgumentsFixture.cs" />
<Compile Include="ExtensionTests\FromOctalStringFixture.cs" />
<Compile Include="ExtensionTests\IEnumerableExtensionTests\ExceptByFixture.cs" />
<Compile Include="ExtensionTests\IEnumerableExtensionTests\IntersectByFixture.cs" />
<Compile Include="ExtensionTests\Int64ExtensionFixture.cs" />
<Compile Include="Http\HttpClientFixture.cs" />
<Compile Include="Http\HttpHeaderFixture.cs" />
<Compile Include="Http\HttpRequestBuilderFixture.cs" />
<Compile Include="Http\HttpRequestFixture.cs" />
<Compile Include="Http\HttpUriFixture.cs" />
<Compile Include="InstrumentationTests\CleanseLogMessageFixture.cs" />
<Compile Include="LevenshteinDistanceFixture.cs" />
<Compile Include="OsPathFixture.cs" />
<Compile Include="PathExtensionFixture.cs" />
<Compile Include="ProcessProviderTests.cs" />
<Compile Include="ReflectionExtensions.cs" />
<Compile Include="ReflectionTests\ReflectionExtensionFixture.cs" />
<Compile Include="ServiceFactoryFixture.cs" />
<Compile Include="ServiceProviderTests.cs" />
<Compile Include="TPLTests\DebouncerFixture.cs" />
<Compile Include="TPLTests\RateLimitServiceFixture.cs" />
<Compile Include="WebClientTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\NzbDrone.Test.Common\App.config">
<Link>App.config</Link>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
<Project>{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}</Project>
<Name>NzbDrone.Core</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Host\NzbDrone.Host.csproj">
<Project>{95C11A9E-56ED-456A-8447-2C89C1139266}</Project>
<Name>NzbDrone.Host</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Mono\NzbDrone.Mono.csproj">
<Project>{15ad7579-a314-4626-b556-663f51d97cd1}</Project>
<Name>NzbDrone.Mono</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Windows\NzbDrone.Windows.csproj">
<Project>{911284d3-f130-459e-836c-2430b6fbf21d}</Project>
<Name>NzbDrone.Windows</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone\NzbDrone.csproj">
<Project>{D12F7F2F-8A3C-415F-88FA-6DD061A84869}</Project>
<Name>NzbDrone</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
<Name>NzbDrone.Test.Common</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Dummy\NzbDrone.Test.Dummy.csproj">
<Project>{FAFB5948-A222-4CF6-AD14-026BE7564802}</Project>
<Name>NzbDrone.Test.Dummy</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent Condition="'$(Configuration)|$(OS)' == 'Debug|Windows_NT'">xcopy /s /y "$(SolutionDir)\ExternalModules\CurlSharp\libs\i386\*" "$(TargetDir)"</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
-->
</Project>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
<package id="Moq" version="4.0.10827" />
<package id="NLog" version="4.3.11" targetFramework="net40" />
<package id="NUnit" version="3.5.0" targetFramework="net40" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
<package id="Moq" version="4.0.10827" />
<package id="NLog" version="4.5.0-rc06" targetFramework="net40" />
<package id="NUnit" version="3.5.0" targetFramework="net40" />
</packages>

View File

@@ -245,6 +245,25 @@ namespace NzbDrone.Common.Disk
File.Move(source, destination);
}
public void MoveFolder(string source, string destination, bool overwrite = false)
{
Ensure.That(source, () => source).IsValidPath();
Ensure.That(destination, () => destination).IsValidPath();
if (source.PathEquals(destination))
{
throw new IOException(string.Format("Source and destination can't be the same {0}", source));
}
if (FolderExists(destination) && overwrite)
{
DeleteFolder(destination, true);
}
RemoveReadOnlyFolder(source);
Directory.Move(source, destination);
}
public abstract bool TryCreateHardLink(string source, string destination);
public void DeleteFolder(string path, bool recursive)
@@ -275,12 +294,22 @@ namespace NzbDrone.Common.Disk
{
Ensure.That(path, () => path).IsValidPath();
if (dateTime.Before(DateTimeExtensions.Epoch))
{
dateTime = DateTimeExtensions.Epoch;
}
Directory.SetLastWriteTimeUtc(path, dateTime);
}
public void FileSetLastWriteTime(string path, DateTime dateTime)
{
Ensure.That(path, () => path).IsValidPath();
if (dateTime.Before(DateTimeExtensions.Epoch))
{
dateTime = DateTimeExtensions.Epoch;
}
File.SetLastWriteTime(path, dateTime);
}
@@ -371,6 +400,20 @@ namespace NzbDrone.Common.Disk
}
}
private static void RemoveReadOnlyFolder(string path)
{
if (Directory.Exists(path))
{
var dirInfo = new DirectoryInfo(path);
if (dirInfo.Attributes.HasFlag(FileAttributes.ReadOnly))
{
var newAttributes = dirInfo.Attributes & ~(FileAttributes.ReadOnly);
dirInfo.Attributes = newAttributes;
}
}
}
public FileAttributes GetFileAttributes(string path)
{
return File.GetAttributes(path);

View File

@@ -30,6 +30,7 @@ namespace NzbDrone.Common.Disk
void DeleteFile(string path);
void CopyFile(string source, string destination, bool overwrite = false);
void MoveFile(string source, string destination, bool overwrite = false);
void MoveFolder(string source, string destination, bool overwrite = false);
bool TryCreateHardLink(string source, string destination);
void DeleteFolder(string path, bool recursive);
string ReadAllText(string filePath);

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