1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-06 13:31:28 -05:00

Compare commits

...

203 Commits

Author SHA1 Message Date
Keivan Beigi
3952ee402b Update readme.md 2015-12-12 11:24:46 -08:00
Mark McDowall
0b3e27cb44 Don't keep dylibs for WIndows and Linux builds 2015-12-09 23:24:50 -08:00
Mark McDowall
4fa4b3507e Fixed: Force grabbing some delayed releases
Closes #984
2015-12-08 22:50:34 -08:00
Mark McDowall
8c211364e2 Fixed: Improved parsing of some multi-episode filenames 2015-12-08 15:26:52 -08:00
Mark McDowall
2d9917d074 Re-order regex to prefer [1x01] over 101 2015-12-06 11:03:11 -08:00
Mark McDowall
d514699ab7 Fixed: Prevent series from being added with an invalid Profile ID
Closes #977
2015-12-05 02:22:22 -08:00
Mark McDowall
dc176a83b3 Update CONTRIBUTING.md 2015-12-01 08:48:41 -08:00
Mark McDowall
69e3516a89 New: Allow Uppercase in Transmission category
Closes #934
2015-11-29 22:01:20 -08:00
Mark McDowall
c8a0f9fa7a Fixed: Saving settings changes 2015-11-26 12:05:37 -08:00
Mark McDowall
c2b9504b15 Merge pull request #931 from Dahlgren/osx-development
Include mediainfo and sqlite3 libraries for Mac
2015-11-24 18:35:07 -08:00
Mark McDowall
2693a3df2e Merge pull request #959 from roguecode/develop
Fixed: Indexer failure log message with local time
2015-11-24 15:41:57 -08:00
Matt
8062466ab8 Changing Indexer failure log message to local from UTC. 2015-11-24 23:42:20 +02:00
Björn Dahlgren
6cde1dd5ae Include mediainfo and sqlite3 libraries for Mac
Enables usage within MonoDevelop and Xamarin Studio including NUnit
2015-11-24 10:21:42 +01:00
Mark McDowall
b6c4a97675 Merge pull request #889 from Sonarr/quality-source
Folder quality when file quality determined by its extension
2015-11-23 23:01:10 -08:00
Mark McDowall
a9444cef30 Fixed: Folder quality when file quality determined by its extension
Closes #603
2015-11-23 23:00:51 -08:00
Mark McDowall
bf217a7093 Merge pull request #754 from Sonarr/real-releases
Support for REAL releases
2015-11-23 22:59:41 -08:00
Mark McDowall
b6b5355261 New: support for REAL releases
Closes #453

New: Added `Quality Real` naming Token
New: Quality Full will add real to file name when applicable
2015-11-23 22:58:53 -08:00
Mark McDowall
bc37084ec4 Merge pull request #928 from Dahlgren/mono-tests
Fixed tests for Mono
2015-11-23 22:50:34 -08:00
Mark McDowall
0a1a30f2af Merge pull request #953 from zetas/nn_preset_nzbcat
New: Newznab Preset for NZBCat
2015-11-23 22:50:15 -08:00
Keivan Beigi
7e023a7944 ConfigServiceFixture shouldn't be touching the DB. 2015-11-23 21:57:01 -08:00
zetas
91f68de8a7 Adding new newznab preset for NZBCat 2015-11-22 07:09:57 -05:00
Björn Dahlgren
994e2a6c57 Fixed failing tests on Mono
Test case unicode characters in escaped format
2015-11-22 01:11:43 +01:00
Mark McDowall
04da2d845a Merge pull request #941 from uzegonemad/hotfix/calendar-legend-width
Give calendar legend ul max width of 100%. Fixes #922
2015-11-18 22:12:39 -08:00
Benjamin Uzelac
d3b87bc3e8 give legend ul max width of 100%
give legend ul max width of 100%
2015-11-18 22:17:05 -06:00
Mark McDowall
554c81f251 Merge pull request #901 from brgaulin/jquery_upgrade
Update jQuery to 1.11.3
2015-11-16 13:44:42 -08:00
Mark McDowall
6de3f9dd0b Merge pull request #942 from uzegonemad/hotfix/calendar-tooltip
Fixed: Hidden calendar tooltips
2015-11-16 13:38:30 -08:00
Mark McDowall
e9692d5b9c Merge pull request #940 from uzegonemad/hotfix/fix-long-path-label
Fixed: Add wrapping to fix long paths in labels
2015-11-16 13:37:26 -08:00
Benjamin Uzelac
1a74990e9b alter calendar tooltip container. fixes #857 2015-11-15 20:50:17 -06:00
Benjamin Uzelac
3b9ac8699d Add wrapping to fix long paths in labels. Fixes #875 2015-11-15 18:25:30 -06:00
Mark McDowall
ea6ae85f7a Fixed: Logging invalid version when failing to connect to Kodi
Closes #927
2015-11-14 22:35:45 -08:00
Mark McDowall
b02b9f026f Fixed: Failing missing episode search when one search fails
Closes #917
2015-11-14 22:35:28 -08:00
Mark McDowall
c419e7b710 Merge pull request #915 from uzegonemad/hotfix/scroll-up-zindex
Fix z-index on scroll to top button
2015-11-14 21:43:37 -08:00
Benjamin Uzelac
cd9132520d fix z-index on scroll to top button 2015-11-05 19:43:53 -06:00
Mark McDowall
08d19df3f7 Fixed: Manual import when quality was not available after failed parsing
Closes #911
2015-11-03 15:12:56 -08:00
Mark McDowall
b34879b4f6 New: Manual search shows error when download fails 2015-11-02 22:46:06 -08:00
Mark McDowall
6b9c4af591 Fixed: Magnet links with torrent blackhole 2015-11-02 22:21:27 -08:00
Mark McDowall
c00c207517 Prevent regrab for all grabs
Fixed: Prevent incorrectly grabbing a similar or identical release for 12 hours
2015-11-01 21:54:49 -08:00
Mark McDowall
6f7fea3591 PFMonkey Newznab preset 2015-11-01 21:35:44 -08:00
Mark McDowall
83eebfe153 Fixed: Stricter parsing of some release filenames 2015-10-29 23:58:56 -07:00
Gaulin, Brendan
fce3f86be7 UI: Update jQuery to 1.11.3 2015-10-29 08:38:21 -04:00
Mark McDowall
2d42c59d70 Fixed: Log download client name when communication fails 2015-10-27 22:19:24 -07:00
Mark McDowall
f0933b9786 Fixed: Test messaging when indexer API returns an error with a message 2015-10-27 22:04:20 -07:00
Mark McDowall
e4e687c2a4 Fixed: Parsing anime series with number in title
Closes #898
2015-10-26 14:56:28 -07:00
Taloth Saldono
44de353b8b Sanitize dognzb apikey in nzb fetch url. 2015-10-25 23:15:21 +01:00
Taloth Saldono
aac4938598 Fixed handling cookies in different system languages.
fixes #896... hopefully
2015-10-25 22:57:37 +01:00
Mark McDowall
d37b24cd0b Better UI messaging when searching for all specials in a series
Fixed: Specials season search UI messaging
Closes #881
2015-10-25 10:10:57 -07:00
Taloth Saldono
c9a36fe4b2 Fixed sorting on Progress in Queue.
Fixes #882
2015-10-22 23:19:24 +02:00
Taloth Saldono
f01a21ce43 Degraded 101 regex to favour S01 regex to match prevent matching 3 digit series title.
Fixes #885
2015-10-22 23:19:22 +02:00
Taloth Saldono
cc72699b8a Fixed: Added verified file transfer mode that doesn't revert to copy. 2015-10-22 23:19:21 +02:00
Mark McDowall
04de0049fe Don't try to process a download client item with an invalid path for the OS 2015-10-21 15:06:54 -07:00
Taloth Saldono
330554edb0 Fixed: External links again open in new windows. 2015-10-20 20:58:56 +02:00
Taloth Saldono
a06a3fa5d6 Fixed: Removal of common suffixes such as [ettv] while parsing.
Fixes #874
2015-10-20 20:12:35 +02:00
Taloth Saldono
e8d6d62fba Warning message when BTN API throw internal server error 2015-10-20 19:31:40 +02:00
Mark McDowall
9cc8ed545f History Spec handles both blackhole and CDH disabled scenarios
Fixed: History will always be used to determine upgrade eligibility when CDH is disabled
2015-10-19 11:42:05 -07:00
Mark McDowall
8bf969983b Tests passing for the wrong reason 2015-10-18 11:01:26 -07:00
Mark McDowall
4ee7d57b7d lrn2spell 2015-10-18 10:54:16 -07:00
Mark McDowall
6ff754eec0 Extend Blackhole grace period to 12 hours 2015-10-18 10:52:26 -07:00
Mark McDowall
862f8024e3 Debug log when release is accepted 2015-10-16 21:54:36 -07:00
Mark McDowall
d170c9ad07 Fixed: Torrent Blackhole client will not track torrents by hash 2015-10-15 23:11:48 -07:00
Mark McDowall
20df619ddd HistorySpecification checks cutoff as well 2015-10-15 00:23:14 -07:00
Taloth Saldono
f7859c8eb5 Fixed: SeasonPass didn't update Series monitored flag if only those were changed. 2015-10-13 22:51:04 +02:00
Taloth Saldono
97cdcb8b19 Bind SignalR to root SeriesCollection so typeahead gets the newest data. 2015-10-13 22:51:02 +02:00
Taloth Saldono
e3c4070924 Fixed: Don't produce scene mapping warnings if TheXEM only maps the second half of a season. 2015-10-13 22:51:01 +02:00
Taloth Saldono
74403815d9 Fixed torznab searching without any id or q.
Fixes #849
2015-10-11 21:39:02 +02:00
Taloth Saldono
897937a778 Fixed indeterministic test. 2015-10-11 12:56:47 +02:00
Taloth Saldono
b6ddc8756b Fixed typo in nn caps and apikey error message. 2015-10-11 02:18:51 +02:00
Taloth Saldono
25aa3b60b0 Don't be so strict about dupe attr values. 2015-10-11 00:26:00 +02:00
Taloth Saldono
fe76d0f98f Refactored the HttpDispatchers. 2015-10-10 22:20:17 +02:00
Taloth Saldono
e13c89521d Merge branch 'nn-tvdbid' into develop 2015-10-10 20:38:03 +02:00
Taloth Saldono
828071c1a5 Merge branch 'pr/n721_ta264' into develop 2015-10-10 20:37:53 +02:00
Mark McDowall
408d86245e Merge pull request #844 from Sonarr/history-spec-improvements
Improvements to History Specification
2015-10-10 11:25:22 -07:00
Mark McDowall
e67de6aae8 New: Blackhole won't grab another release if release in last hour meets the cutoff
Fixed: Invalid season packs preventing future releases from being grabbed when using SAB as download client

Closes #837
Fixes #625
2015-10-09 21:50:04 -07:00
Taloth Saldono
45cdb98c58 Fixed namespace detection for EZRSS now DOCTYPE is gone. 2015-10-10 00:04:58 +02:00
Taloth Saldono
6585aed0a9 Removed doctype from ezrss test. 2015-10-09 23:16:07 +02:00
Taloth Saldono
ef305b8d25 Updated Selenium to 2.48 2015-10-09 22:52:59 +02:00
Taloth Saldono
84c7f4cd8c Added support for tvmaze. 2015-10-09 22:36:10 +02:00
Taloth Saldono
9162e97dd5 Added support for querying newznab with multiple ids in one query. 2015-10-09 22:22:50 +02:00
Taloth Saldono
1ad1d73c91 Added tiered indexer requests to support fallback to wildcard queries. 2015-10-09 22:22:48 +02:00
Taloth Saldono
88ce0ec487 Missing TvdbId on ReleaseResource. 2015-10-09 22:22:47 +02:00
Taloth Saldono
99f452e299 New: Added support for newznab indexers using tvdbid for searching. 2015-10-09 22:22:46 +02:00
Taloth Saldono
7af7c2003e Show Specials in Wanted. 2015-10-09 00:01:32 +02:00
Taloth Saldono
bb482047b1 Fixed removing partials before trying to copy files. 2015-10-09 00:01:31 +02:00
Mark McDowall
a39b36d157 Fixed rTorrent test 2015-10-07 21:37:13 -07:00
Mark McDowall
0841bf1d2a Merge pull request #824 from larsjohnsen/rtorrent-misc
rTorrent fixes

Fixed: Adding label to torrents in rTorrent
2015-10-07 21:14:44 -07:00
Mark McDowall
97f1761092 Log description for invalid API key response
Closes #838
2015-10-07 00:09:03 -07:00
Mark McDowall
0e90bf5227 Fixed: Don't import single files that start with ._ 2015-10-04 13:47:02 -07:00
Mark McDowall
192d001b61 New: Option to remove illegal characters
Closes #809
2015-10-04 13:13:14 -07:00
Mark McDowall
68cd9ab8c8 Don't error out if PMS returns no ID for a specific series
Closes #813
2015-10-04 12:12:07 -07:00
ta264
4be0fe1b76 Add tests for CurlHttpClient and fix the failures 2015-10-04 11:11:58 +01:00
Mark McDowall
9ffa28f17c New: Show time instead of date if event occurs/occurred today
Closes #808
2015-10-03 13:27:37 -07:00
Taloth Saldono
0b219e1169 Fixed nullables. 2015-10-03 21:19:25 +02:00
Taloth Saldono
ccfa13e383 Replaced built-in valuetypes with language keywords. 2015-10-03 21:14:06 +02:00
Taloth Saldono
d6a135857d Clarified error message when parsed episode doesn't exist in the database. 2015-10-03 21:14:04 +02:00
Lars
6ed7a8b471 rTorrent: Url Path displayed by default, misc 2015-10-03 15:30:46 +02:00
Lars
7426efd423 rTorrent: Fixed label bug 2015-10-03 15:26:16 +02:00
Lars
95017884d7 rTorrent: Fixed race condition 2015-10-03 15:26:16 +02:00
Mark McDowall
db5494e7ac Fixed: Tooltips for series and season searches 2015-10-02 21:11:32 -07:00
Mark McDowall
2d7774c018 Use X-Api-Key header in integration tests 2015-10-01 13:53:55 -07:00
Mark McDowall
986dae590b Terminate Sonarr instance created during integration tests by Process ID 2015-10-01 13:52:33 -07:00
Taloth Saldono
99f6c65b76 Removed Trakt to Tvdb migration workaround, so it actually removes the tvrageid when skyhook says so. 2015-09-27 11:38:39 +02:00
Mark McDowall
0c7d8c2d38 Fixed: TV Directory is not required for local rTorrent 2015-09-24 13:55:45 -07:00
Taloth Saldono
c63b65eba1 Only apply kat peers fix for recent releases. 2015-09-24 22:33:01 +02:00
Taloth Saldono
3fc348d045 Fixed: Removed deferrer from external links, instead relying solely on the rel=noreferrer attribute (supported by Chrome and Firefox, but not all browser)
fixes #811
2015-09-24 21:53:08 +02:00
Mark McDowall
5dae0b24d3 Merge pull request #768 from kmcc049/fix-bug-709
Change to using 1024 over 1000
2015-09-23 11:32:27 -07:00
kmcc049
07b70f9d3f Fixed: Consistent display of sizes
Closes #709
2015-09-24 06:30:49 +12:00
Taloth Saldono
4060a24eec Fixed: Missing Episode Search command wasn't stored properly in the db causing it to search for all series, instead of one. 2015-09-22 23:48:19 +02:00
Taloth Saldono
d637ee1a2d Disable kickass seeds/peers info since they only report 0 on the rss. 2015-09-22 22:46:49 +02:00
Taloth Saldono
30bcc662bc Fixed composition. 2015-09-21 23:22:34 +02:00
Taloth Saldono
57afa668e1 Fixed: Removing torcache url query params to avoid redirect.
fixes #799
Removing query param was cleaner coz it avoids spoofing the referrer.
2015-09-21 22:01:42 +02:00
Mark McDowall
d7eae958b7 Fixed: Parse TVRip releases as SDTV 2015-09-20 11:28:15 -07:00
Mark McDowall
c591a86b02 Fixed: Parsing 4-digit season packs
Closes #805
2015-09-20 11:21:04 -07:00
Mark McDowall
49dea2cd7f Fixed: Log error message when moving file to recycling bin fails 2015-09-20 10:41:50 -07:00
Mark McDowall
fa527d7820 New: Custom Script Download contains SourcePath and SourceFolder
Closes #793
2015-09-10 21:12:48 -07:00
Mark McDowall
81778cb0b0 New: Custom Script environment variables use underscores instead of periods 2015-09-10 20:11:16 -07:00
Mark McDowall
e1afd89aae Extremely long titles
Fixed: Extremely long series titles causing display issues on main page

Fixes: #769
2015-09-10 20:08:14 -07:00
Mark McDowall
a2f62a5dcd Hide completed downloads when CDH is disabled
New: Only show completed downloads in queue when Completed Download Handling is enabled
2015-09-03 18:38:10 -07:00
Mark McDowall
19f09fdb86 Path and Arguments were set to the same number for CustomScript 2015-09-03 14:57:38 -07:00
Mark McDowall
68e12f1c5e Merge pull request #774 from Sonarr/preserve-startup-args
Preserve startup arguments during restart
2015-09-02 23:13:21 -07:00
Mark McDowall
5acaf9d60b Fixed: Preserve startup arguments during restart
Closes #325
2015-09-02 23:12:27 -07:00
Mark McDowall
741dc8f50b Fixed: Only run a complete section update in Plex if all partial updates fail
Closes #773
2015-09-01 23:46:26 -07:00
Mark McDowall
28a70a0cf1 Fixed: Import episodes in ascending numerical order
Closes #772
2015-09-01 23:29:49 -07:00
Mark McDowall
bf10d420ec Show implementationName for metadata
Closes #770
2015-09-01 00:20:17 -07:00
Mark McDowall
7286ccdd56 return early for existing files in UnverifiedSceneNumberingSpecification 2015-09-01 00:15:15 -07:00
Gavin Mogan
c5b25bcfee New: Add Webhook support to sonarr
Add Form type url (type=url input field)
Add isValidUrl input type validation

Only allow absolute urls when checking if a url is valid

String => string as per comments that sonarr is standarizing on the lowercase primative

Remove this before function calls

Refactored everything so OnGrab is supported

Don't double submit the webhook

Wrappers around Series, EpisodeFile, Episode so the entire data structure isn't exposed

Add Braces as per style guide

Series.ID and Series.TvdbId should be integers

Reorder webhook payload as per style guide

Upgrade to use ongrab as json instead of string

Add method selection to webhook settings

include episode directly in download event

QualityVersion should be an int and not a string (don't convert it int=>string)

Remove the list of episodes

Add season number to episode data structure

Code Review Fixes:

* Remove episodefile from payload, move everything to episode
* Change episode to a list

convert to var as per code review / style guide

Down with internals

Everything now uses webhookpayload. None of that payload.Message stuff

{"EventType":"Test","Series":{"Id":1,"Title":"Test Title","Path":"C:\\testpath","TvdbId":1234},"Episodes":[{"Id":123,"EpisodeNumber":1,"SeasonNumber":1,"Title":"Test title","AirDate":null,"AirDateUtc":null,"Quality":null,"QualityVersion":0,"ReleaseGroup":null,"SceneName":null}]}

Remove logger and processProvider

Remove unused constructor
2015-08-29 22:45:14 -07:00
Keivan Beigi
187064101c Phantom: screen less files are defined in sonarr.less 2015-08-29 15:19:45 -07:00
Keivan Beigi
66e829f71e upgraded postcss, webpack 2015-08-26 23:33:08 -07:00
Keivan Beigi
a28dd6269a switched web pack watch to poll mode 2015-08-26 23:32:38 -07:00
Mark McDowall
53985a282d Succeeded instead of completed for testing
Closes #758
2015-08-25 23:34:25 -07:00
Mark McDowall
ffffd8ca69 New: Warning message that Torrent Blackhole will move files, not copy or hard link 2015-08-25 23:33:09 -07:00
Gavin Mogan
d3b9ebf86c Convert onGrab from passing a string to passing an object with series and episode information
Use object initalizer instead of creation of OnGrab/grabmessage
2015-08-25 21:13:08 -07:00
ta264
d41dd05d00 Fix build on linux and add build.sh 2015-08-24 09:57:15 -07:00
Mark McDowall
8f9e076325 Fixed: Don't log all daily episodes parsing as unknown episodes 2015-08-21 17:54:50 -07:00
Mark McDowall
ac587168cd Merge pull request #747 from Sonarr/release-pushing
Release pushing
2015-08-17 22:20:26 -07:00
Mark McDowall
bb144a6df6 New: Ability to push releases to Sonarr via API for processing
Closes #419
2015-08-16 23:09:11 -07:00
bitPhex
4f38454825 Inital work for release pushing 2015-08-16 22:53:57 -07:00
Mark McDowall
3a59b38037 Fix theme less file 2015-08-16 14:25:58 -07:00
Mark McDowall
f032cc8cf6 Support for not adding a hash to some index elements 2015-08-16 01:50:46 -07:00
Keivan Beigi
1a872035e7 external less source maps, autoprefixer 2015-08-15 23:52:45 -07:00
Mark McDowall
026e05dcee Fixed: Better parsing of full season x265 releases 2015-08-15 22:42:15 -07:00
Keivan Beigi
99fd1fd4c1 Added lazy load 2015-08-15 18:07:50 -07:00
Taloth Saldono
d6bfa561ad mono and .net handle Uri escapes differently messing up the tests. 2015-08-16 00:17:55 +02:00
Taloth Saldono
8d0dab6578 Fixed tests after Uri cleanup logic. 2015-08-15 21:35:09 +02:00
Taloth Saldono
1a402a9cf4 MediaInfo should use ParseSpeed > 0.2 for .ts files to get accurate readings.
Fixes #742
2015-08-15 16:55:59 +02:00
Taloth Saldono
211863d55d Fixed: Indexers returning relative urls for grabs. 2015-08-15 13:36:40 +02:00
Mark McDowall
38c57ce73a Fixed: Emby metadata added date will use series added date 2015-08-13 22:33:42 -07:00
Taloth Saldono
372ba13fd2 Fixed SkyHookSearch tests. 2015-08-12 22:53:51 +02:00
Taloth Saldono
9bcb6ff19a New: Sonarr can now update series to use another tvdbid in case when tvdb removes a duplicate and Skyhook detects it. 2015-08-12 22:07:47 +02:00
Taloth Saldono
2627072aab Fixed log message for rss sync gap warning. 2015-08-12 18:53:14 +02:00
Taloth Saldono
7991a3f1c3 Fixed series refresh repeated too often if Sonarr is killed before Scheduled task finishes.
Fixes #735
2015-08-11 22:25:37 +02:00
Taloth Saldono
408991e03c Fixed negative NzbGet DownloadLimit
Fixes #700
2015-08-11 21:52:26 +02:00
Taloth Saldono
5ea954695e Ignore duplicates when using history to identify an existing downloaditem. 2015-08-11 21:46:07 +02:00
Taloth Saldono
648a16c1bb Fixed: Don't check for missing TheXEM numbering when importing existing series. 2015-08-11 21:46:06 +02:00
Keivan Beigi
8090c853ba Added source map to css files 2015-08-11 10:44:21 -07:00
Mark McDowall
809c8a7f37 Log number of episodes, not type 2015-08-10 23:06:19 -07:00
Keivan Beigi
608cb296e6 Fixed phantom build 2015-08-09 12:02:18 -07:00
Mark McDowall
7cf400975e Merge pull request #731 from Mirx/develop
Add Hungarian Language
2015-08-07 23:55:43 -07:00
Mirx
4faf7ed959 New: Hungarian language support
Closes #729
2015-08-08 08:41:22 +02:00
Mark McDowall
25493654ff Removed semi-colon 2015-08-04 16:36:34 -07:00
Mark McDowall
48f70815a3 Fixed: rTorrent category is optional
Fixes: #726
2015-08-04 15:13:57 -07:00
Mark McDowall
a720e5f3b5 Fixed paths for phantom 2015-08-03 15:41:33 -07:00
Taloth Saldono
a84f39bb48 Fixed: Should ignore indexer provided tvrageid when scene naming exception exists. 2015-08-03 23:09:33 +02:00
Keivan Beigi
c56cf8860e Cleaned up project root. 2015-08-02 22:22:22 -07:00
Taloth Saldono
2d968a725c Only list the matching ignored terms in the rejection. 2015-08-02 21:27:19 +02:00
Mark McDowall
b1d0d422e9 New: Support 5-digit multi-episode releases 2015-08-01 23:12:15 -07:00
Mark McDowall
86b748b9eb New: Sonarr logo is optional for Pushalot notifications 2015-08-01 00:51:57 -07:00
Mark McDowall
129d7c9338 Fixed: Series failing to load when there were no seasons 2015-08-01 00:02:52 -07:00
Mark McDowall
7f23d25fcf Merge pull request #644 from Sonarr/twitter-notifications
Twitter notifications
2015-07-31 22:38:29 -07:00
Mark McDowall
b82e830e86 Cleanup and refactoring of Twitter notifications
Closes #301
New: Twitter Notifications
2015-07-31 22:25:05 -07:00
Gavin Mogan
2fbf7a4114 Inital work on Twitter notifications 2015-07-31 22:25:01 -07:00
Taloth Saldono
e05365a669 Added missing property to CommandResource. 2015-08-01 02:41:48 +02:00
Taloth Saldono
44e6c46337 Fixed: Refreshing individual series incorrectly delayed the schedule task.
fixes #720
2015-08-01 01:53:39 +02:00
Taloth Saldono
ecb4835a16 minor pageable code error. 2015-08-01 01:53:37 +02:00
Mark McDowall
8c31af608b Merge pull request #698 from srod/boxcar2
Added Boxcar 2
2015-07-31 11:45:06 -07:00
Rodolphe Stoclin
9b1915a187 New: Boxcar 2 notifications 2015-07-31 20:30:37 +02:00
Mark McDowall
db879426db Fixed backbone.collectionview shim 2015-07-28 23:25:48 -07:00
Taloth Saldono
c274c7d589 Icon now completely hidden if spinner overlay is shown.
Fixed season action margin.
2015-07-28 22:16:22 +02:00
Taloth Saldono
8bd675f9f4 Include indexers name in back-off healthcheck warning. 2015-07-28 22:06:43 +02:00
Taloth Saldono
0a12989a70 Actually added deepmodel shim. 2015-07-28 22:06:41 +02:00
Mark McDowall
5b58bd504d Shim for deepmodel 2015-07-27 22:56:44 -07:00
Keivan Beigi
f4d9e3495a Added shim for _ 2015-07-27 22:34:55 -07:00
Mark McDowall
fcfbfae4c1 Merge pull request #690 from Sonarr/backgrid-pageable-reset
Alter backbone.pageable to stay on same page during fetch
2015-07-27 21:36:12 -07:00
Mark McDowall
3f7ae250c7 AsPageableMixin to make backbone.pageable to stay on same page during fetch
Closes #670
2015-07-27 00:50:20 -07:00
Taloth Saldono
645c9c25d1 Updated spinner visualization. 2015-07-26 22:05:12 +02:00
Taloth Saldono
c8b7446f7c Fixed: Readded series monitoring flag to Season Pass view. 2015-07-26 22:05:11 +02:00
Taloth Saldono
293bc55e58 Added link to existing series in add series view. 2015-07-26 22:05:09 +02:00
Taloth Saldono
7eeabd7ca3 Fixed: Updated libcurl version mappings to use libcurl.4 instead of libcurl.3. 2015-07-26 22:05:08 +02:00
Taloth Saldono
c16d02fc1d Fixed: indexer returning an empty page during the rss sync. 2015-07-26 22:05:06 +02:00
Taloth Saldono
fc75783fbe Rewrote the RequestGenerator to support paging and other refactorings. 2015-07-26 22:04:02 +02:00
Mark McDowall
58b01b91d5 New: Titans of TV tracker 2015-07-24 21:45:09 +02:00
Taloth Saldono
c6c68c0c75 Incorrect number of parameters. 2015-07-23 06:28:20 +02:00
Taloth Saldono
9fe8477a40 Now logging nzb&torrent response sizes. 2015-07-22 20:33:47 +02:00
Taloth Saldono
794a7957ef Show thexem outdated mappings message on the calendar as well. 2015-07-22 19:56:20 +02:00
Taloth Saldono
5c1d683e71 Tooltips are now properly hidden if the element is removed from the dom. 2015-07-22 19:56:19 +02:00
Keivan Beigi
0789ace879 Use IsProduction instead of IsDebug to toggle caching on/off 2015-07-21 20:38:23 -07:00
Keivan Beigi
9b16e3b538 _output folder is considered a non-prodction folder 2015-07-21 19:43:06 -07:00
Keivan Beigi
98acd0d886 Added support for custom UI folder 2015-07-21 19:42:38 -07:00
Keivan Beigi
760469fc5f Added support for live reload 2015-07-21 19:38:46 -07:00
Taloth Saldono
5af12b67be Revert "Fixed: Disabled transactional file transfers since we don't want that feature in master yet."
This reverts commit ada5919136.
2015-07-21 21:26:15 +02:00
Taloth Saldono
a1bfecedcd Removed duplicate test. 2015-07-20 21:29:51 +02:00
Taloth Saldono
f2a70677e4 New: Will now temporarily stop using an indexer if the indexer reported an error. 2015-07-20 21:09:16 +02:00
Taloth Saldono
6d046a8df8 Fixed: Extrapolate scene numbering but won't auto import. 2015-07-20 21:05:48 +02:00
Taloth Saldono
23bd9440b3 Removed duplicate file. 2015-07-20 21:04:55 +02:00
Mark McDowall
0f2bba0615 Custom scripts
New: Run custom scripts (Connection)

Closes #439
2015-07-20 10:49:54 -07:00
744 changed files with 19857 additions and 15282 deletions

7
.gitignore vendored
View File

@@ -97,7 +97,7 @@ App_Data/*.ldf
_NCrunch_*
_TeamCity*
# NzbDrone
# Sonarr
config.xml
nzbdrone.log*txt
UpdateLogs/
@@ -105,7 +105,7 @@ UpdateLogs/
*.test-cache
*.userprefs
*/test-results/*
.idea/*
src/UI/.idea/*
*log.txt
node_modules/
_output*
@@ -113,9 +113,6 @@ _rawPackage/
_dotTrace*
_tests/
*.Result.xml
wix/*.msi
wix/*.wixobj
wix/*.wixpdb
setup/Output/
*.~is

1
.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
Sonarr

25
.idea/Sonarr.iml generated Normal file
View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/Logo" />
<excludeFolder url="file://$MODULE_DIR$/_output" />
<excludeFolder url="file://$MODULE_DIR$/_output_mono" />
<excludeFolder url="file://$MODULE_DIR$/_output_osx" />
<excludeFolder url="file://$MODULE_DIR$/_output_osx_app" />
<excludeFolder url="file://$MODULE_DIR$/_start" />
<excludeFolder url="file://$MODULE_DIR$/_tests" />
<excludeFolder url="file://$MODULE_DIR$/debian" />
<excludeFolder url="file://$MODULE_DIR$/node_modules" />
<excludeFolder url="file://$MODULE_DIR$/osx" />
<excludeFolder url="file://$MODULE_DIR$/schemas" />
<excludeFolder url="file://$MODULE_DIR$/setup" />
<excludeFolder url="file://$MODULE_DIR$/src" />
<excludeFolder url="file://$MODULE_DIR$/tools" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Sonarr node_modules" level="project" />
</component>
</module>

59
.idea/codeStyleSettings.xml generated Normal file
View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="LINE_SEPARATOR" value="&#13;&#10;" />
<option name="RIGHT_MARGIN" value="190" />
<option name="HTML_ATTRIBUTE_WRAP" value="0" />
<option name="HTML_KEEP_LINE_BREAKS" value="false" />
<option name="HTML_KEEP_BLANK_LINES" value="1" />
<option name="HTML_ALIGN_ATTRIBUTES" value="false" />
<option name="HTML_INLINE_ELEMENTS" value="" />
<option name="HTML_DONT_ADD_BREAKS_IF_INLINE_CONTENT" value="" />
<CssCodeStyleSettings>
<option name="HEX_COLOR_LOWER_CASE" value="true" />
<option name="HEX_COLOR_LONG_FORMAT" value="true" />
<option name="VALUE_ALIGNMENT" value="1" />
</CssCodeStyleSettings>
<JSCodeStyleSettings>
<option name="SPACE_BEFORE_PROPERTY_COLON" value="true" />
<option name="ALIGN_OBJECT_PROPERTIES" value="2" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="OBJECT_LITERAL_WRAP" value="2" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
</JSCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="CSS">
<indentOptions>
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="true" />
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="SPACE_BEFORE_METHOD_PARENTHESES" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="ARRAY_INITIALIZER_WRAP" value="2" />
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
</project>

6
.idea/jsLibraryMappings.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="file://$PROJECT_DIR$" libraries="{Sonarr node_modules}" />
</component>
</project>

14
.idea/libraries/Sonarr_node_modules.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Sonarr node_modules" type="javaScript">
<properties>
<option name="frameworkName" value="node_modules" />
<sourceFilesUrls>
<item url="file://$PROJECT_DIR$/node_modules" />
</sourceFilesUrls>
</properties>
<CLASSES>
<root url="file://$PROJECT_DIR$/node_modules" />
</CLASSES>
<SOURCES />
</library>
</component>

14
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Sonarr.iml" filepath="$PROJECT_DIR$/.idea/Sonarr.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

4
CLA.md
View File

@@ -1,6 +1,6 @@
# NzbDrone Individual Contributor License Agreement #
# Sonarr Individual Contributor License Agreement #
Thank you for your interest in contributing to NzbDrone ("We" or "Us").
Thank you for your interest in contributing to Sonarr ("We" or "Us").
This contributor agreement ("Agreement") documents the rights granted by contributors to Us. To make this document effective, please complete the form below. This is a legally binding document, so please read it carefully before agreeing to it. The Agreement may cover more than one software project managed by Us.
## 1. Definitions ##

View File

@@ -1,6 +1,6 @@
# How to Contribute #
We're always looking for people to help make NzbDrone even better, there are a number of ways to contribute. To get started, <a href="http://www.clahub.com/agreements/NzbDrone/NzbDrone">sign the Contributor License Agreement</a>.
We're always looking for people to help make Sonarr even better, there are a number of ways to contribute. To get started, <a href="http://www.clahub.com/agreements/NzbDrone/NzbDrone">sign the Contributor License Agreement</a>.
## Documentation ##
Setup guides, FAQ, the more information we have on the wiki the better.
@@ -15,15 +15,15 @@ Setup guides, FAQ, the more information we have on the wiki the better.
### Getting started ###
1. Fork NzbDrone
2. Clone (develop branch)
1. Fork Sonarr
2. Clone (develop branch) *you may need pull in submodules separately if you client doesn't clone them automatically (CurlSharp)*
3. Run `npm install`
4. Run `gulp watch` - Used to compile the UI components and copy them (leave this window open)
5. Compile in Visual Studio
### Contributing Code ###
- If you're adding a new, already requested feature, please comment on [Github Issues](https://github.com/Sonarr/Sonarr/issues "Github Issues") so work is not duplicated (If you want to add something not already on there, please talk to us first)
- Rebase from NzbDrone's develop branch, don't merge
- Rebase from Sonarr's develop branch, don't merge
- Make meaningful commits, or squash them
- Feel free to make a pull request before work is complete, this will let us see where its at and make comments/suggest improvements
- Reach out to us on the forums or on IRC if you have any questions

View File

@@ -1,720 +0,0 @@
<Config xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:b="http://schemas.datacontract.org/2004/07/System.Drawing" xmlns:d="http://schemas.datacontract.org/2004/07/Prosa.Log4View.Db" xmlns:f="http://schemas.datacontract.org/2004/07/Prosa.Log4View.Receiver.File" xmlns:l="http://schemas.datacontract.org/2004/07/Prosa.Log4View.Level" xmlns:m="http://schemas.datacontract.org/2004/07/Prosa.Log4View.Receiver.Msg" xmlns:n="http://schemas.datacontract.org/2004/07/Prosa.Log4View.Receiver.Net" xmlns:t="http://schemas.datacontract.org/2004/07/Prosa.Log4View.LoggerTree" xmlns:u="http://schemas.datacontract.org/2004/07/Prosa.Log4View.Utils" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/Prosa.Log4View.Configuration">
<Id>
<u:Value>1</u:Value>
</Id>
<Data z:Id="2">
<Id>
<u:Value>2</u:Value>
</Id>
<Version>17</Version>
<_receivers z:Id="3" z:Size="1">
<ReceiverConfig z:Id="4" i:type="n:NetReceiverConfig">
<Id>
<u:Value>16</u:Value>
</Id>
<BackColor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4293654015</b:value>
</BackColor>
<BufferSize>500000</BufferSize>
<Encoding z:Id="5">Windows-1252</Encoding>
<LevelFilter z:Id="6" i:type="LogLevelSurrogated">
<LevelName z:Id="7">ALL</LevelName>
</LevelFilter>
<LoggingFrameworkId z:Id="8">Log4net</LoggingFrameworkId>
<Name z:Id="9">NzbDrone</Name>
<ParserType>XML</ParserType>
<ReadAdjacentMessages>0</ReadAdjacentMessages>
<ReadFrom>0001-01-01T00:00:00</ReadFrom>
<ReadUntil>0001-01-01T00:00:00</ReadUntil>
<SourceId>0</SourceId>
<TimeOffset>0</TimeOffset>
<TimeZone z:Id="10">Pacific Standard Time</TimeZone>
<UseFilter>false</UseFilter>
<Window>18</Window>
<n:HostName z:Id="11">localhost</n:HostName>
<n:Port>20480</n:Port>
<n:Protocol>Udp</n:Protocol>
</ReceiverConfig>
</_receivers>
<_sources z:Id="12" z:Size="0" />
</Data>
<Presentation z:Id="13">
<Id>
<u:Value>3</u:Value>
</Id>
<DefaultLogLevel z:Ref="6" i:nil="true" />
<ShowCodeDetails>false</ShowCodeDetails>
<ShowMessageDetails>true</ShowMessageDetails>
<ShowMultiField>true</ShowMultiField>
<ShowOutputOnDebug>true</ShowOutputOnDebug>
<ShowProcessDetails>false</ShowProcessDetails>
<ToolTipLogLevel z:Id="14" i:type="LogLevelSurrogated">
<LevelName z:Id="15">OFF</LevelName>
</ToolTipLogLevel>
<Version>17</Version>
<_charts z:Id="16" z:Size="0" />
<_columns z:Id="17" z:Size="29">
<ColumnConfig z:Id="18">
<Id>
<u:Value>78</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="19">Id</FieldName>
<Name z:Ref="19" i:nil="true" />
<Position>-1</Position>
<Width>45</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="20">
<Id>
<u:Value>79</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="21">OriginalTime</FieldName>
<Name z:Ref="21" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="22">
<Id>
<u:Value>80</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="23">Time</FieldName>
<Name z:Ref="23" i:nil="true" />
<Position>1</Position>
<Width>80</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="24">
<Id>
<u:Value>81</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="25">LocalTime</FieldName>
<Name z:Ref="25" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="26">
<Id>
<u:Value>82</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="27">UtcTime</FieldName>
<Name z:Ref="27" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="28">
<Id>
<u:Value>83</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="29">Date</FieldName>
<Name z:Ref="29" i:nil="true" />
<Position>-1</Position>
<Width>70</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="30">
<Id>
<u:Value>84</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="31">Key</FieldName>
<Name z:Ref="31" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="32">
<Id>
<u:Value>85</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="33">Level</FieldName>
<Name z:Ref="33" i:nil="true" />
<Position>-1</Position>
<Width>85</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="34">
<Id>
<u:Value>86</u:Value>
</Id>
<ClipMode>ClipMiddle</ClipMode>
<FieldName z:Id="35">Logger</FieldName>
<Name z:Ref="35" i:nil="true" />
<Position>2</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="36">
<Id>
<u:Value>87</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="37">Source</FieldName>
<Name z:Ref="37" i:nil="true" />
<Position>-1</Position>
<Width>90</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="38">
<Id>
<u:Value>88</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="39">Message</FieldName>
<Name z:Ref="39" i:nil="true" />
<Position>3</Position>
<Width>874</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="40">
<Id>
<u:Value>89</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="41">Thread</FieldName>
<Name z:Ref="41" i:nil="true" />
<Position>-1</Position>
<Width>95</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="42">
<Id>
<u:Value>90</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="43">Host</FieldName>
<Name z:Ref="43" i:nil="true" />
<Position>-1</Position>
<Width>90</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="44">
<Id>
<u:Value>91</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="45">Exception</FieldName>
<Name z:Ref="45" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="46">
<Id>
<u:Value>92</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="47">Domain</FieldName>
<Name z:Ref="47" i:nil="true" />
<Position>-1</Position>
<Width>90</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="48">
<Id>
<u:Value>93</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="49">Identity</FieldName>
<Name z:Ref="49" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="50">
<Id>
<u:Value>94</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="51">User</FieldName>
<Name z:Ref="51" i:nil="true" />
<Position>-1</Position>
<Width>90</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="52">
<Id>
<u:Value>95</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="53">Class</FieldName>
<Name z:Ref="53" i:nil="true" />
<Position>-1</Position>
<Width>90</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="54">
<Id>
<u:Value>96</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="55">Method</FieldName>
<Name z:Ref="55" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="56">
<Id>
<u:Value>97</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="57">File</FieldName>
<Name z:Ref="57" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="58">
<Id>
<u:Value>98</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="59">Line</FieldName>
<Name z:Ref="59" i:nil="true" />
<Position>-1</Position>
<Width>45</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="60">
<Id>
<u:Value>99</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="61">NDC</FieldName>
<Name z:Ref="61" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="62">
<Id>
<u:Value>100</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="63">MDC</FieldName>
<Name z:Ref="63" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="64">
<Id>
<u:Value>101</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="65">Comment</FieldName>
<Name z:Ref="65" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="66">
<Id>
<u:Value>102</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="67">StackTrace</FieldName>
<Name z:Ref="67" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="68">
<Id>
<u:Value>103</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="69">ProcessId</FieldName>
<Name z:Ref="69" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="70">
<Id>
<u:Value>104</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="71">ThreadId</FieldName>
<Name z:Ref="71" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="72">
<Id>
<u:Value>105</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="73">CallStack</FieldName>
<Name z:Ref="73" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
<ColumnConfig z:Id="74">
<Id>
<u:Value>106</u:Value>
</Id>
<ClipMode>ClipRight</ClipMode>
<FieldName z:Id="75">assembly</FieldName>
<Name z:Ref="75" i:nil="true" />
<Position>-1</Position>
<Width>120</Width>
<WindowId>18</WindowId>
</ColumnConfig>
</_columns>
<_filters z:Id="76" z:Size="0" />
<_formats z:Id="77" z:Size="1">
<FormatConfig z:Id="78">
<Id>
<u:Value>0</u:Value>
</Id>
<ConditionFieldName z:Ref="39" i:nil="true" />
<ConditionRelation z:Id="79"></ConditionRelation>
<ConditionText z:Ref="79" i:nil="true" />
<Formats z:Id="80" z:Size="12">
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="81" i:type="LogLevelSurrogated">
<LevelName z:Id="82">VERBOSE</LevelName>
</a:Key>
<a:Value z:Id="83">
<Id>
<u:Value>4</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="84">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4290032820</b:value>
</Forecolor>
<Loglevel z:Ref="81" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="85" i:type="LogLevelSurrogated">
<LevelName z:Id="86">TRACE</LevelName>
</a:Key>
<a:Value z:Id="87">
<Id>
<u:Value>5</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="88">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4288716960</b:value>
</Forecolor>
<Loglevel z:Ref="85" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="89" i:type="LogLevelSurrogated">
<LevelName z:Id="90">DEBUG</LevelName>
</a:Key>
<a:Value z:Id="91">
<Id>
<u:Value>6</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="92">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4286743170</b:value>
</Forecolor>
<Loglevel z:Ref="89" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="93" i:type="LogLevelSurrogated">
<LevelName z:Id="94">INFO</LevelName>
</a:Key>
<a:Value z:Id="95">
<Id>
<u:Value>7</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="96">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4278190080</b:value>
</Forecolor>
<Loglevel z:Ref="93" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="97" i:type="LogLevelSurrogated">
<LevelName z:Id="98">NOTICE</LevelName>
</a:Key>
<a:Value z:Id="99">
<Id>
<u:Value>8</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="100">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4281957177</b:value>
</Forecolor>
<Loglevel z:Ref="97" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="101" i:type="LogLevelSurrogated">
<LevelName z:Id="102">WARN</LevelName>
</a:Key>
<a:Value z:Id="103">
<Id>
<u:Value>9</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="104">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4294934528</b:value>
</Forecolor>
<Loglevel z:Ref="101" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="105" i:type="LogLevelSurrogated">
<LevelName z:Id="106">ERROR</LevelName>
</a:Key>
<a:Value z:Id="107">
<Id>
<u:Value>10</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="108">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4294901760</b:value>
</Forecolor>
<Loglevel z:Ref="105" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="109" i:type="LogLevelSurrogated">
<LevelName z:Id="110">SEVERE</LevelName>
</a:Key>
<a:Value z:Id="111">
<Id>
<u:Value>11</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="112">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4293067295</b:value>
</Forecolor>
<Loglevel z:Ref="109" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="113" i:type="LogLevelSurrogated">
<LevelName z:Id="114">CRITICAL</LevelName>
</a:Key>
<a:Value z:Id="115">
<Id>
<u:Value>12</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="116">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4289400377</b:value>
</Forecolor>
<Loglevel z:Ref="113" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="117" i:type="LogLevelSurrogated">
<LevelName z:Id="118">ALERT</LevelName>
</a:Key>
<a:Value z:Id="119">
<Id>
<u:Value>13</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="120">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4294902015</b:value>
</Forecolor>
<Loglevel z:Ref="117" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="121" i:type="LogLevelSurrogated">
<LevelName z:Id="122">FATAL</LevelName>
</a:Key>
<a:Value z:Id="123">
<Id>
<u:Value>14</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="124">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4287309977</b:value>
</Forecolor>
<Loglevel z:Ref="121" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
<a:Key z:Id="125" i:type="LogLevelSurrogated">
<LevelName z:Id="126">EMERGENCY</LevelName>
</a:Key>
<a:Value z:Id="127">
<Id>
<u:Value>15</u:Value>
</Id>
<Backcolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>0</b:state>
<b:value>0</b:value>
</Backcolor>
<FontName z:Id="128">Tahoma</FontName>
<Forecolor>
<b:knownColor>0</b:knownColor>
<b:name i:nil="true" />
<b:state>2</b:state>
<b:value>4285932413</b:value>
</Forecolor>
<Loglevel z:Ref="125" i:nil="true" />
<Size>8.25</Size>
<Style>Regular</Style>
</a:Value>
</a:KeyValueOfLogLevelLoggerFormatConfigxIppDzWS>
</Formats>
<IgnoreCase>false</IgnoreCase>
<Name z:Id="129">Default Format Settings</Name>
</FormatConfig>
</_formats>
<_logLevels z:Id="130" z:Size="0" />
<_loggers z:Id="131" z:Size="1">
<LoggerConfig z:Id="132">
<Id>
<u:Value>77</u:Value>
</Id>
<LogLevel z:Ref="6" i:nil="true" />
<LoggerPath z:Ref="79" i:nil="true" />
<ReceiverId>16</ReceiverId>
</LoggerConfig>
</_loggers>
</Presentation>
<Version>17</Version>
</Config>

View File

@@ -1,2 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/Environment/ExternalSources/Decompiler/DecompileMethodBodies/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -33,6 +33,7 @@ Function Build()
Write-Host "Removing Mono.Posix.dll"
Remove-Item "$outputFolder\Mono.Posix.dll"
Get-ChildItem $outputFolder -File -Filter "*.dylib" -Recurse | foreach ($_) {Remove-Item $_.Fullname}
Write-Host "##teamcity[progressFinish 'Build']"
}
@@ -218,6 +219,9 @@ Function PackageTests()
Write-Host "Adding NzbDrone.Core.dll.config (for dllmap)"
Copy-Item "$sourceFolder\NzbDrone.Core\NzbDrone.Core.dll.config" -Destination $testPackageFolder -Force
Write-Host "Copying CurlSharp libraries"
Copy-Item $sourceFolder\ExternalModules\CurlSharp\libs\i386\* $testPackageFolder
Write-Host "##teamcity[progressFinish 'Creating Test Package']"
}
@@ -230,6 +234,9 @@ Function RunGulp()
Invoke-Expression 'gulp build' -ErrorAction Continue -Verbose
CheckExitCode
Invoke-Expression 'gulp build --phantom' -ErrorAction Continue -Verbose
CheckExitCode
Write-Host "##teamcity[progressFinish 'Running Gulp']"
}

260
build.sh Executable file
View File

@@ -0,0 +1,260 @@
#! /bin/bash
msBuild='/c/Windows/Microsoft.NET/Framework64/v4.0.30319/'
outputFolder='./_output'
outputFolderMono='./_output_mono'
outputFolderOsx='./_output_osx'
outputFolderOsxApp='./_output_osx_app'
testPackageFolder='./_tests/'
testSearchPattern='*.Test/bin/x86/Release/*'
sourceFolder='./src'
updateFolder=$outputFolder/NzbDrone.Update
updateFolderMono=$outputFolderMono/NzbDrone.Update
CheckExitCode()
{
"$@"
local status=$?
if [ $status -ne 0 ]; then
echo "error with $1" >&2
exit 1
fi
return $status
}
CleanFolder()
{
local path=$1
local keepConfigFiles=$2
echo "Removing XMLDoc files"
local xmlfiles=( $(find $path -name "*.xml") )
for filename in "${xmlfiles[@]}"
do
if [ -e ${filename%.xml}.dll ] || [ -e ${filename%.xml}.exe ] ; then
rm $filename
fi
done
find $path -name "*.transform" -exec rm "{}" \;
if [ $keepConfigFiles != true ] ; then
find $path -name "*.dll.config" -exec rm "{}" \;
fi
echo "Removing FluentValidation.Resources files"
find $path -name "FluentValidation.resources.dll" -exec rm "{}" \;
find $path -name "App.config" -exec rm "{}" \;
echo "Removing .less files"
find $path -name "*.less" -exec rm "{}" \;
echo "Removing vshost files"
find $path -name "*.vshost.exe" -exec rm "{}" \;
if [ -d $path/NuGet ] ; then
echo "Removing NuGet"
rm -rf $path/NuGet
fi
echo "Removing Empty folders"
find $path -depth -empty -type d -exec rm -r "{}" \;
}
AddJsonNet()
{
rm $outputFolder/Newtonsoft.Json.*
cp $sourceFolder/packages/Newtonsoft.Json.*/lib/net35/*.dll $outputFolder
cp $sourceFolder/packages/Newtonsoft.Json.*/lib/net35/*.dll $outputFolder/NzbDrone.Update
}
BuildWithMSBuild()
{
export PATH=$msBuild:$PATH
CheckExitCode MSBuild.exe $sourceFolder/NzbDrone.sln //t:Clean //m
CheckExitCode MSBuild.exe $sourceFolder/NzbDrone.sln //p:Configuration=Release //p:Platform=x86 //t:Build //m
}
BuildWithXbuild()
{
export MONO_IOMAP=case
CheckExitCode xbuild /t:Clean $sourceFolder/NzbDrone.sln
CheckExitCode xbuild /p:Configuration=Release /p:Platform=x86 /t:Build $sourceFolder/NzbDrone.sln
}
Build()
{
echo "##teamcity[progressStart 'Build']"
rm -rf $outputFolder
if [ $runtime = "dotnet" ] ; then
BuildWithMSBuild
else
BuildWithXbuild
fi
CleanFolder $outputFolder false
AddJsonNet
echo "Removing Mono.Posix.dll"
rm $outputFolder/Mono.Posix.dll
echo "##teamcity[progressFinish 'Build']"
}
RunGulp()
{
echo "##teamcity[progressStart 'Running Gulp']"
CheckExitCode npm install
CheckExitCode gulp build
echo "##teamcity[progressFinish 'Running Gulp']"
}
CreateMdbs()
{
local path=$1
if [ $runtime = "dotnet" ] ; then
find $path \( -name "*.exe" -o -name "*.dll" \) -not -name "MediaInfo.dll" -not -name "sqlite3.dll" -exec tools/pdb2mdb/pdb2mdb.exe "{}" \;
fi
}
PackageMono()
{
echo "##teamcity[progressStart 'Creating Mono Package']"
rm -rf $outputFolderMono
cp -r $outputFolder $outputFolderMono
echo "Creating MDBs"
CreateMdbs $outputFolderMono
echo "Removing PDBs"
find $outputFolderMono -name "*.pdb" -exec rm "{}" \;
echo "Removing Service helpers"
rm -f $outputFolderMono/ServiceUninstall.*
rm -f $outputFolderMono/ServiceInstall.*
echo "Removing native windows binaries Sqlite, MediaInfo"
rm -f $outputFolderMono/sqlite3.*
rm -f $outputFolderMono/MediaInfo.*
echo "Adding NzbDrone.Core.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Core/NzbDrone.Core.dll.config $outputFolderMono
echo "Adding CurlSharp.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Common/CurlSharp.dll.config $outputFolderMono
echo "Renaming NzbDrone.Console.exe to NzbDrone.exe"
rm $outputFolderMono/NzbDrone.exe*
for file in $outputFolderMono/NzbDrone.Console.exe*; do
mv "$file" "${file//.Console/}"
done
echo "Removing NzbDrone.Windows"
rm $outputFolderMono/NzbDrone.Windows.*
echo "Adding NzbDrone.Mono to UpdatePackage"
cp $outputFolderMono/NzbDrone.Mono.* $updateFolderMono
}
PackageOsx()
{
echo "##teamcity[progressStart 'Creating OS X Package']"
rm -rf $outputFolderOsx
cp -r $outputFolderMono $outputFolderOsx
echo "Adding sqlite dylibs"
cp $sourceFolder/Libraries/Sqlite/*.dylib $outputFolderOsx
echo "Adding MediaInfo dylib"
cp $sourceFolder/Libraries/MediaInfo/*.dylib $outputFolderOsx
echo "Adding Startup script"
cp ./osx/Sonarr $outputFolderOsx
echo "##teamcity[progressFinish 'Creating OS X Package']"
}
PackageOsxApp()
{
echo "##teamcity[progressStart 'Creating OS X App Package']"
rm -rf $outputFolderOsxApp
mkdir $outputFolderOsxApp
cp -r ./osx/Sonarr.app $outputFolderOsxApp
cp -r $outputFolderOsx $outputFolderOsxApp/Sonarr.app/Contents/MacOS
echo "##teamcity[progressFinish 'Creating OS X App Package']"
}
PackageTests()
{
echo "Packaging Tests"
echo "##teamcity[progressStart 'Creating Test Package']"
rm -rf $testPackageFolder
mkdir $testPackageFolder
find . -maxdepth 6 -path $testSearchPattern -exec cp -r "{}" $testPackageFolder \;
if [ $runtime = "dotnet" ] ; then
$sourceFolder/.nuget/NuGet.exe install NUnit.Runners -Version 2.6.1 -Output $testPackageFolder
cp $outputFolder/*.pdb $testPackageFolder
else
mono $sourceFolder/.nuget/NuGet.exe install NUnit.Runners -Version 2.6.1 -Output $testPackageFolder
fi
cp $outputFolder/*.dll $testPackageFolder
cp ./*.sh $testPackageFolder
echo "Creating MDBs for tests"
CreateMdbs $testPackageFolder
rm -f $testPackageFolder/*.log.config
CleanFolder $testPackageFolder true
echo "Adding NzbDrone.Core.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Core/NzbDrone.Core.dll.config $testPackageFolder
echo "Adding CurlSharp.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Common/CurlSharp.dll.config $testPackageFolder
echo "Copying CurlSharp libraries"
cp $sourceFolder/ExternalModules/CurlSharp/libs/i386/* $testPackageFolder
echo "##teamcity[progressFinish 'Creating Test Package']"
}
CleanupWindowsPackage()
{
echo "Removing NzbDrone.Mono"
rm -f $outputFolder/NzbDrone.Mono.*
echo "Adding NzbDrone.Windows to UpdatePackage"
cp $outputFolder/NzbDrone.Windows.* $updateFolder
}
# Use mono or .net depending on OS
case "$(uname -s)" in
CYGWIN*|MINGW32*|MINGW64*|MSYS*)
# on windows, use dotnet
runtime="dotnet"
;;
*)
# otherwise use mono
runtime="mono"
;;
esac
Build
RunGulp
PackageMono
PackageOsx
PackageOsxApp
PackageTests
CleanupWindowsPackage

View File

@@ -1,50 +0,0 @@
<Query Kind="Program" />
void Main()
{
var files = Directory.GetFiles("c:\\git\\sonarr\\src\\UI","*.js", SearchOption.AllDirectories);
var moduleRegex = new Regex(@"module.exports\s*=\s*\(function\s*\(\)\s*{\n\s*return\s*(\w|\W)*\)\.call\(this\);$");
var functionHead = new Regex(@"\s*\(function\s*\(\)\s*{\n\s*return\s*");
var functionTail = new Regex(@"\}\).call\(this\);$");
var multiVar = new Regex(@"^(?<d>var\s*\w*\s*=\s*require\(.*\)),");
var seperateDeclearatuin = new Regex(@"^((\w|\$|_)*\s=\srequire\(.*\))(,|;)", RegexOptions.Multiline);
foreach (var filePath in files)
{
var text = File.ReadAllText(filePath);
var newContent = text.Replace("// Generated by uRequire v0.7.0-beta.14 template: 'nodejs'","");
newContent = newContent.Replace("var __isAMD = !!(typeof define === 'function' && define.amd),","");
newContent = newContent.Replace("__isNode = (typeof exports === 'object'),","");
newContent = newContent.Replace("__isWeb = !__isNode;","");
newContent = newContent.Replace("\"use strict\";","'use strict';");
newContent = newContent.Trim();
if(moduleRegex.IsMatch(newContent))
{
filePath.Dump();
newContent = functionHead.Replace(newContent," ");
newContent = functionTail.Replace(newContent,"");
}
if(multiVar.IsMatch(newContent))
{
newContent = multiVar.Replace(newContent,"$1;"); //first one
}
newContent = seperateDeclearatuin.Replace(newContent,"var $1;"); //ones after
newContent.Replace("var $ = require('jquery'), var","var $ = require('jquery');");
File.WriteAllText(filePath,newContent.Trim());
}
}
// Define other methods and classes here

View File

@@ -6,7 +6,13 @@ require('./less');
require('./handlebars');
require('./copy');
gulp.task('build', function () {
return runSequence('clean',
['webpack', 'less', 'handlebars', 'copyHtml', 'copyContent', 'copyJs']);
gulp.task('build', function() {
return runSequence('clean', [
'webpack',
'less',
'handlebars',
'copyHtml',
'copyContent',
'copyJs'
]);
});

View File

@@ -3,6 +3,6 @@ var del = require('del');
var paths = require('./paths');
gulp.task('clean', function (cb) {
del([paths.dest.root], cb);
gulp.task('clean', function(cb) {
del([paths.dest.root], cb);
});

View File

@@ -1,27 +1,31 @@
var gulp = require('gulp');
var print = require('gulp-print');
var cache = require('gulp-cached');
var livereload = require('gulp-livereload');
var paths = require('./paths.js');
gulp.task('copyJs', function () {
return gulp.src(
[
paths.src.root + "polyfills.js",
paths.src.root + "JsLibraries/handlebars.runtime.js",
])
.pipe(cache('copyJs'))
.pipe(print())
.pipe(gulp.dest(paths.dest.root));
return gulp.src(
[
paths.src.root + 'polyfills.js',
paths.src.root + 'JsLibraries/handlebars.runtime.js'
])
.pipe(cache('copyJs'))
.pipe(print())
.pipe(gulp.dest(paths.dest.root))
.pipe(livereload());
});
gulp.task('copyHtml', function () {
return gulp.src(paths.src.html)
.pipe(cache('copyHtml'))
.pipe(gulp.dest(paths.dest.root));
return gulp.src(paths.src.html)
.pipe(cache('copyHtml'))
.pipe(gulp.dest(paths.dest.root))
.pipe(livereload());
});
gulp.task('copyContent', function () {
return gulp.src([paths.src.content + '**/*.*', '!**/*.less'])
.pipe(gulp.dest(paths.dest.content));
return gulp.src([paths.src.content + '**/*.*', '!**/*.less'])
.pipe(gulp.dest(paths.dest.content))
.pipe(livereload());
});

View File

@@ -1,7 +1,7 @@
module.exports = {
onError:function (error) {
onError : function(error) {
//If you want details of the error in the console
console.log(error.toString());
this.emit('end');
}
}
};

View File

@@ -3,21 +3,25 @@ var handlebars = require('gulp-handlebars');
var declare = require('gulp-declare');
var concat = require('gulp-concat');
var wrap = require("gulp-wrap");
var livereload = require('gulp-livereload');
var path = require('path');
var streamqueue = require('streamqueue');
var stripbom = require('gulp-stripbom');
var paths = require('./paths.js');
gulp.task('handlebars', function () {
gulp.task('handlebars', function() {
var coreStream = gulp.src([paths.src.templates, '!*/**/*Partial.*'])
.pipe(stripbom({ showLog: false }))
var coreStream = gulp.src([
paths.src.templates,
'!*/**/*Partial.*'
])
.pipe(stripbom({ showLog : false }))
.pipe(handlebars())
.pipe(declare({
namespace: 'T',
noRedeclare: true,
processName: function (filePath) {
namespace : 'T',
noRedeclare : true,
processName : function(filePath) {
filePath = path.relative(paths.src.root, filePath);
@@ -29,12 +33,12 @@ gulp.task('handlebars', function () {
}));
var partialStream = gulp.src([paths.src.partials])
.pipe(stripbom({ showLog: false }))
.pipe(stripbom({ showLog : false }))
.pipe(handlebars())
.pipe(wrap('Handlebars.template(<%= contents %>)'))
.pipe(wrap('Handlebars.registerPartial(<%= processPartialName(file.relative) %>, <%= contents %>)', {}, {
imports: {
processPartialName: function (fileName) {
imports : {
processPartialName : function(fileName) {
return JSON.stringify(
path.basename(fileName, '.js')
);
@@ -42,11 +46,10 @@ gulp.task('handlebars', function () {
}
}));
return streamqueue({ objectMode: true },
return streamqueue({ objectMode : true },
partialStream,
coreStream
).pipe(concat('templates.js'))
.pipe(gulp.dest(paths.dest.root));
.pipe(gulp.dest(paths.dest.root))
.pipe(livereload());
});

View File

@@ -2,14 +2,13 @@ var gulp = require('gulp');
var print = require('gulp-print');
var paths = require('./paths.js');
gulp.task('imageMin', function () {
gulp.task('imageMin', function() {
var imagemin = require('gulp-imagemin');
return gulp.src(paths.src.images)
.pipe(imagemin({
progressive: false,
optimizationLevel :4,
svgoPlugins: [{removeViewBox: false}]
progressive : false,
optimizationLevel : 4,
svgoPlugins : [{ removeViewBox : false }]
}))
.pipe(print())
.pipe(gulp.dest(paths.src.content + 'Images/'));

View File

@@ -4,9 +4,11 @@ var stylish = require('jshint-stylish');
var cache = require('gulp-cached');
var paths = require('./paths.js');
gulp.task('jshint', function () {
return gulp.src([paths.src.scripts, paths.src.exclude.libs])
gulp.task('jshint', function() {
return gulp.src([
paths.src.scripts,
paths.src.exclude.libs
])
.pipe(cache('jshint'))
.pipe(jshint())
.pipe(jshint.reporter(stylish));

View File

@@ -1,34 +1,55 @@
var gulp = require('gulp');
var less = require('gulp-less');
var print = require('gulp-print');
var less = require('gulp-less');
var postcss = require('gulp-postcss');
var sourcemaps = require('gulp-sourcemaps');
var autoprefixer = require('autoprefixer-core');
var livereload = require('gulp-livereload');
var print = require('gulp-print');
var phantom = require('./phantom');
var paths = require('./paths');
var errorHandler = require('./errorHandler');
gulp.task('less', function () {
return gulp.src([
paths.src.content + 'bootstrap.less',
paths.src.content + 'theme.less',
paths.src.content + 'overrides.less',
paths.src.root + 'Series/series.less',
paths.src.root + 'Activity/activity.less',
paths.src.root + 'AddSeries/addSeries.less',
paths.src.root + 'Calendar/calendar.less',
paths.src.root + 'Cells/cells.less',
paths.src.root + 'ManualImport/manualimport.less',
paths.src.root + 'Settings/settings.less',
paths.src.root + 'System/Logs/logs.less',
paths.src.root + 'System/Update/update.less',
paths.src.root + 'System/Info/info.less',
])
gulp.task('less', function() {
var src = [
paths.src.content + 'bootstrap.less',
paths.src.content + 'theme.less',
paths.src.content + 'overrides.less',
paths.src.root + 'Series/series.less',
paths.src.root + 'Activity/activity.less',
paths.src.root + 'AddSeries/addSeries.less',
paths.src.root + 'Calendar/calendar.less',
paths.src.root + 'Cells/cells.less',
paths.src.root + 'ManualImport/manualimport.less',
paths.src.root + 'Settings/settings.less',
paths.src.root + 'System/Logs/logs.less',
paths.src.root + 'System/Update/update.less',
paths.src.root + 'System/Info/info.less'
];
if (phantom) {
src = [
paths.src.content + 'Bootstrap/bootstrap.less',
paths.src.content + 'Vendor/vendor.less',
paths.src.content + 'sonarr.less'
];
}
return gulp.src(src)
.pipe(print())
.pipe(sourcemaps.init())
.pipe(less({
dumpLineNumbers: 'false',
compress: true,
yuicompress: true,
ieCompat: true,
strictImports: true
dumpLineNumbers : 'false',
compress : true,
yuicompress : true,
ieCompat : true,
strictImports : true
}))
.pipe(postcss([ autoprefixer({ browsers: ['last 2 versions'] }) ]))
.on('error', errorHandler.onError)
.pipe(gulp.dest(paths.dest.content));
.pipe(sourcemaps.write(paths.dest.content))
.pipe(gulp.dest(paths.dest.content))
.pipe(livereload());
});

View File

@@ -1,45 +1,45 @@
var phantom = require('./phantom');
var paths = {
src: {
root: './src/UI/',
templates: './src/UI/**/*.hbs',
html: './src/UI/*.html',
partials: './src/UI/**/*Partial.hbs',
scripts: './src/UI/**/*.js',
less: ['./src/UI/**/*.less'],
content: './src/UI/Content/',
images: './src/UI/Content/Images/**/*',
exclude: {
libs: '!./src/UI/JsLibraries/**'
src : {
root : './src/UI/',
templates : './src/UI/**/*.hbs',
html : './src/UI/*.html',
partials : './src/UI/**/*Partial.hbs',
scripts : './src/UI/**/*.js',
less : ['./src/UI/**/*.less'],
content : './src/UI/Content/',
images : './src/UI/Content/Images/**/*',
exclude : {
libs : '!./src/UI/JsLibraries/**'
}
},
dest : {
root : './_output/UI/',
content : './_output/UI/Content/'
}
},
dest: {
root: './_output/UI/',
content: './_output/UI/Content/'
}
};
if (phantom) {
paths = {
src: {
root: './src/UI.Phantom/',
templates: './src/UI.Phantom/**/*.hbs',
html: './src/UI.Phantom/*.html',
partials: './src/UI.Phantom/**/*Partial.hbs',
scripts: './src/UI.Phantom/**/*.js',
less: ['./src/UI.Phantom/**/*.less'],
content: './src/UI.Phantom/Content/',
images: './src/UI.Phantom/Content/Images/**/*',
exclude: {
libs: '!./src/UI.Phantom/JsLibraries/**'
}
},
dest: {
root: './_output/UI.Phantom/',
content: './_output/UI.Phantom/Content/'
}
};
paths = {
src : {
root : './UI.Phantom/',
templates : './UI.Phantom/**/*.hbs',
html : './UI.Phantom/*.html',
partials : './UI.Phantom/**/*Partial.hbs',
scripts : './UI.Phantom/**/*.js',
less : ['./UI.Phantom/**/*.less'],
content : './UI.Phantom/Content/',
images : './UI.Phantom/Content/Images/**/*',
exclude : {
libs : '!./UI.Phantom/JsLibraries/**'
}
},
dest : {
root : './_output/UI.Phantom/',
content : './_output/UI.Phantom/Content/'
}
};
}
module.exports = paths;

View File

@@ -3,10 +3,12 @@
// gulp --phantom
var phantom = false;
process.argv.forEach(function (val, index, array) {
if(val=== '--phantom'){
phantom = true;
}
process.argv.forEach(function(val, index, array) {
if (val === '--phantom') {
phantom = true;
}
});
console.log('Phantom:', phantom);
module.exports = phantom;

View File

@@ -84,7 +84,7 @@ gulp.task('getSonarr', function () {
download(package.url, packagePath, function () {
extract(packagePath, dirName, function () {
// clean old binaries
console.log('Cleaning old binaries')
console.log('Cleaning old binaries');
del.sync(['./_output/*', '!./_output/UI/']);
console.log('copying binaries to target');
gulp.src(dirName + '/NzbDrone/*.*')

View File

@@ -7,6 +7,10 @@ var stripBom = function (dest) {
.pipe(stripbom({ showLog: false }))
.pipe(gulp.dest(dest));
gulp.src(paths.src.less)
.pipe(stripbom({ showLog: false }))
.pipe(gulp.dest(dest));
gulp.src(paths.src.templates)
.pipe(stripbom({ showLog: false }))
.pipe(gulp.dest(dest));

View File

@@ -1,6 +1,5 @@
var gulp = require('gulp');
//var livereload = require('gulp-livereload');
var livereload = require('gulp-livereload');
var paths = require('./paths.js');
@@ -10,24 +9,12 @@ require('./less.js');
require('./copy.js');
require('./webpack.js');
gulp.task('watch', ['jshint', 'handlebars', 'less','copyHtml', 'copyContent','copyJs'], function () {
gulp.start('webpackWatch');
gulp.watch([paths.src.scripts, paths.src.exclude.libs], ['jshint','copyJs']);
gulp.watch(paths.src.templates, ['handlebars']);
gulp.watch([paths.src.less, paths.src.exclude.libs], ['less']);
gulp.watch([paths.src.html], ['copyHtml']);
gulp.watch([paths.src.content + '**/*.*', '!**/*.less'], ['copyContent']);
});
gulp.task('liveReload', ['jshint', 'handlebars', 'less', 'webPack'], function () {
var server = livereload();
gulp.watch([
'app/**/*.js',
'app/**/*.css',
'app/index.html',
'app/login.html'
]).on('change', function (file) {
server.changed(file.path);
});
});
gulp.task('watch', ['jshint', 'handlebars', 'less', 'copyHtml', 'copyContent', 'copyJs'], function () {
livereload.listen();
gulp.start('webpackWatch');
gulp.watch([paths.src.scripts, paths.src.exclude.libs], ['jshint', 'copyJs']);
gulp.watch(paths.src.templates, ['handlebars']);
gulp.watch([paths.src.less, paths.src.exclude.libs], ['less']);
gulp.watch([paths.src.html], ['copyHtml']);
gulp.watch([paths.src.content + '**/*.*', '!**/*.less'], ['copyContent']);
});

View File

@@ -1,20 +1,13 @@
var gulp = require('gulp');
var gulpWebpack = require('gulp-webpack');
var webpack = require('webpack');
var webpackStream = require('webpack-stream');
var livereload = require('gulp-livereload');
var webpackConfig = require('../webpack.config');
webpackConfig.devtool = "#source-map";
gulp.task('webpack', function() {
return gulp.src('main.js')
.pipe(gulpWebpack(webpackConfig, webpack))
.pipe(gulp.dest(''));
return gulp.src('main.js').pipe(webpackStream(webpackConfig)).pipe(gulp.dest(''));
});
gulp.task('webpackWatch', function() {
webpackConfig.watch = true;
return gulp.src('main.js')
.pipe(gulpWebpack(webpackConfig, webpack))
.pipe(gulp.dest(''));
webpackConfig.watch = true;
return gulp.src('main.js').pipe(webpackStream(webpackConfig)).pipe(gulp.dest('')).pipe(livereload());
});

View File

@@ -5,3 +5,4 @@ NUNIT="$TESTDIR/NUnit.Runners.2.6.1/tools/nunit-console-x86.exe"
mono --debug --runtime=v4.0 $NUNIT $EXCLUDE -xml:NzbDrone.Api.Result.xml $TESTDIR/NzbDrone.Api.Test.dll
mono --debug --runtime=v4.0 $NUNIT $EXCLUDE -xml:NzbDrone.Core.Result.xml $TESTDIR/NzbDrone.Core.Test.dll
mono --debug --runtime=v4.0 $NUNIT $EXCLUDE -xml:NzbDrone.Integration.Result.xml $TESTDIR/NzbDrone.Integration.Test.dll
mono --debug --runtime=v4.0 $NUNIT $EXCLUDE -xml:NzbDrone.Common.Result.xml $TESTDIR/NzbDrone.Common.Test.dll

View File

@@ -15,6 +15,7 @@
"gitHead": "9ff7aa1bf7fe38c4c5bdb92f56c8ad556916ed67",
"readmeFilename": "readme.md",
"dependencies": {
"autoprefixer-core": "5.2.1",
"del": "1.2.0",
"gulp": "3.9.0",
"gulp-cached": "1.1.0",
@@ -23,9 +24,12 @@
"gulp-handlebars": "3.0.1",
"gulp-jshint": "1.11.2",
"gulp-less": "3.0.3",
"gulp-livereload": "3.8.0",
"gulp-postcss": "6.0.0",
"gulp-print": "1.1.0",
"gulp-replace": "0.5.3",
"gulp-run": "1.6.8",
"gulp-sourcemaps": "1.5.2",
"gulp-stripbom": "1.0.4",
"gulp-webpack": "1.5.0",
"gulp-wrap": "0.11.0",
@@ -34,7 +38,8 @@
"jshint-stylish": "2.0.1",
"run-sequence": "1.1.1",
"streamqueue": "1.1.0",
"tar.gz": "^0.1.1",
"webpack": "1.10.1"
"tar.gz": "0.1.1",
"webpack": "1.12.0",
"webpack-stream": "2.1.0"
}
}

View File

@@ -5,7 +5,7 @@ Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS fee
## Major Features Include: ##
* Support for major platforms: Windows, Linux, OSX, Raspberry Pi, etc.
* Support for major platforms: Windows, Linux, OSX, Raspberry Pi, etc.
* Automatically detects new episodes
* Can scan your existing library and download any missing episodes
* Can watch for better quality of the episodes you already have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
@@ -21,7 +21,7 @@ Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS fee
## Configuring Development Environment: ##
### Requirements ###
- Visual Studio 2013 [Free Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
- Visual Studio 2015 [Free Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
- [Git](http://git-scm.com/downloads)
- [NodeJS](http://nodejs.org/download/)
- [Gulp](http://gulpjs.com)
@@ -35,7 +35,7 @@ Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS fee
- install gulp `npm install gulp -g`
- start gulp to monitor your dev environment for any changes that need post processing using `gulp watch` command.
*Please note gulp must be running at all times while you are working with NzbDrone client source files.*
*Please note gulp must be running at all times while you are working with Sonarr client source files.*
### Development ###

View File

@@ -22,7 +22,7 @@ namespace NzbDrone.Api.Authentication
private readonly IUserService _userService;
private static readonly NzbDroneUser AnonymousUser = new NzbDroneUser { UserName = "Anonymous" };
private static String API_KEY;
private static string API_KEY;
private static AuthenticationType AUTH_METHOD;
public AuthenticationService(IConfigFileProvider configFileProvider, IUserService userService)

View File

@@ -39,8 +39,8 @@ namespace NzbDrone.Api.Authentication
pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(_authenticationService, "Sonarr"));
}
pipelines.BeforeRequest.AddItemToEndOfPipeline(RequiresAuthentication);
pipelines.AfterRequest.AddItemToEndOfPipeline(RemoveLoginHooksForApiCalls);
pipelines.BeforeRequest.AddItemToEndOfPipeline((Func<NancyContext, Response>) RequiresAuthentication);
pipelines.AfterRequest.AddItemToEndOfPipeline((Action<NancyContext>) RemoveLoginHooksForApiCalls);
}
private Response RequiresAuthentication(NancyContext context)

View File

@@ -5,14 +5,14 @@ namespace NzbDrone.Api.ClientSchema
{
public class Field
{
public Int32 Order { get; set; }
public String Name { get; set; }
public String Label { get; set; }
public String HelpText { get; set; }
public String HelpLink { get; set; }
public Object Value { get; set; }
public String Type { get; set; }
public Boolean Advanced { get; set; }
public int Order { get; set; }
public string Name { get; set; }
public string Label { get; set; }
public string HelpText { get; set; }
public string HelpLink { get; set; }
public object Value { get; set; }
public string Type { get; set; }
public bool Advanced { get; set; }
public List<SelectOption> SelectOptions { get; set; }
}
}

View File

@@ -77,19 +77,19 @@ namespace NzbDrone.Api.ClientSchema
{
var field = fields.Find(f => f.Name == propertyInfo.Name);
if (propertyInfo.PropertyType == typeof(Int32))
if (propertyInfo.PropertyType == typeof(int))
{
var value = Convert.ToInt32(field.Value);
propertyInfo.SetValue(target, value, null);
}
else if (propertyInfo.PropertyType == typeof(Int64))
else if (propertyInfo.PropertyType == typeof(long))
{
var value = Convert.ToInt64(field.Value);
propertyInfo.SetValue(target, value, null);
}
else if (propertyInfo.PropertyType == typeof(Nullable<Int32>))
else if (propertyInfo.PropertyType == typeof(int?))
{
var value = field.Value.ToString().ParseInt32();
propertyInfo.SetValue(target, value, null);
@@ -101,13 +101,13 @@ namespace NzbDrone.Api.ClientSchema
propertyInfo.SetValue(target, value, null);
}
else if (propertyInfo.PropertyType == typeof(IEnumerable<Int32>))
else if (propertyInfo.PropertyType == typeof(IEnumerable<int>))
{
IEnumerable<Int32> value;
IEnumerable<int> value;
if (field.Value.GetType() == typeof(JArray))
{
value = ((JArray)field.Value).Select(s => s.Value<Int32>());
value = ((JArray)field.Value).Select(s => s.Value<int>());
}
else

View File

@@ -7,8 +7,8 @@ namespace NzbDrone.Api.Commands
{
public class CommandResource : RestResource
{
public String Name { get; set; }
public String Message { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public Command Body { get; set; }
public CommandPriority Priority { get; set; }
public CommandStatus Status { get; set; }
@@ -33,7 +33,7 @@ namespace NzbDrone.Api.Commands
set { }
}
public Boolean Manual
public bool Manual
{
get
{
@@ -66,7 +66,7 @@ namespace NzbDrone.Api.Commands
set { }
}
public Boolean SendUpdatesToClient
public bool SendUpdatesToClient
{
get
{
@@ -78,6 +78,18 @@ namespace NzbDrone.Api.Commands
set { }
}
public bool UpdateScheduledTask
{
get
{
if (Body != null) return Body.UpdateScheduledTask;
return false;
}
set { }
}
public DateTime? LastExecutionTime { get; set; }
}
}

View File

@@ -19,7 +19,7 @@ namespace NzbDrone.Api.Config
.SetValidator(rootFolderValidator)
.SetValidator(mappedNetworkDriveValidator)
.SetValidator(pathExistsValidator)
.When(c => !String.IsNullOrWhiteSpace(c.DownloadedEpisodesFolder));
.When(c => !string.IsNullOrWhiteSpace(c.DownloadedEpisodesFolder));
}
}
}

View File

@@ -5,14 +5,14 @@ namespace NzbDrone.Api.Config
{
public class DownloadClientConfigResource : RestResource
{
public String DownloadedEpisodesFolder { get; set; }
public String DownloadClientWorkingFolders { get; set; }
public Int32 DownloadedEpisodesScanInterval { get; set; }
public string DownloadedEpisodesFolder { get; set; }
public string DownloadClientWorkingFolders { get; set; }
public int DownloadedEpisodesScanInterval { get; set; }
public Boolean EnableCompletedDownloadHandling { get; set; }
public Boolean RemoveCompletedDownloads { get; set; }
public bool EnableCompletedDownloadHandling { get; set; }
public bool RemoveCompletedDownloads { get; set; }
public Boolean AutoRedownloadFailed { get; set; }
public Boolean RemoveFailedDownloads { get; set; }
public bool AutoRedownloadFailed { get; set; }
public bool RemoveFailedDownloads { get; set; }
}
}

View File

@@ -7,23 +7,23 @@ namespace NzbDrone.Api.Config
{
public class HostConfigResource : RestResource
{
public String BindAddress { get; set; }
public Int32 Port { get; set; }
public Int32 SslPort { get; set; }
public Boolean EnableSsl { get; set; }
public Boolean LaunchBrowser { get; set; }
public string BindAddress { get; set; }
public int Port { get; set; }
public int SslPort { get; set; }
public bool EnableSsl { get; set; }
public bool LaunchBrowser { get; set; }
public AuthenticationType AuthenticationMethod { get; set; }
public Boolean AnalyticsEnabled { get; set; }
public String Username { get; set; }
public String Password { get; set; }
public String LogLevel { get; set; }
public String Branch { get; set; }
public String ApiKey { get; set; }
public Boolean Torrent { get; set; }
public String SslCertHash { get; set; }
public String UrlBase { get; set; }
public Boolean UpdateAutomatically { get; set; }
public bool AnalyticsEnabled { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string LogLevel { get; set; }
public string Branch { get; set; }
public string ApiKey { get; set; }
public bool Torrent { get; set; }
public string SslCertHash { get; set; }
public string UrlBase { get; set; }
public bool UpdateAutomatically { get; set; }
public UpdateMechanism UpdateMechanism { get; set; }
public String UpdateScriptPath { get; set; }
public string UpdateScriptPath { get; set; }
}
}

View File

@@ -5,8 +5,8 @@ namespace NzbDrone.Api.Config
{
public class IndexerConfigResource : RestResource
{
public Int32 MinimumAge { get; set; }
public Int32 Retention { get; set; }
public Int32 RssSyncInterval { get; set; }
public int MinimumAge { get; set; }
public int Retention { get; set; }
public int RssSyncInterval { get; set; }
}
}

View File

@@ -12,7 +12,7 @@ namespace NzbDrone.Api.Config
{
SharedValidator.RuleFor(c => c.FileChmod).NotEmpty();
SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !String.IsNullOrWhiteSpace(c.RecycleBin));
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin));
}
}
}

View File

@@ -6,20 +6,20 @@ namespace NzbDrone.Api.Config
{
public class MediaManagementConfigResource : RestResource
{
public Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
public String RecycleBin { get; set; }
public Boolean AutoDownloadPropers { get; set; }
public Boolean CreateEmptySeriesFolders { get; set; }
public bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
public string RecycleBin { get; set; }
public bool AutoDownloadPropers { get; set; }
public bool CreateEmptySeriesFolders { get; set; }
public FileDateType FileDate { get; set; }
public Boolean SetPermissionsLinux { get; set; }
public String FileChmod { get; set; }
public String FolderChmod { get; set; }
public String ChownUser { get; set; }
public String ChownGroup { get; set; }
public bool SetPermissionsLinux { get; set; }
public string FileChmod { get; set; }
public string FolderChmod { get; set; }
public string ChownUser { get; set; }
public string ChownGroup { get; set; }
public Boolean SkipFreeSpaceCheckWhenImporting { get; set; }
public Boolean CopyUsingHardlinks { get; set; }
public Boolean EnableMediaInfo { get; set; }
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
public bool CopyUsingHardlinks { get; set; }
public bool EnableMediaInfo { get; set; }
}
}

View File

@@ -57,7 +57,7 @@ namespace NzbDrone.Api.Config
var nameSpec = _namingConfigService.GetConfig();
var resource = nameSpec.InjectTo<NamingConfigResource>();
if (String.IsNullOrWhiteSpace(resource.StandardEpisodeFormat))
if (string.IsNullOrWhiteSpace(resource.StandardEpisodeFormat))
{
return resource;
}

View File

@@ -5,8 +5,9 @@ namespace NzbDrone.Api.Config
{
public class NamingConfigResource : RestResource
{
public Boolean RenameEpisodes { get; set; }
public Int32 MultiEpisodeStyle { get; set; }
public bool RenameEpisodes { get; set; }
public bool ReplaceIllegalCharacters { get; set; }
public int MultiEpisodeStyle { get; set; }
public string StandardEpisodeFormat { get; set; }
public string DailyEpisodeFormat { get; set; }
public string AnimeEpisodeFormat { get; set; }

View File

@@ -6,15 +6,15 @@ namespace NzbDrone.Api.Config
public class UiConfigResource : RestResource
{
//Calendar
public Int32 FirstDayOfWeek { get; set; }
public String CalendarWeekColumnHeader { get; set; }
public int FirstDayOfWeek { get; set; }
public string CalendarWeekColumnHeader { get; set; }
//Dates
public String ShortDateFormat { get; set; }
public String LongDateFormat { get; set; }
public String TimeFormat { get; set; }
public Boolean ShowRelativeDates { get; set; }
public string ShortDateFormat { get; set; }
public string LongDateFormat { get; set; }
public string TimeFormat { get; set; }
public bool ShowRelativeDates { get; set; }
public Boolean EnableColorImpairedMode { get; set; }
public bool EnableColorImpairedMode { get; set; }
}
}

View File

@@ -7,7 +7,7 @@ namespace NzbDrone.Api.DiskSpace
{
public string Path { get; set; }
public string Label { get; set; }
public Int64 FreeSpace { get; set; }
public Int64 TotalSpace { get; set; }
public long FreeSpace { get; set; }
public long TotalSpace { get; set; }
}
}

View File

@@ -5,7 +5,7 @@ namespace NzbDrone.Api.DownloadClient
{
public class DownloadClientResource : ProviderResource
{
public Boolean Enable { get; set; }
public bool Enable { get; set; }
public DownloadProtocol Protocol { get; set; }
}
}

View File

@@ -6,15 +6,15 @@ namespace NzbDrone.Api.EpisodeFiles
{
public class EpisodeFileResource : RestResource
{
public Int32 SeriesId { get; set; }
public Int32 SeasonNumber { get; set; }
public String RelativePath { get; set; }
public String Path { get; set; }
public Int64 Size { get; set; }
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 string SceneName { get; set; }
public QualityModel Quality { get; set; }
public Boolean QualityCutoffNotMet { get; set; }
public bool QualityCutoffNotMet { get; set; }
}
}

View File

@@ -40,7 +40,7 @@ namespace NzbDrone.Api.Episodes
ISeriesService seriesService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
IBroadcastSignalRMessage signalRBroadcaster,
String resource)
string resource)
: base(signalRBroadcaster, resource)
{
_episodeService = episodeService;

View File

@@ -8,29 +8,30 @@ namespace NzbDrone.Api.Episodes
{
public class EpisodeResource : RestResource
{
public Int32 SeriesId { get; set; }
public Int32 EpisodeFileId { get; set; }
public Int32 SeasonNumber { get; set; }
public Int32 EpisodeNumber { get; set; }
public String Title { get; set; }
public String AirDate { get; set; }
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 string Overview { get; set; }
public EpisodeFileResource EpisodeFile { get; set; }
public Boolean HasFile { get; set; }
public Boolean Monitored { get; set; }
public Nullable<Int32> AbsoluteEpisodeNumber { get; set; }
public Nullable<Int32> SceneAbsoluteEpisodeNumber { get; set; }
public Nullable<Int32> SceneEpisodeNumber { get; set; }
public Nullable<Int32> SceneSeasonNumber { 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 DateTime? EndTime { get; set; }
public DateTime? GrabDate { get; set; }
public String SeriesTitle { 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 Boolean Grabbed { get; set; }
public bool Grabbed { get; set; }
}
}

View File

@@ -6,11 +6,11 @@ namespace NzbDrone.Api.Episodes
{
public class RenameEpisodeResource : RestResource
{
public Int32 SeriesId { get; set; }
public Int32 SeasonNumber { get; set; }
public List<Int32> EpisodeNumbers { get; set; }
public Int32 EpisodeFileId { get; set; }
public String ExistingPath { get; set; }
public String NewPath { get; set; }
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; }
}
}

View File

@@ -63,7 +63,7 @@ namespace NzbDrone.Api.ErrorManagement
}.AsResponse(HttpStatusCode.Conflict);
}
var sqlErrorMessage = String.Format("[{0} {1}]", context.Request.Method, context.Request.Path);
var sqlErrorMessage = string.Format("[{0} {1}]", context.Request.Method, context.Request.Path);
_logger.ErrorException(sqlErrorMessage, sqLiteException);
}

View File

@@ -13,7 +13,7 @@ namespace NzbDrone.Api.Extensions
{
private static readonly ICached<MethodInfo> SetterCache = new Cached<MethodInfo>();
public static IEnumerable<TParent> LoadSubtype<TParent, TChild, TSourceChild>(this IEnumerable<TParent> parents, Func<TParent, Int32> foreignKeySelector, Func<IEnumerable<Int32>, IEnumerable<TSourceChild>> sourceChildSelector)
public static IEnumerable<TParent> LoadSubtype<TParent, TChild, TSourceChild>(this IEnumerable<TParent> parents, Func<TParent, int> foreignKeySelector, Func<IEnumerable<int>, IEnumerable<TSourceChild>> sourceChildSelector)
where TSourceChild : ModelBase, new()
where TChild : RestResource, new()
where TParent : RestResource

View File

@@ -1,4 +1,5 @@
using Nancy;
using System;
using Nancy;
using Nancy.Bootstrapper;
using NzbDrone.Api.Frontend;
@@ -15,7 +16,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
public void Register(IPipelines pipelines)
{
pipelines.AfterRequest.AddItemToStartOfPipeline(Handle);
pipelines.AfterRequest.AddItemToStartOfPipeline((Action<NancyContext>) Handle);
}
private void Handle(NancyContext context)

View File

@@ -9,7 +9,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
{
public void Register(IPipelines pipelines)
{
pipelines.AfterRequest.AddItemToEndOfPipeline(Handle);
pipelines.AfterRequest.AddItemToEndOfPipeline((Action<NancyContext>) Handle);
}
private void Handle(NancyContext context)
@@ -31,7 +31,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
allowedMethods = response.Headers["Allow"];
}
var requestedHeaders = String.Join(", ", request.Headers[AccessControlHeaders.RequestHeaders]);
var requestedHeaders = string.Join(", ", request.Headers[AccessControlHeaders.RequestHeaders]);
response.Headers.Add(AccessControlHeaders.AllowOrigin, "*");
response.Headers.Add(AccessControlHeaders.AllowMethods, allowedMethods);

View File

@@ -1,3 +1,4 @@
using System;
using Nancy;
using Nancy.Bootstrapper;
using NzbDrone.Api.Frontend;
@@ -15,7 +16,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
public void Register(IPipelines pipelines)
{
pipelines.BeforeRequest.AddItemToStartOfPipeline(Handle);
pipelines.BeforeRequest.AddItemToStartOfPipeline((Func<NancyContext, Response>) Handle);
}
private Response Handle(NancyContext context)

View File

@@ -1,4 +1,5 @@
using Nancy;
using System;
using Nancy;
using Nancy.Bootstrapper;
using NzbDrone.Common.EnvironmentInfo;
@@ -8,7 +9,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
{
public void Register(IPipelines pipelines)
{
pipelines.AfterRequest.AddItemToStartOfPipeline(Handle);
pipelines.AfterRequest.AddItemToStartOfPipeline((Action<NancyContext>) Handle);
}
private void Handle(NancyContext context)

View File

@@ -14,7 +14,7 @@ namespace NzbDrone.Api.Frontend
{
public bool IsCacheable(NancyContext context)
{
if (BuildInfo.IsDebug)
if (!RuntimeInfoBase.IsProduction)
{
return false;
}

View File

@@ -3,17 +3,20 @@ using System.IO;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Api.Frontend.Mappers
{
public class FaviconMapper : StaticResourceMapperBase
{
private readonly IAppFolderInfo _appFolderInfo;
private readonly IConfigFileProvider _configFileProvider;
public FaviconMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, Logger logger)
public FaviconMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider,IConfigFileProvider configFileProvider, Logger logger)
: base(diskProvider, logger)
{
_appFolderInfo = appFolderInfo;
_configFileProvider = configFileProvider;
}
public override string Map(string resourceUrl)
@@ -27,7 +30,7 @@ namespace NzbDrone.Api.Frontend.Mappers
var path = Path.Combine("Content", "Images", fileName);
return Path.Combine(_appFolderInfo.StartUpFolder, "UI", path);
return Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path);
}
public override bool CanHandle(string resourceUrl)

View File

@@ -17,10 +17,10 @@ namespace NzbDrone.Api.Frontend.Mappers
private readonly IAnalyticsService _analyticsService;
private readonly Func<ICacheBreakerProvider> _cacheBreakProviderFactory;
private readonly string _indexPath;
private static readonly Regex ReplaceRegex = new Regex("(?<=(?:href|src)=\").*?(css|js|png|ico|ics)(?=\")", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex ReplaceRegex = new Regex(@"(?:(?<attribute>href|src)=\"")(?<path>.*?(?<extension>css|js|png|ico|ics))(?:\"")(?:\s(?<nohash>data-no-hash))?", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static String API_KEY;
private static String URL_BASE;
private static string API_KEY;
private static string URL_BASE;
private string _generatedContent
;
@@ -36,7 +36,7 @@ namespace NzbDrone.Api.Frontend.Mappers
_configFileProvider = configFileProvider;
_analyticsService = analyticsService;
_cacheBreakProviderFactory = cacheBreakProviderFactory;
_indexPath = Path.Combine(appFolderInfo.StartUpFolder, "UI", "index.html");
_indexPath = Path.Combine(appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, "index.html");
API_KEY = configFileProvider.ApiKey;
URL_BASE = configFileProvider.UrlBase;
@@ -85,8 +85,19 @@ namespace NzbDrone.Api.Frontend.Mappers
text = ReplaceRegex.Replace(text, match =>
{
var url = cacheBreakProvider.AddCacheBreakerToPath(match.Value);
return URL_BASE + url;
string url;
if (match.Groups["nohash"].Success)
{
url = match.Groups["path"].Value;
}
else
{
url = cacheBreakProvider.AddCacheBreakerToPath(match.Groups["path"].Value);
}
return string.Format("{0}=\"{1}{2}\"", match.Groups["attribute"].Value, URL_BASE, url);
});
text = text.Replace("API_ROOT", URL_BASE + "/api");

View File

@@ -12,11 +12,12 @@ namespace NzbDrone.Api.Frontend.Mappers
public class LoginHtmlMapper : StaticResourceMapperBase
{
private readonly IDiskProvider _diskProvider;
private readonly IConfigFileProvider _configFileProvider;
private readonly Func<ICacheBreakerProvider> _cacheBreakProviderFactory;
private readonly string _indexPath;
private static readonly Regex ReplaceRegex = new Regex("(?<=(?:href|src|data-main)=\").*?(?=\")", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static String URL_BASE;
private static string URL_BASE;
private string _generatedContent;
public LoginHtmlMapper(IAppFolderInfo appFolderInfo,
@@ -27,8 +28,9 @@ namespace NzbDrone.Api.Frontend.Mappers
: base(diskProvider, logger)
{
_diskProvider = diskProvider;
_configFileProvider = configFileProvider;
_cacheBreakProviderFactory = cacheBreakProviderFactory;
_indexPath = Path.Combine(appFolderInfo.StartUpFolder, "UI", "login.html");
_indexPath = Path.Combine(appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, "login.html");
URL_BASE = configFileProvider.UrlBase;
}

View File

@@ -3,24 +3,27 @@ using System.IO;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Api.Frontend.Mappers
{
public class RobotsTxtMapper : StaticResourceMapperBase
{
private readonly IAppFolderInfo _appFolderInfo;
private readonly IConfigFileProvider _configFileProvider;
public RobotsTxtMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, Logger logger)
public RobotsTxtMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
: base(diskProvider, logger)
{
_appFolderInfo = appFolderInfo;
_configFileProvider = configFileProvider;
}
public override string Map(string resourceUrl)
{
var path = Path.Combine("Content", "robots.txt");
return Path.Combine(_appFolderInfo.StartUpFolder, "UI", path);
return Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path);
}
public override bool CanHandle(string resourceUrl)

View File

@@ -2,17 +2,20 @@ using System.IO;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Api.Frontend.Mappers
{
public class StaticResourceMapper : StaticResourceMapperBase
{
private readonly IAppFolderInfo _appFolderInfo;
private readonly IConfigFileProvider _configFileProvider;
public StaticResourceMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, Logger logger)
public StaticResourceMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
: base(diskProvider, logger)
{
_appFolderInfo = appFolderInfo;
_configFileProvider = configFileProvider;
}
public override string Map(string resourceUrl)
@@ -20,7 +23,7 @@ namespace NzbDrone.Api.Frontend.Mappers
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
path = path.Trim(Path.DirectorySeparatorChar);
return Path.Combine(_appFolderInfo.StartUpFolder, "UI", path);
return Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path);
}
public override bool CanHandle(string resourceUrl)
@@ -30,7 +33,8 @@ namespace NzbDrone.Api.Frontend.Mappers
resourceUrl.EndsWith(".map") ||
resourceUrl.EndsWith(".css") ||
(resourceUrl.EndsWith(".ico") && !resourceUrl.Equals("/favicon.ico")) ||
resourceUrl.EndsWith(".swf");
resourceUrl.EndsWith(".swf") ||
resourceUrl.EndsWith("oauth.html");
}
}
}

View File

@@ -43,7 +43,7 @@ namespace NzbDrone.Api.Frontend
{
var urlBase = _configFileProvider.UrlBase;
if (!String.IsNullOrEmpty(urlBase))
if (!string.IsNullOrEmpty(urlBase))
{
if (Request.Url.BasePath != urlBase)
{

View File

@@ -7,7 +7,7 @@ namespace NzbDrone.Api.Health
public class HealthResource : RestResource
{
public HealthCheckResult Type { get; set; }
public String Message { get; set; }
public string Message { get; set; }
public Uri WikiUrl { get; set; }
}
}

View File

@@ -71,7 +71,7 @@ namespace NzbDrone.Api.History
{
var id = (int)Request.Form.Id;
_failedDownloadService.MarkAsFailed(id);
return new Object().AsResponse();
return new object().AsResponse();
}
}
}

View File

@@ -15,7 +15,7 @@ namespace NzbDrone.Api.History
public int SeriesId { get; set; }
public string SourceTitle { get; set; }
public QualityModel Quality { get; set; }
public Boolean QualityCutoffNotMet { get; set; }
public bool QualityCutoffNotMet { get; set; }
public DateTime Date { get; set; }
public string Indexer { get; set; }
public string ReleaseGroup { get; set; }

View File

@@ -5,10 +5,10 @@ namespace NzbDrone.Api.Indexers
{
public class IndexerResource : ProviderResource
{
public Boolean EnableRss { get; set; }
public Boolean EnableSearch { get; set; }
public Boolean SupportsRss { get; set; }
public Boolean SupportsSearch { get; set; }
public bool EnableRss { get; set; }
public bool EnableSearch { get; set; }
public bool SupportsRss { get; set; }
public bool SupportsSearch { get; set; }
public DownloadProtocol Protocol { get; set; }
}
}

View File

@@ -9,8 +9,6 @@ using NzbDrone.Core.Exceptions;
using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser.Model;
using Omu.ValueInjecter;
using System.Linq;
using Nancy.ModelBinding;
using NzbDrone.Api.Extensions;
using NzbDrone.Common.Cache;
@@ -18,7 +16,7 @@ using HttpStatusCode = System.Net.HttpStatusCode;
namespace NzbDrone.Api.Indexers
{
public class ReleaseModule : NzbDroneRestModule<ReleaseResource>
public class ReleaseModule : ReleaseModuleBase
{
private readonly IFetchAndParseRss _rssFetcherAndParser;
private readonly ISearchForNzb _nzbSearchService;
@@ -113,55 +111,10 @@ namespace NzbDrone.Api.Indexers
return MapDecisions(prioritizedDecisions);
}
private List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision> decisions)
protected override ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
{
var result = new List<ReleaseResource>();
foreach (var downloadDecision in decisions)
{
_remoteEpisodeCache.Set(downloadDecision.RemoteEpisode.Release.Guid, downloadDecision.RemoteEpisode, TimeSpan.FromMinutes(30));
var release = new ReleaseResource();
release.InjectFrom(downloadDecision.RemoteEpisode.Release);
release.InjectFrom(downloadDecision.RemoteEpisode.ParsedEpisodeInfo);
release.InjectFrom(downloadDecision);
release.Rejections = downloadDecision.Rejections.Select(r => r.Reason).ToList();
release.DownloadAllowed = downloadDecision.RemoteEpisode.DownloadAllowed;
release.ReleaseWeight = result.Count;
if (downloadDecision.RemoteEpisode.Series != null)
{
release.QualityWeight = downloadDecision.RemoteEpisode
.Series
.Profile
.Value
.Items
.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
}
release.QualityWeight += release.Quality.Revision.Real * 10;
release.QualityWeight += release.Quality.Revision.Version;
var torrentRelease = downloadDecision.RemoteEpisode.Release as TorrentInfo;
if (torrentRelease != null)
{
release.Protocol = DownloadProtocol.Torrent;
release.Seeders = torrentRelease.Seeders;
//TODO: move this up the chains
release.Leechers = torrentRelease.Peers - torrentRelease.Seeders;
}
else
{
release.Protocol = DownloadProtocol.Usenet;
}
result.Add(release);
}
return result;
_remoteEpisodeCache.Set(decision.RemoteEpisode.Release.Guid, decision.RemoteEpisode, TimeSpan.FromMinutes(30));
return base.MapDecision(decision, initialWeight);
}
}
}

View File

@@ -0,0 +1,67 @@
using System.Collections.Generic;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser.Model;
using Omu.ValueInjecter;
using System.Linq;
namespace NzbDrone.Api.Indexers
{
public abstract class ReleaseModuleBase : NzbDroneRestModule<ReleaseResource>
{
protected virtual List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision> decisions)
{
var result = new List<ReleaseResource>();
foreach (var downloadDecision in decisions)
{
var release = MapDecision(downloadDecision, result.Count);
result.Add(release);
}
return result;
}
protected virtual ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
{
var release = new ReleaseResource();
release.InjectFrom(decision.RemoteEpisode.Release);
release.InjectFrom(decision.RemoteEpisode.ParsedEpisodeInfo);
release.InjectFrom(decision);
release.Rejections = decision.Rejections.Select(r => r.Reason).ToList();
release.DownloadAllowed = decision.RemoteEpisode.DownloadAllowed;
release.ReleaseWeight = initialWeight;
if (decision.RemoteEpisode.Series != null)
{
release.QualityWeight = decision.RemoteEpisode
.Series
.Profile
.Value
.Items
.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
}
release.QualityWeight += release.Quality.Revision.Real * 10;
release.QualityWeight += release.Quality.Revision.Version;
var torrentRelease = decision.RemoteEpisode.Release as TorrentInfo;
if (torrentRelease != null)
{
release.Protocol = DownloadProtocol.Torrent;
release.Seeders = torrentRelease.Seeders;
//TODO: move this up the chains
release.Leechers = torrentRelease.Peers - torrentRelease.Seeders;
}
else
{
release.Protocol = DownloadProtocol.Usenet;
}
return release;
}
}
}

View File

@@ -0,0 +1,50 @@
using Nancy;
using Nancy.ModelBinding;
using FluentValidation;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Api.Mapping;
using NzbDrone.Api.Extensions;
using NLog;
namespace NzbDrone.Api.Indexers
{
class ReleasePushModule : ReleaseModuleBase
{
private readonly IMakeDownloadDecision _downloadDecisionMaker;
private readonly IProcessDownloadDecisions _downloadDecisionProcessor;
private readonly Logger _logger;
public ReleasePushModule(IMakeDownloadDecision downloadDecisionMaker,
IProcessDownloadDecisions downloadDecisionProcessor,
Logger logger)
{
_downloadDecisionMaker = downloadDecisionMaker;
_downloadDecisionProcessor = downloadDecisionProcessor;
_logger = logger;
Post["/push"] = x => ProcessRelease(this.Bind<ReleaseResource>());
PostValidator.RuleFor(s => s.Title).NotEmpty();
PostValidator.RuleFor(s => s.DownloadUrl).NotEmpty();
PostValidator.RuleFor(s => s.DownloadProtocol).NotEmpty();
PostValidator.RuleFor(s => s.PublishDate).NotEmpty();
}
private Response ProcessRelease(ReleaseResource release)
{
_logger.Info("Release pushed: {0} - {1}", release.Title, release.DownloadUrl);
var info = release.InjectTo<ReleaseInfo>();
info.Guid = "PUSH-" + info.DownloadUrl;
var decisions = _downloadDecisionMaker.GetRssDecision(new List<ReleaseInfo> { info });
var processed = _downloadDecisionProcessor.ProcessDecisions(decisions);
return MapDecisions(decisions).First().AsResponse();
}
}
}

View File

@@ -9,37 +9,39 @@ namespace NzbDrone.Api.Indexers
{
public class ReleaseResource : RestResource
{
public String Guid { get; set; }
public string Guid { get; set; }
public QualityModel Quality { get; set; }
public Int32 QualityWeight { get; set; }
public Int32 Age { get; set; }
public Double AgeHours { get; set; }
public Double AgeMinutes { get; set; }
public Int64 Size { get; set; }
public String Indexer { get; set; }
public String ReleaseGroup { get; set; }
public String SubGroup { get; set; }
public String ReleaseHash { get; set; }
public String Title { get; set; }
public Boolean FullSeason { get; set; }
public Boolean SceneSource { get; set; }
public Int32 SeasonNumber { get; set; }
public int QualityWeight { get; set; }
public int Age { get; set; }
public double AgeHours { get; set; }
public double AgeMinutes { get; set; }
public long Size { get; set; }
public int IndexerId { get; set; }
public string Indexer { get; set; }
public string ReleaseGroup { get; set; }
public string SubGroup { get; set; }
public string ReleaseHash { get; set; }
public string Title { get; set; }
public bool FullSeason { get; set; }
public bool SceneSource { get; set; }
public int SeasonNumber { get; set; }
public Language Language { get; set; }
public String AirDate { get; set; }
public String SeriesTitle { get; set; }
public string AirDate { get; set; }
public string SeriesTitle { get; set; }
public int[] EpisodeNumbers { get; set; }
public int[] AbsoluteEpisodeNumbers { get; set; }
public Boolean Approved { get; set; }
public Boolean TemporarilyRejected { get; set; }
public Boolean Rejected { get; set; }
public Int32 TvRageId { get; set; }
public IEnumerable<String> Rejections { get; set; }
public bool Approved { get; set; }
public bool TemporarilyRejected { get; set; }
public bool Rejected { get; set; }
public int TvdbId { get; set; }
public int TvRageId { get; set; }
public IEnumerable<string> Rejections { get; set; }
public DateTime PublishDate { get; set; }
public String CommentUrl { get; set; }
public String DownloadUrl { get; set; }
public String InfoUrl { get; set; }
public Boolean DownloadAllowed { get; set; }
public Int32 ReleaseWeight { get; set; }
public string CommentUrl { get; set; }
public string DownloadUrl { get; set; }
public string InfoUrl { get; set; }
public bool DownloadAllowed { get; set; }
public int ReleaseWeight { get; set; }
public int? Seeders { get; set; }
@@ -49,9 +51,9 @@ namespace NzbDrone.Api.Indexers
//TODO: besides a test I don't think this is used...
public DownloadProtocol DownloadProtocol { get; set; }
public Boolean IsDaily { get; set; }
public Boolean IsAbsoluteNumbering { get; set; }
public Boolean IsPossibleSpecialEpisode { get; set; }
public Boolean Special { get; set; }
public bool IsDaily { get; set; }
public bool IsAbsoluteNumbering { get; set; }
public bool IsPossibleSpecialEpisode { get; set; }
public bool Special { get; set; }
}
}

View File

@@ -18,7 +18,7 @@ namespace NzbDrone.Api.Logs
public LogFileModuleBase(IDiskProvider diskProvider,
IConfigFileProvider configFileProvider,
String route)
string route)
: base("log/file" + route)
{
_diskProvider = diskProvider;
@@ -44,15 +44,15 @@ namespace NzbDrone.Api.Logs
Id = i + 1,
Filename = filename,
LastWriteTime = _diskProvider.FileGetLastWrite(file),
ContentsUrl = String.Format("{0}/api/{1}/{2}", _configFileProvider.UrlBase, Resource, filename),
DownloadUrl = String.Format("{0}/{1}/{2}", _configFileProvider.UrlBase, DownloadUrlRoot, filename)
ContentsUrl = string.Format("{0}/api/{1}/{2}", _configFileProvider.UrlBase, Resource, filename),
DownloadUrl = string.Format("{0}/{1}/{2}", _configFileProvider.UrlBase, DownloadUrlRoot, filename)
});
}
return result.OrderByDescending(l => l.LastWriteTime).ToList();
}
private Response GetLogFileResponse(String filename)
private Response GetLogFileResponse(string filename)
{
var filePath = GetLogFilePath(filename);
@@ -64,9 +64,9 @@ namespace NzbDrone.Api.Logs
return new TextResponse(data);
}
protected abstract IEnumerable<String> GetLogFiles();
protected abstract String GetLogFilePath(String filename);
protected abstract IEnumerable<string> GetLogFiles();
protected abstract string GetLogFilePath(string filename);
protected abstract String DownloadUrlRoot { get; }
protected abstract string DownloadUrlRoot { get; }
}
}

View File

@@ -5,9 +5,9 @@ namespace NzbDrone.Api.Logs
{
public class LogFileResource : RestResource
{
public String Filename { get; set; }
public string Filename { get; set; }
public DateTime LastWriteTime { get; set; }
public String ContentsUrl { get; set; }
public String DownloadUrl { get; set; }
public string ContentsUrl { get; set; }
public string DownloadUrl { get; set; }
}
}

View File

@@ -6,11 +6,11 @@ namespace NzbDrone.Api.Logs
public class LogResource : RestResource
{
public DateTime Time { get; set; }
public String Exception { get; set; }
public String ExceptionType { get; set; }
public String Level { get; set; }
public String Logger { get; set; }
public String Message { get; set; }
public String Method { get; set; }
public string Exception { get; set; }
public string ExceptionType { get; set; }
public string Level { get; set; }
public string Logger { get; set; }
public string Message { get; set; }
public string Method { get; set; }
}
}

View File

@@ -24,21 +24,21 @@ namespace NzbDrone.Api.Logs
_diskProvider = diskProvider;
}
protected override IEnumerable<String> GetLogFiles()
protected override IEnumerable<string> GetLogFiles()
{
if (!_diskProvider.FolderExists(_appFolderInfo.GetUpdateLogFolder())) return Enumerable.Empty<String>();
if (!_diskProvider.FolderExists(_appFolderInfo.GetUpdateLogFolder())) return Enumerable.Empty<string>();
return _diskProvider.GetFiles(_appFolderInfo.GetUpdateLogFolder(), SearchOption.TopDirectoryOnly)
.Where(f => Regex.IsMatch(Path.GetFileName(f), LOGFILE_ROUTE.TrimStart('/'), RegexOptions.IgnoreCase))
.ToList();
}
protected override String GetLogFilePath(String filename)
protected override string GetLogFilePath(string filename)
{
return Path.Combine(_appFolderInfo.GetUpdateLogFolder(), filename);
}
protected override String DownloadUrlRoot
protected override string DownloadUrlRoot
{
get
{

View File

@@ -30,10 +30,13 @@ namespace NzbDrone.Api.ManualImport
private ManualImportResource AddQualityWeight(ManualImportResource item)
{
item.QualityWeight = Quality.DefaultQualityDefinitions.Single(q => q.Quality == item.Quality.Quality).Weight;
item.QualityWeight += item.Quality.Revision.Real * 10;
item.QualityWeight += item.Quality.Revision.Version;
if (item.Quality != null)
{
item.QualityWeight = Quality.DefaultQualityDefinitions.Single(q => q.Quality == item.Quality.Quality).Weight;
item.QualityWeight += item.Quality.Revision.Real * 10;
item.QualityWeight += item.Quality.Revision.Version;
}
return item;
}
}

View File

@@ -7,7 +7,7 @@ namespace NzbDrone.Api.Mapping
public class ResourceMappingException : ApplicationException
{
public ResourceMappingException(IEnumerable<string> error)
: base(Environment.NewLine + String.Join(Environment.NewLine, error.OrderBy(c => c)))
: base(Environment.NewLine + string.Join(Environment.NewLine, error.OrderBy(c => c)))
{
}

View File

@@ -4,6 +4,6 @@ namespace NzbDrone.Api.Metadata
{
public class MetadataResource : ProviderResource
{
public Boolean Enable { get; set; }
public bool Enable { get; set; }
}
}

View File

@@ -1,4 +1,6 @@
using NLog;
using System;
using NLog;
using Nancy;
using Nancy.Bootstrapper;
using Nancy.Diagnostics;
using NzbDrone.Api.ErrorManagement;
@@ -36,7 +38,7 @@ namespace NzbDrone.Api
container.Resolve<DatabaseTarget>().Register();
container.Resolve<IEventAggregator>().PublishEvent(new ApplicationStartedEvent());
ApplicationPipelines.OnError.AddItemToEndOfPipeline(container.Resolve<NzbDroneErrorPipeline>().HandleException);
ApplicationPipelines.OnError.AddItemToEndOfPipeline((Func<NancyContext, Exception, Response>) container.Resolve<NzbDroneErrorPipeline>().HandleException);
}
private void RegisterPipelines(IPipelines pipelines)

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
namespace NzbDrone.Api.Notifications
{
@@ -9,6 +8,11 @@ namespace NzbDrone.Api.Notifications
public bool OnGrab { get; set; }
public bool OnDownload { get; set; }
public bool OnUpgrade { get; set; }
public bool OnRename { get; set; }
public bool SupportsOnGrab { get; set; }
public bool SupportsOnDownload { get; set; }
public bool SupportsOnUpgrade { get; set; }
public bool SupportsOnRename { get; set; }
public string TestCommand { get; set; }
public HashSet<int> Tags { get; set; }
}

View File

@@ -101,6 +101,8 @@
<Compile Include="Extensions\Pipelines\CorsPipeline.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="Parse\ParseModule.cs" />
<Compile Include="Parse\ParseResource.cs" />
<Compile Include="ManualImport\ManualImportModule.cs" />

View File

@@ -24,7 +24,7 @@ namespace NzbDrone.Api.Parse
return null;
}
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo);
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
if (remoteEpisode == null)
{

View File

@@ -7,8 +7,8 @@ namespace NzbDrone.Api.Profiles.Languages
public class LanguageResource : RestResource
{
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]
public Int32 Id { get; set; }
public String Name { get; set; }
public String NameLower { get { return Name.ToLowerInvariant(); } }
public int Id { get; set; }
public string Name { get; set; }
public string NameLower { get { return Name.ToLowerInvariant(); } }
}
}

View File

@@ -12,7 +12,7 @@ namespace NzbDrone.Api.Profiles
Get["/"] = x =>
{
string queryString = ConvertQueryParams(Request.Query);
var url = String.Format("/api/profile?{0}", queryString);
var url = string.Format("/api/profile?{0}", queryString);
return Response.AsRedirect(url);
};

View File

@@ -8,7 +8,7 @@ namespace NzbDrone.Api.Profiles
{
public class ProfileResource : RestResource
{
public String Name { get; set; }
public string Name { get; set; }
public Quality Cutoff { get; set; }
public List<ProfileQualityItemResource> Items { get; set; }
public Language Language { get; set; }

View File

@@ -11,6 +11,7 @@ using NzbDrone.Common.Reflection;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using Omu.ValueInjecter;
using Newtonsoft.Json;
namespace NzbDrone.Api
{
@@ -27,7 +28,8 @@ namespace NzbDrone.Api
_providerFactory = providerFactory;
Get["schema"] = x => GetTemplates();
Post["test"] = x => Test(ReadResourceFromRequest());
Post["test"] = x => Test(ReadResourceFromRequest(true));
Post["connectData/{stage}"] = x => ConnectData(x.stage, ReadResourceFromRequest(true));
GetResourceAll = GetAll;
GetResourceById = GetProviderById;
@@ -98,7 +100,7 @@ namespace NzbDrone.Api
_providerFactory.Update(providerDefinition);
}
private TProviderDefinition GetDefinition(TProviderResource providerResource, bool includeWarnings = false)
private TProviderDefinition GetDefinition(TProviderResource providerResource, bool includeWarnings = false, bool validate = true)
{
var definition = new TProviderDefinition();
@@ -111,8 +113,10 @@ namespace NzbDrone.Api
var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract);
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(providerResource.Fields, configContract, preset);
Validate(definition, includeWarnings);
if (validate)
{
Validate(definition, includeWarnings);
}
return definition;
}
@@ -133,7 +137,7 @@ namespace NzbDrone.Api
var providerResource = new TProviderResource();
providerResource.InjectFrom(providerDefinition);
providerResource.Fields = SchemaBuilder.ToSchema(providerDefinition.Settings);
providerResource.InfoLink = String.Format("https://github.com/NzbDrone/NzbDrone/wiki/Supported-{0}#{1}",
providerResource.InfoLink = string.Format("https://github.com/NzbDrone/NzbDrone/wiki/Supported-{0}#{1}",
typeof(TProviderResource).Name.Replace("Resource", "s"),
providerDefinition.Implementation.ToLower());
@@ -163,6 +167,19 @@ namespace NzbDrone.Api
return "{}";
}
private Response ConnectData(string stage, TProviderResource providerResource)
{
TProviderDefinition providerDefinition = GetDefinition(providerResource, true, false);
if (!providerDefinition.Enable) return "{}";
object data = _providerFactory.ConnectData(providerDefinition, stage, (IDictionary<string, object>) Request.Query.ToDictionary());
Response resp = JsonConvert.SerializeObject(data);
resp.ContentType = "application/json";
return resp;
}
protected virtual void Validate(TProviderDefinition definition, bool includeWarnings)
{
var validationResult = definition.Settings.Validate();

View File

@@ -14,15 +14,15 @@ namespace NzbDrone.Api.Queue
public SeriesResource Series { get; set; }
public EpisodeResource Episode { get; set; }
public QualityModel Quality { get; set; }
public Decimal Size { get; set; }
public String Title { get; set; }
public Decimal Sizeleft { get; set; }
public decimal Size { get; set; }
public string Title { get; set; }
public decimal Sizeleft { get; set; }
public TimeSpan? Timeleft { get; set; }
public DateTime? EstimatedCompletionTime { get; set; }
public String Status { get; set; }
public String TrackedDownloadStatus { get; set; }
public string Status { get; set; }
public string TrackedDownloadStatus { get; set; }
public List<TrackedDownloadStatusMessage> StatusMessages { get; set; }
public String DownloadId { get; set; }
public string DownloadId { get; set; }
public DownloadProtocol Protocol { get; set; }
}
}

View File

@@ -182,7 +182,7 @@ namespace NzbDrone.Api.REST
}
}
protected TResource ReadResourceFromRequest()
protected TResource ReadResourceFromRequest(bool skipValidate = false)
{
//TODO: handle when request is null
var resource = Request.Body.FromJson<TResource>();
@@ -194,7 +194,7 @@ namespace NzbDrone.Api.REST
var errors = SharedValidator.Validate(resource).Errors.ToList();
if (Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase) && !Request.Url.Path.EndsWith("/test", StringComparison.InvariantCultureIgnoreCase))
if (Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase) && !skipValidate && !Request.Url.Path.EndsWith("/test", StringComparison.InvariantCultureIgnoreCase))
{
errors.AddRange(PostValidator.Validate(resource).Errors);
}
@@ -214,11 +214,11 @@ namespace NzbDrone.Api.REST
private PagingResource<TResource> ReadPagingResourceFromRequest()
{
int pageSize;
Int32.TryParse(Request.Query.PageSize.ToString(), out pageSize);
int.TryParse(Request.Query.PageSize.ToString(), out pageSize);
if (pageSize == 0) pageSize = 10;
int page;
Int32.TryParse(Request.Query.Page.ToString(), out page);
int.TryParse(Request.Query.Page.ToString(), out page);
if (page == 0) page = 1;

View File

@@ -5,8 +5,8 @@ namespace NzbDrone.Api.RemotePathMappings
{
public class RemotePathMappingResource : RestResource
{
public String Host { get; set; }
public String RemotePath { get; set; }
public String LocalPath { get; set; }
public string Host { get; set; }
public string RemotePath { get; set; }
public string LocalPath { get; set; }
}
}

View File

@@ -33,7 +33,7 @@ namespace NzbDrone.Api.Restrictions
});
}
private RestrictionResource Get(Int32 id)
private RestrictionResource Get(int id)
{
return _restrictionService.Get(id).InjectTo<RestrictionResource>();
}
@@ -43,7 +43,7 @@ namespace NzbDrone.Api.Restrictions
return ToListResource(_restrictionService.All);
}
private Int32 Create(RestrictionResource resource)
private int Create(RestrictionResource resource)
{
return _restrictionService.Add(resource.InjectTo<Restriction>()).Id;
}
@@ -53,7 +53,7 @@ namespace NzbDrone.Api.Restrictions
_restrictionService.Update(resource.InjectTo<Restriction>());
}
private void Delete(Int32 id)
private void Delete(int id)
{
_restrictionService.Delete(id);
}

View File

@@ -6,14 +6,14 @@ namespace NzbDrone.Api.Restrictions
{
public class RestrictionResource : RestResource
{
public String Required { get; set; }
public String Preferred { get; set; }
public String Ignored { get; set; }
public HashSet<Int32> Tags { get; set; }
public string Required { get; set; }
public string Preferred { get; set; }
public string Ignored { get; set; }
public HashSet<int> Tags { get; set; }
public RestrictionResource()
{
Tags = new HashSet<Int32>();
Tags = new HashSet<int>();
}
}
}

View File

@@ -7,8 +7,8 @@ namespace NzbDrone.Api.RootFolders
{
public class RootFolderResource : RestResource
{
public String Path { get; set; }
public Int64? FreeSpace { get; set; }
public string Path { get; set; }
public long? FreeSpace { get; set; }
public List<UnmappedFolder> UnmappedFolders { get; set; }
}

View File

@@ -4,7 +4,7 @@ namespace NzbDrone.Api.Series
{
public class AlternateTitleResource
{
public String Title { get; set; }
public Int32 SeasonNumber { get; set; }
public string Title { get; set; }
public int SeasonNumber { get; set; }
}
}

View File

@@ -10,11 +10,11 @@ using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.SeriesStats;
using NzbDrone.Core.Tv;
using NzbDrone.Api.Validation;
using NzbDrone.Api.Mapping;
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
@@ -43,7 +43,8 @@ namespace NzbDrone.Api.Series
SeriesPathValidator seriesPathValidator,
SeriesExistsValidator seriesExistsValidator,
DroneFactoryValidator droneFactoryValidator,
SeriesAncestorValidator seriesAncestorValidator
SeriesAncestorValidator seriesAncestorValidator,
ProfileExistsValidator profileExistsValidator
)
: base(signalRBroadcaster)
{
@@ -59,7 +60,7 @@ namespace NzbDrone.Api.Series
UpdateResource = UpdateSeries;
DeleteResource = DeleteSeries;
SharedValidator.RuleFor(s => s.ProfileId).ValidId();
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
SharedValidator.RuleFor(s => s.Path)
.Cascade(CascadeMode.StopOnFirstFailure)
@@ -70,6 +71,8 @@ namespace NzbDrone.Api.Series
.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();

View File

@@ -14,11 +14,11 @@ namespace NzbDrone.Api.Series
//Todo: We should get the entire Profile instead of ID and Name separately
//View Only
public String Title { get; set; }
public string Title { get; set; }
public List<AlternateTitleResource> AlternateTitles { get; set; }
public String SortTitle { get; set; }
public string SortTitle { get; set; }
public Int32 SeasonCount
public int SeasonCount
{
get
{
@@ -28,45 +28,46 @@ namespace NzbDrone.Api.Series
}
}
public Int32? TotalEpisodeCount { get; set; }
public Int32? EpisodeCount { get; set; }
public Int32? EpisodeFileCount { get; set; }
public Int64? SizeOnDisk { get; set; }
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 ProfileName { get; set; }
public String Overview { get; set; }
public string ProfileName { 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 string Network { get; set; }
public string AirTime { get; set; }
public List<MediaCover> Images { get; set; }
public String RemotePoster { get; set; }
public string RemotePoster { get; set; }
public List<SeasonResource> Seasons { get; set; }
public Int32 Year { get; set; }
public int Year { get; set; }
//View & Edit
public String Path { get; set; }
public Int32 ProfileId { get; set; }
public string Path { get; set; }
public int ProfileId { get; set; }
//Editing Only
public Boolean SeasonFolder { get; set; }
public Boolean Monitored { get; set; }
public bool SeasonFolder { get; set; }
public bool Monitored { get; set; }
public Boolean UseSceneNumbering { get; set; }
public Int32 Runtime { get; set; }
public Int32 TvdbId { get; set; }
public Int32 TvRageId { 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<Int32> Tags { 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; }
@@ -74,7 +75,7 @@ namespace NzbDrone.Api.Series
//TODO: Add series statistics as a property of the series (instead of individual properties)
//Used to support legacy consumers
public Int32 QualityProfileId
public int QualityProfileId
{
get
{

View File

@@ -6,8 +6,8 @@ namespace NzbDrone.Api.System.Backup
{
public class BackupResource : RestResource
{
public String Name { get; set; }
public String Path { get; set; }
public string Name { get; set; }
public string Path { get; set; }
public BackupType Type { get; set; }
public DateTime Time { get; set; }
}

View File

@@ -5,9 +5,9 @@ namespace NzbDrone.Api.System.Tasks
{
public class TaskResource : RestResource
{
public String Name { get; set; }
public String TaskName { get; set; }
public Int32 Interval { get; set; }
public string Name { get; set; }
public string TaskName { get; set; }
public int Interval { get; set; }
public DateTime LastExecution { get; set; }
public DateTime NextExecution { get; set; }
}

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