1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-03-05 13:20:20 -05:00

Compare commits

...

798 Commits

Author SHA1 Message Date
Taloth Saldono
94f8e38d5a Implemented experimental Script Console for debugging with editor in the diag ui. 2020-06-07 00:14:08 +02:00
Taloth Saldono
031371652b Used ReflectionOnly and/or public types where possible to avoid loading related assemblies unnecessarily. 2020-06-06 23:12:31 +02:00
Taloth Saldono
02104aff34 jsconfig for a bit of autocompletion and intellisense 2020-06-06 23:12:31 +02:00
Taloth Saldono
5bd1c47ca7 Revised webpack bundling and updated worker loading, turned inline worker on by default. 2020-06-06 23:12:31 +02:00
Taloth Saldono
f846e0c031 Fixed flaky test. 2020-06-06 22:28:08 +02:00
Taloth Saldono
72b0f640f4 Added Plex url to cleanser 2020-06-06 22:28:08 +02:00
Mark McDowall
430af0401c New: Use release quality source if not in downloaded file and resolution matches 2020-06-06 10:47:00 -07:00
Mark McDowall
0ff08dbe8d Fixed: Error when processing release with files Sonarr is unable to parse 2020-06-06 10:19:59 -07:00
Taloth Saldono
57cca9fcdc Fixed typo in Cleanse IP 2020-06-03 18:33:00 +02:00
Taloth Saldono
b3daa280c5 Cleanse remote IP Address from trace log file 2020-06-02 20:58:13 +02:00
Taloth Saldono
449c1caf55 Fixed: Mono not validating cross-signed certficates properly 2020-06-02 20:57:20 +02:00
Taloth Saldono
0c05236bee Support for Runtime Patches via Harmony 2020-06-02 20:57:20 +02:00
Mark McDowall
9f54ff8169 Fixed: Interactive search for anime season even if all episodes are unmonitored
Fixes #3791
2020-06-01 21:33:53 -07:00
Taloth Saldono
f2e1b4e435 Log contents on api errors during tests. 2020-06-01 15:01:40 +02:00
Taloth Saldono
1e80361c3a Fixed tests and missing logger initialization 2020-06-01 14:01:09 +02:00
Taloth Saldono
3564be19a8 Fixed typo 2020-06-01 00:26:09 +02:00
Mark McDowall
14c9b6aaf4 Additional logging when trying to complete tracked downloads 2020-05-30 16:40:41 -07:00
Mark McDowall
069fc5cd33 Mass Editor size and options
New: Option to show size in Mass Editor
New: Size on Disk in Mass Editor custom filters

Closes #3273
2020-05-30 13:56:28 -07:00
Mark McDowall
3586d7042b Fixed: Auto-focusing Filter series import during import series 2020-05-30 11:04:13 -07:00
Mark McDowall
a32b6276bd Fixed: Deleting row from middle of filter builder leading to error 2020-05-30 10:46:42 -07:00
Mark McDowall
b0e31629b5 Fixed: Not removing seeded download if it was manual imported in some cases 2020-05-30 10:18:17 -07:00
Mark McDowall
e2644c3847 Fixed manual import possible null series 2020-05-30 10:12:24 -07:00
Mark McDowall
7ea45bb714 Fix some styling issues in Quality Profile and Release Profiles 2020-05-30 10:11:34 -07:00
Mark McDowall
f524fcd3e4 Fixed: Skip missing episode title check if file is already in series folder 2020-05-30 10:09:46 -07:00
Mark McDowall
6c418302f8 Fixed: Episode file renamed event stored language properly
Closes #3783
2020-05-27 23:52:37 -07:00
Mark McDowall
b28d329654 Fixed: Size on disk with seasons over 100
Fixes #3774
2020-05-24 23:39:57 -07:00
Mark McDowall
ebe2ad1520 New: Show size on disk for each season
Closes #3432
2020-05-24 14:38:37 -07:00
Mark McDowall
41dfb677e7 Fixed: Rejections custom filter for Interactive Search (now Rejections Count) 2020-05-24 14:02:30 -07:00
Mark McDowall
c646bef369 Calendar item/episode status fixes
New: Calendar shows icon when download is complete and not yet imported
New: Episode status shows pending import and importing icon
2020-05-24 13:32:33 -07:00
Mark McDowall
910de6d94a Queue status/timeleft improvements
New: Queue status icon is purple when download is waiting to import or importing
Fixed: Timeleft on Queue won't show when completed
Closes #3743
2020-05-24 13:30:33 -07:00
Mark McDowall
5951992bd5 Fixed: Preferred words remove button in Firefox
Fixes #3710
2020-05-24 12:06:35 -07:00
Mark McDowall
cb9d78064a Fixed: Width of episode column with warning
Closes #3733
2020-05-24 11:39:50 -07:00
Mark McDowall
fd608fd411 New: Don't close manual import when clicking outside the modal
Closes #3761
2020-05-24 10:38:30 -07:00
Mark McDowall
d3bd90e4b9 Fixed: Manual import for unknown series items will properly mark as imported 2020-05-24 10:11:10 -07:00
Mark McDowall
4988655568 Store language with deleted episode history 2020-05-24 10:10:24 -07:00
ildoc
098db08ede updated readme 2020-05-21 10:58:35 +02:00
Skyler Mäntysaari
93e3e92bba New: SendGrid Notifications
Closes #3341
2020-05-20 11:22:05 -07:00
Taloth Saldono
bdfdd28d6a Fixed: Added .org to website url filtering in parser 2020-05-19 23:01:21 +02:00
Taloth Saldono
a75e10c4c9 Fixed: Parsing anime dual language titles
closes #3756
2020-05-18 01:33:03 +02:00
Taloth Saldono
5251db7224 Fixed recursion issue when emptying recycle bin 2020-05-16 19:22:47 +02:00
Taloth Saldono
4d1a4d4241 Updated kodi url 2020-05-13 21:29:21 +02:00
Taloth Saldono
d3a22459ac Fixed: Performance issue when scanning large root folder 2020-05-13 21:27:39 +02:00
Qstick
4f7e00bdc4 Fixed: Don't lock command queue if updating is disabled 2020-05-13 19:33:14 +02:00
Mark McDowall
1199ae4e4f New: Use filename for preferred word score if it's higher than scene name 2020-05-09 16:45:42 -07:00
Mark McDowall
36088ef49d Fixed: Tag details list series in alphabetical order 2020-05-09 16:45:42 -07:00
Taloth Saldono
7ffb2eb440 Replaced matchAll usage since it's not available on all browsers 2020-05-06 14:33:14 +02:00
Taloth Saldono
0716d0931a Added UserAgent to api request trace log 2020-05-05 20:14:07 +02:00
Taloth Saldono
66ee28d0a9 Lock CommandQueueManager.PushMany too 2020-05-03 18:48:20 +02:00
Taloth Saldono
1487f54749 Skip unknown/removed commands still queued in the database 2020-05-03 17:29:46 +02:00
Taloth Saldono
013c46d266 Fixed timing issue allowing multiple instances of the same command to be queued 2020-05-03 17:29:46 +02:00
Taloth Saldono
c8d2fcb223 Added UpdateMechanismMessage to allow package maintainers provide custom message 2020-05-03 17:29:46 +02:00
Taloth Saldono
5288b61378 Inline markdown-style link for PackageAuthor 2020-05-03 17:28:38 +02:00
Taloth Saldono
a2679f64ee Parse WEB at the end of release title. 2020-05-03 17:00:11 +02:00
Mark McDowall
5d9dfee3c0 New: Add DownloadClient and DownloadId to Webhook notifications 2020-05-02 21:02:11 -07:00
Mark McDowall
98f9323b42 Fixed: Root folder custom filter in Mass Editor 2020-05-02 21:02:11 -07:00
Taloth Saldono
f282ae8aae Prevent exception parsing unicode digits in absolute numbers. 2020-05-02 14:21:58 +02:00
Mark McDowall
0b1e99991e Fixed: Imports triggered through API not being marked as imported/removed from client
Fixes #3717
2020-04-29 00:08:01 -07:00
Mark McDowall
75be036a87 Fixed: Imported downloads not being removed when seeding goals are met
Fixes #3693
2020-04-28 21:37:26 -07:00
Taloth Saldono
23dc7794f1 Fixed: Generating Kodi episode metadata files when scanning series folder 2020-04-28 23:34:52 +02:00
Taloth Saldono
b8e2f3d716 Clarify that Post-Import Category torrents are not monitored by Sonarr.
Configure Deluge to remove such torrents when seeding criteria has been met.

closes #3659
2020-04-28 22:10:30 +02:00
Taloth Saldono
686a14cdff Log Real IP on Authentication failure in case of a reverse proxy
closes #3711
2020-04-27 23:58:35 +02:00
Taloth Saldono
b4405b0600 Fixed: Parsing release group from file rather than folder in case of season packs 2020-04-27 19:09:49 +02:00
Qstick
d4bcf28d08 Add missing "does" to DifferentQualitySpec message 2020-04-26 13:28:38 -07:00
rg9400
4bacc35605 Fixed: Indicate unchecking Replace Illegal Characters will remove them 2020-04-26 12:54:18 -07:00
Mark McDowall
417340c2c6 Fixed: Manual imports of multi-episode files being treated as fully imported 2020-04-25 14:13:29 -07:00
Mark McDowall
79d8a9d44b Fixed: Episodes removed from queue re-appearing on refresh
Fixes #3697
2020-04-25 14:12:38 -07:00
Mark McDowall
68440bba4d Fixed: Rejection message for quality mismatch 2020-04-25 14:09:57 -07:00
Mark McDowall
0719c83da4 Fixed: Parsing of some anime batch releases
Fixes #3698
2020-04-25 13:33:30 -07:00
Mark McDowall
5a7dec34cc Fixed: Rotating mobile device when modal is open won't reset modal
Closes #3333
2020-04-25 11:59:29 -07:00
Mark McDowall
9d766cfed5 Fixed: Remove seeded downloads if they've finished seeding after import
Fixes #3693
2020-04-25 11:49:18 -07:00
Mark McDowall
1498f4e361 Revert: Prevent an edge case where a download is not marked as complete 2020-04-21 10:27:27 -07:00
Taloth Saldono
05dd17aacb Added support for title query parameter to newznab/torznab, receiving raw series title 2020-04-21 18:44:08 +02:00
Taloth Saldono
200aee52f7 New: Searching for episodes with season level scene mapping now possible instead of only via RssSync (Newznab/Torznab only) 2020-04-21 18:44:08 +02:00
Mark McDowall
d6dd13a6be Prevent an edge case where a download is not marked as complete 2020-04-20 18:09:24 -07:00
Mark McDowall
be3b3df903 Don't reject for having the same file size
Fixed: Remove same file size rejection during import
Fixed: Reject imports for non-season pack files if quality of file doesn't match grabbed quality
Closes #3691
2020-04-20 17:58:59 -07:00
Mark McDowall
f2a56b29d9 Fixed: Windows installer won't create shortcut if unchecked 2020-04-20 17:57:09 -07:00
Mark McDowall
27d98868b8 Fixed: Can ignore queue items with unknown episodes 2020-04-20 17:56:36 -07:00
Mark McDowall
7f28ab895a Small change to creating an itemMap during item update 2020-04-20 17:56:22 -07:00
Mark McDowall
97ec184754 Fixed: Import series failing to add items to process 2020-04-20 09:35:35 -07:00
Mark McDowall
42343d5283 Add class to allow for overriding scrollbar width 2020-04-18 20:21:46 -07:00
Mark McDowall
479baf06a7 Fixed: Removed items in queue still showing until refresh 2020-04-18 20:21:29 -07:00
Mark McDowall
7f7d196e44 Fixed: Don't process downloads removed from the client
Fixes #3557
2020-04-18 20:21:29 -07:00
Mark McDowall
c862fd9ff6 Don't re-trigger completed event 2020-04-18 20:21:29 -07:00
Mark McDowall
770b89c2b3 Track fully imported downloads in separate history table
New: Improved detection of already imported downloads
Closes #3554
2020-04-18 20:21:29 -07:00
Taloth Saldono
576275b6da Another mono 6.x workaround to use rename rather than expensive copy 2020-04-18 11:08:47 +02:00
Taloth Saldono
776191b3bd Improved error message when nzb download contains an newznab error instead 2020-04-17 00:14:05 +02:00
Mark McDowall
d369d85699 Fixed: Ended overlay on series posters 2020-04-15 09:14:05 -07:00
Mark McDowall
552fac0466 More strict ExcludedSubFoldersRegex 2020-04-15 09:13:26 -07:00
Mark McDowall
a348d98dd9 Fixed: Filter direct excluded subfolders of the selected directory during manual import 2020-04-13 21:30:40 -07:00
Mark McDowall
ccdfdd1049 Fix checkingUP qbit status unit test 2020-04-12 12:31:17 -07:00
Mark McDowall
f0ca636654 Fixed sort in HistoryRepository 2020-04-09 22:58:42 -07:00
Mark McDowall
b5e734b9e5 Fixed: Ignore .@__thumb folders 2020-04-09 22:58:24 -07:00
Mark McDowall
e1639d35a2 Fixed: Series toolbar button collapsing 2020-04-09 22:58:08 -07:00
Mark McDowall
9b99ad27cd Fixed: Tooltip for existing series on add new series item 2020-04-09 22:57:39 -07:00
Mark McDowall
bba57bb434 Fixed: Queue not always clearing checked items when updated 2020-04-03 08:44:58 -07:00
Mark McDowall
8c24cd9864 Fixed: Strip AlteZachen from release group name 2020-04-02 17:27:16 -07:00
Mark McDowall
91de7ff11c Fixed: Don't try to render quality when it's null
Fixes #3649
2020-04-02 17:24:18 -07:00
Mark McDowall
9702d2e5ad Fixed: Treated checkingUP status from Qbit as queued in case it fails to validate 2020-04-02 17:23:25 -07:00
Anthony Borushko
638066db03 Fixed: Tag inputs respect non-QWERTY layouts 2020-03-31 09:57:27 -07:00
Jef LeCompte
1b3839ac0d Updated README 2020-03-31 09:21:52 -07:00
Mark McDowall
219494ea9d Fixed: Preferred word can't have a term that is empty or only spaces 2020-03-29 14:54:14 -07:00
Mark McDowall
642f75761f GetBestRootFolderPathFixture OS Agnostic paths 2020-03-28 12:43:05 -07:00
Mark McDowall
ed28f94f02 Improve root folder health check 2020-03-27 15:24:20 -07:00
Mark McDowall
618c611a59 Fixed: Series Network filter breaking if network was not available 2020-03-22 22:50:18 -07:00
Mark McDowall
00821b7ad6 New: Parse multi-part episodes using date
Closes #381
2020-03-22 22:44:14 -07:00
Mark McDowall
84b9488cfb Fix broken test 2020-03-22 10:45:54 -07:00
Taloth Saldono
37ad801065 Fixed: Audio Channel Information missing in MediaInfo for certain mkv files with DTS audio 2020-03-22 12:02:51 +01:00
Taloth Saldono
4219cdb364 Fixed: RemotePoster on v3 api provides local url rather than thetvdb url 2020-03-22 12:02:51 +01:00
Mark McDowall
e23a879669 Fixed: Cutoff unmet searches rejecting releases incorrectly 2020-03-20 17:34:18 -07:00
Mark McDowall
4ddf4a22a3 Fixed: Enter on Delete profile confirmation deleting all unused profiles 2020-03-20 08:37:35 -07:00
Mark McDowall
72afb28c30 Revert failing parsing tests 2020-03-19 11:11:37 -07:00
Mark McDowall
eb51a42f60 Fixed: Sorting queue by episode properties when not all items have an episode 2020-03-19 10:11:07 -07:00
Mark McDowall
bc01384cc7 Actually fixed error rending queue row when quality is missing 2020-03-19 10:10:36 -07:00
Mark McDowall
00c922875f Fixed: Multiple series found during manual import prevents manual importing from folder
Fixes #3512
2020-03-18 19:30:02 -07:00
Mark McDowall
8c93d73b42 Fixed: Error rending queue row when quality is missing
Fixes #3614
2020-03-18 19:09:07 -07:00
Mark McDowall
3b6d60e904 New: RSS Sync button on Calendar
Closes #3326
2020-03-18 19:08:58 -07:00
Mark McDowall
a965b8e7b2 New: Filter episodes in API v3 by episode file ID
Closes #3589
2020-03-18 19:08:51 -07:00
Taloth Saldono
25abf52b3f Added update check early in startup if the package requested a post-install update check 2020-03-16 19:18:41 +01:00
Taloth Saldono
19764014be Increased mono dependency from 5.4 to 5.18 for debian
# Conflicts:
#	docker/tests/run-all.sh
2020-03-16 19:18:41 +01:00
Taloth Saldono
c91a5c80d3 Added .NET Framework 4.7.2 requirement check to windows installer 2020-03-16 19:18:41 +01:00
Taloth Saldono
e7b88c313d Fixed: Workaround for mono 6.x file copy/move issues 2020-03-16 19:18:41 +01:00
Taloth Saldono
9ac0864b61 Fixed scrolling issue in Root Path selector dropdown on mobile 2020-03-14 22:08:51 +01:00
Taloth Saldono
fcdd0f21c7 Fixed: Wrongly parsing language in series title for season packs (episodes were already handled) 2020-03-13 20:18:37 +01:00
Taloth Saldono
5497b68a98 Fixed: Don't auto-search newly added episodes on tvdb that aired more than 2 weeks ago
Fixed: Don't monitor newly added old episodes on tvdb if series was previously empty
2020-03-13 00:33:35 +01:00
Mark McDowall
50886ac928 More webook series properties
New: IMDB and TvMaze IDs in Webhooks
New: Series type in Webhooks
2020-03-10 23:58:34 -07:00
Mark McDowall
e2ff089232 Fixed: Metadata files not being created after rescan 2020-03-10 23:57:41 -07:00
Mark McDowall
ae7f8926f8 New: Ignore #recycle folders (Synology Recycle bin folder) 2020-03-10 23:56:09 -07:00
Mark McDowall
0bbc4e8c1b Fixed: Remove website post fix before parsing 2020-03-08 11:14:21 -07:00
Mark McDowall
295fdad750 Fixed: Broken tasks getting stuck in queue 2020-03-05 17:57:20 -08:00
Mark McDowall
63e01aff8c Fixed: Not importing upgrade for preferred language
Fixes #3605
2020-03-05 17:57:20 -08:00
unknown
e05ceb226c Update help text in Connections from Download to Import 2020-03-05 09:14:46 -08:00
Mark McDowall
1c699841c1 Fixed: Handle qBit ForcedDL State
Closes #3604
2020-03-05 09:13:44 -08:00
Mark McDowall
385c7fb0ce Fixed: Error occurred while executing task ProcessMonitoredDownloads 2020-03-03 18:10:29 -08:00
Mark McDowall
15d84046db Fixed: Inaccessible path leading to import process being aborted before processing all items
Fixes #3598
2020-03-03 16:54:12 -08:00
Mark McDowall
3ad396a9c2 Fixed: Re-add background to apple-touch-icon
This reverts commit afcfaace19.
2020-03-03 08:58:53 -08:00
Mark McDowall
77f886ceef OverlayScroller still needs to be used in PageContentBody 2020-03-02 14:06:36 -08:00
Taloth Saldono
8adb788205 Linting 2020-03-02 22:49:46 +01:00
Taloth Saldono
d731317c81 Fixed comment typo in webpack config 2020-03-02 22:48:44 +01:00
Mark McDowall
a824ce691b Fixed: Preferred is not an indexer field
Fixes #3595
2020-03-02 08:29:46 -08:00
Mark McDowall
506023b0f3 Scrolling and hotkey improvements
New: Use Esc/Enter for cancel/accept in confirmation modals
Fixed: Modals focused when opened
Fixed: Scrolling with keyboard unless focus is shifted out of scrollable area
Closes #3291
2020-03-01 21:03:59 -08:00
Taloth Saldono
52e5d4d0f1 Linting error 2020-03-01 22:26:49 +01:00
Taloth Saldono
00edffc0f4 Fixed random typo 2020-03-01 22:16:00 +01:00
Taloth Saldono
92f1f3e73a New: Added mediainfo formatting for E-AC3 Atmos 2020-03-01 22:16:00 +01:00
Taloth Saldono
1d339ad4f1 Belated removal of bitmetv and cleanup of usenet-crawler. 2020-03-01 22:16:00 +01:00
Jacob
99728a604d New: Added option to filter Release Profile to a specific indexer 2020-03-01 22:15:59 +01:00
netpok
c07a67ae3c New: Added aired-before field to kodi metadata to sort specials
closes #3073
2020-03-01 22:15:58 +01:00
Mark McDowall
be11789a86 New: Clone indexer button
Closes #3546
2020-03-01 12:56:58 -08:00
Mark McDowall
b8ce274fa5 Manual Import Sorting
Fixed: Manual Import sorting by quality
New: Manual Import sort by size
Closes #3334
2020-03-01 11:51:27 -08:00
Mark McDowall
d7967e3e1b Fix hasDifferentItems 2020-02-28 11:15:01 -08:00
ta264
746da69070 Fixed: UI slowdowns while tasks are running
Fixes #3480
2020-02-26 17:57:21 -08:00
ta264
b05b7ec4ad Trigger fewer signalr broadcasts 2020-02-26 17:57:21 -08:00
ta264
9abdaca079 New: Faster processing of special releases 2020-02-26 17:57:21 -08:00
ta264
5a79b8502e New: Improved Series list performance 2020-02-26 17:57:21 -08:00
ta264
466d4fba9e Don't rerender all cells each scroll 2020-02-26 17:57:21 -08:00
ta264
108f6fe393 Better selection of jump bar items
Show first, last and most common items
2020-02-26 17:57:21 -08:00
ta264
792896c46b New: Faster searching of existing series 2020-02-26 17:57:21 -08:00
ta264
43d04cd54e Faster series selector 2020-02-26 17:57:21 -08:00
ta264
283f905d79 Don't mutate state when sorting items 2020-02-26 17:57:21 -08:00
ta264
dd8d1b673e Faster hasDifferentItems and specialized OrOrder version 2020-02-26 17:57:21 -08:00
ta264
9ef64660ce Option for production build with profiling 2020-02-26 17:57:21 -08:00
Mark McDowall
88b1c8fc3e Fixed: Moving series folders in subfolders of the root folder when destination subfolder was missing 2020-02-26 17:45:13 -08:00
Mark McDowall
bcc8b655f7 Fixed: Re-processing imported download causing task to fail
Fixes #3501
2020-02-19 19:09:55 -08:00
Mark McDowall
438d9eb717 Fixed: Prompt to restart after resetting API key
Fixes #3580
2020-02-19 18:18:47 -08:00
Mark McDowall
2c0a0175ef Fixed: Sorting by episode count
Fixes #3531
2020-02-19 18:03:58 -08:00
Mark McDowall
e51f1b5e16 Fixed: Parsing of 360p releases
Fixes #3519
2020-02-19 17:38:17 -08:00
Mark McDowall
544108df37 Fixed: Import series when no results are returned from for a folder 2020-02-19 17:21:55 -08:00
beyondmeat
a23639e62e Fixed: Empty list message for System: Events 2020-02-19 17:19:18 -08:00
Taloth Saldono
cde5a6d1a4 Fixed stylelint errors 2020-02-11 21:41:16 +01:00
Taloth Saldono
b601c8bcfe New: Added advanced subtitle/audio language filter to {MediaInfo ..}
closes #3367
2020-02-11 21:13:13 +01:00
Taloth Saldono
023c8260f2 Added Norwegian Bokmal alias 2020-02-11 20:14:10 +01:00
Taloth Saldono
51e2e084af Added try-catch for DateTime.TryParse edgecase
closes #3518
2020-02-09 17:05:45 +01:00
Taloth Saldono
fc5dd8137f Support for VS2019 build environment 2020-02-07 21:16:53 +01:00
Taloth Saldono
268fc46ef7 Fixed: Representation of episode start time when not starting at the full hour in am/pm notation 2020-02-01 22:50:16 +01:00
Mark McDowall
010c65af9c Fixed: Don't monitor new seasons if series is not monitored
Fixes #3547
2020-02-01 13:03:11 -08:00
Mark McDowall
db42256dc3 Improve default series type handling (for daily series)
New: Display default series type when adding new/existing series when available
Fixed: Don't override series type on series refresh
2020-01-31 17:51:30 -08:00
Mark McDowall
e9b537b6e6 Fixed: Rejecting import for a release that was grabbed again 2020-01-31 17:51:30 -08:00
Mark McDowall
c615ef476a Fixed: Typo in unmonitored series tooltip
Fixes #3538
2020-01-31 17:51:30 -08:00
Mark McDowall
b93e8da235 Fixed: Force grabbing selected delayed items in queue 2020-01-31 17:51:30 -08:00
Pika
74a0a57468 BTN: Fix name 2020-01-19 18:40:06 +01:00
Петр Шургалин
b19d665817 Fixed: RestClient does not use global proxy settings 2020-01-19 16:41:31 +01:00
Taloth Saldono
10dc884fa8 Fixed: Posters not always showing when searching for new shows 2020-01-12 22:27:56 +01:00
Taloth Saldono
d8446c2d5a New: Added tvdb Upcoming series status 2020-01-12 22:27:55 +01:00
Mark McDowall
d3cd46bb51 New: Limit recent folders in Manual import to 10 and descending order
Closes #3491
2020-01-07 17:36:57 -08:00
Mark McDowall
bc0da03caf Fix proptype warning for id of EnhancedSelectInputOption 2020-01-07 17:11:45 -08:00
Mark McDowall
c0a356261b New: Added help text for qualities in groups
Closes #3495
2020-01-07 17:00:12 -08:00
Mark McDowall
fa4060b7fe Fixed: Previously imported downloads reappear in queue
Fixes #3496
2020-01-07 16:55:13 -08:00
Taloth Saldono
29117fc222 Fixed missing interface for the CheckForFinishedDownloadCommand backward compat handling
fixes #3492
2020-01-05 14:37:52 +01:00
julakali
24ba5e5bda Use msbuild instead of the deprecated xbuild 2020-01-04 17:54:25 -08:00
gl3nni3
2d94857369 Fixed: Replace duplicate slashes from file names when importing
Fixes #3470
2020-01-04 17:52:45 -08:00
Mark McDowall
c6ea7d7e63 Option to ignore items when removing from queue instead of removing from client
New: Option to not remove item from download client when removing from queue

Closes #1710
2020-01-04 17:49:39 -08:00
Mark McDowall
3916495329 Monitor and Process downloads separately
New: Queue remains up to date while importing file from remote file system
Fixed: Failed downloads still in queue won't result in failed search

Closes #668
Closes #907
Fixes #2973
2020-01-04 17:49:39 -08:00
Mark McDowall
4e965e59a9 Fixed: Parsing of Extended Multi-episode format file names 2019-12-30 09:27:24 -08:00
Taloth Saldono
0acb3aa32b Fixed: Regression in Multi-Episode format parser in previous release
fixes #3481
2019-12-30 13:06:25 +01:00
Mark McDowall
9189d8bf4d Fixed: Parsing of poorly named double episode releases
Fixes #3439
2019-12-29 02:32:30 -08:00
Mark McDowall
ec0c96bde4 Remove website prefixes with dashes in URL 2019-12-29 02:32:30 -08:00
Mark McDowall
562c8c4afe Fixed: Improved quality parsing from truncated release names
Closes #3345
2019-12-29 02:32:30 -08:00
Mark McDowall
fd6d4493c4 Fixed: Details for episode history flashing on mobile devices 2019-12-29 02:32:30 -08:00
Jayden
1a2419e096 Fix typo in remove queue item modal 2019-12-29 01:49:49 -08:00
Taloth Saldono
b86cfd49ef Fixed redirect test 2019-12-24 11:52:26 +01:00
Taloth Saldono
d421ff9736 Increased max redirects from 3 to 5
closes #3449
2019-12-24 11:27:58 +01:00
Taloth Saldono
92c61701f2 Fixed: Imports of multi-episode files did not trigger the download completion event and thus apply the PostImport category for supported download clients
fixes #3403
2019-12-24 11:27:58 +01:00
Wu Haotian
d45d9e356c New: Improve Chinese language detection 2019-12-24 11:26:30 +01:00
Fossil
098f9a2675 Remove PFMonkey.com from Presets
Indexer closed in 2018
2019-12-24 11:06:58 +01:00
Fossil
0347dab82e Add new X265 category to NZB Finder 2019-12-24 11:06:58 +01:00
Taloth Saldono
9aa89a0df9 Fixed: Inserting literal { or } in renaming format using {{ or }}
fixes #3434
2019-12-24 10:58:47 +01:00
Taloth Saldono
556bd11725 Disable pooling rather than clearing it 2019-12-18 23:09:10 +01:00
Taloth Saldono
07f5c21a07 Clear the connection pool in the backdoor migration to prevent occasional conflicts with following migrations 2019-12-18 20:39:31 +01:00
Taloth Saldono
93b20960b8 Fixed regex in Backup list 2019-12-08 11:00:56 +01:00
Taloth Saldono
3cbdd6bfd3 Fixed: Rare scenario where early Radarr version messes up Sonarr database 2019-12-07 21:56:44 +01:00
Mark McDowall
c3c38880e6 Fixed: Test All not clearing health error
Fixes #3409
2019-12-06 17:42:40 -08:00
Mark McDowall
415bbf5b3b Fixed: Update deleted series health after refreshing series 2019-12-06 17:42:40 -08:00
Taloth Saldono
186cb02748 Added NUnit3TestAdapter nuget so it can work without VS extension 2019-12-06 19:49:27 +01:00
Taloth Saldono
4aaccb909f Cleanse getnzb url 2019-12-06 19:49:27 +01:00
Jef LeCompte
2daf7dd01a Fixed: Handle qBittorrent "moving" state 2019-12-04 09:02:39 -08:00
Taloth Saldono
ab9ed73e55 New: Added version number to backup filename 2019-11-28 21:23:48 +01:00
Mark McDowall
a4a33fe167 Fixed: Letter jump bar on series list not working correctly with banners 2019-11-26 17:41:40 -08:00
Mark McDowall
e6fbd10031 Improved some log messages 2019-11-26 17:41:40 -08:00
Mark McDowall
9868d96fec Fixed: Delete files from Series Mass Editor not actually deleting files 2019-11-26 17:41:40 -08:00
Mark McDowall
0d1c2ac40c Fixed react error when displaying a series search result for an existing series 2019-11-26 17:41:40 -08:00
Mark McDowall
a6d0dddaf7 Fixed: Trying to add a series when root folders hadn't populated
Fixed #3387
2019-11-26 17:41:40 -08:00
Taloth Saldono
06d57e8f32 Fixed: Refresh Deleted & Upcoming shows as frequently as Continuing ones 2019-11-24 23:47:22 +01:00
Taloth Saldono
70a40edc5d Tiny fix in test, left-over from my on-windows test. 2019-11-19 21:55:48 +01:00
Taloth Saldono
95d64208d0 Fixed: File imports on cloud drives slow due to transaction logic 2019-11-19 17:35:19 +01:00
Taloth Saldono
e28b2e8328 Fixed: Corrupt image files when downloading from redirecting Url
closes #3401
2019-11-15 18:39:31 +01:00
Mark McDowall
4123745a6b Fixed: Interactive search results failing to show when processing failed
Closes #3377
2019-11-08 09:12:42 -08:00
Mark McDowall
70bb4d71e6 Fixed: Parsing of poor standard file names using dashes for separators 2019-11-03 09:26:39 -08:00
Mark McDowall
dd314e1741 Fixed: Deletion of empty episode sub folders when an episode file is deleted 2019-11-03 09:04:39 -08:00
Mark McDowall
3cbb489ac6 Default id for MenuContent 2019-10-30 10:25:55 -07:00
Mark McDowall
101df4cbf1 Ensure Season Folder Format will correctly replace illegal characters 2019-10-30 09:41:40 -07:00
Mark McDowall
42263a0ec0 Fixed: Set Default Sort Key for Blacklist Endpoint 2019-10-30 09:41:13 -07:00
Mark McDowall
d402f7514e Fixed: Manual Import failing to show files when processing fails 2019-10-28 12:50:09 -07:00
Mark McDowall
84e6674e23 Fixed: Actually run Recycle Bin cleanup 2019-10-28 12:50:09 -07:00
Mark McDowall
afcfaace19 Fixed: Remove background from apple-touch-icon 2019-10-28 12:50:09 -07:00
Mark McDowall
5a3bd8cfe5 Fixed: Set permissions on extra and subtitle files 2019-10-28 12:50:09 -07:00
Mark McDowall
f0c90a4744 Fixed: Log matching scene mapping for title 2019-10-28 12:50:09 -07:00
Mark McDowall
3baed292e1 Fixed: Allow Interactive Season Search when all episodes are unmonitored 2019-10-28 12:50:09 -07:00
Mark McDowall
d41a2cad73 Fixed: Include releases that failed to parse in search results 2019-10-28 12:50:09 -07:00
Mark McDowall
ffccc3be38 Fixed: Kodi episode metadata missing uniqueid
Fixes #3308
2019-10-28 12:50:09 -07:00
Mark McDowall
ef1e8d7ef3 Fixed: Don't parse packs missing season number 2019-10-28 12:50:09 -07:00
Taloth Saldono
7af891216d Another failing test 2019-10-20 22:11:10 +02:00
Taloth Saldono
aa80500b35 Missing test on EventDrivenHealthCheck 2019-10-20 21:51:12 +02:00
Taloth Saldono
b72fbe06f7 Adding missing series Deleted UI elements 2019-10-20 21:38:15 +02:00
Taloth Saldono
41a63a5418 Fixed test failing due to rng 2019-10-20 20:58:12 +02:00
Taloth Saldono
e8ce7898c1 use TestContext.Progress rather than Console.WriteLine for NzbDroneRunner output 2019-10-20 20:22:28 +02:00
Taloth Saldono
687a45c564 Added docker to run tests on various mono versions 2019-10-20 20:21:22 +02:00
ta264
3ac3dd3ca5 New: Swap to ImageSharp library for resizing posters 2019-10-20 20:21:22 +02:00
Qstick
f2efebf7d9 New: Option to send notification when a Health Check warning occurs
closes #3253
2019-10-19 17:32:08 +02:00
ta264
7b68ce49d5 Fix .gitattributes and normalize to LF in repository
Existing `*text eol=lf` is malformed (no space after *) so does
nothing.

CONTRIBUTING.md states 'We checkout Windows and commit *nix'.  The
correct way to achieve this is `* text=auto`. `* text eol=lf` would
force line endings to LF on checkout.

See:
https://git-scm.com/docs/gitattributes#Documentation/gitattributes.txt-Settostringvaluelf
2019-10-19 17:16:45 +02:00
Taloth Saldono
8a2a41fab0 New: Added health check warning to emphasis when a series was deleted instead of only logging it in System Events 2019-10-19 17:15:38 +02:00
Taloth Saldono
ceaaec5378 New: Parsing Saison season packs as alternative to Season
Just because we're in a good mood
2019-10-18 21:00:51 +02:00
sirloinofbeef
e49a3e7206 Updated XBMC notification strings to Kodi 2019-09-17 11:50:44 -07:00
Taloth Saldono
dc7986dbad Fixed regression in container registration. Additional logging in case of integration test startup failures 2019-09-13 17:11:20 +02:00
Taloth Saldono
2dfba130f5 Split up _tests into windows and linux 2019-09-13 12:29:31 +02:00
Taloth Saldono
155c7c409b Moved Platform version determination to static 2019-09-13 12:26:27 +02:00
Taloth Saldono
aacb8970f8 Fixed several failing/flaky mono unit tests 2019-09-13 11:41:18 +02:00
ta264
be66a0520d Fix integration tests on linux with debug build 2019-09-12 18:39:07 +02:00
Rhys Braunschweig
3fa3c45794 Add digits to Deluge's category validator 2019-09-09 22:59:50 +02:00
ta264
0f6da1873e Update unity 2019-09-09 22:59:01 +02:00
Taloth Saldono
1564208e83 Fixed tests 2019-09-07 15:07:06 +02:00
Taloth Saldono
e724e8db60 Fixed: Copy linux permission mask when moving folder to recycle bin folder
fixes #3161
2019-09-07 12:13:22 +02:00
Taloth Saldono
5a092a83cd Fixed: Disregard Real when user disabled proper preference 2019-09-07 12:12:57 +02:00
Taloth Saldono
ffefe5e8aa And a bunch of video codecs. Also fixed the dual-video channel issue. 2019-09-05 00:32:18 +02:00
Taloth Saldono
631fdd8a26 New: Additional Atmos detection in MediaInfo
ref Radarr/Radarr#3712
2019-09-04 23:26:17 +02:00
Taloth Saldono
53d7ef4014 Fixed third-party clients calling api without Accept header 2019-09-01 15:58:01 +02:00
Taloth Saldono
5c3ac79043 Removed obsolete code. 2019-09-01 11:28:07 +02:00
ta264
90fb1646e0 Updated Nancy to 2.0 2019-09-01 11:20:08 +02:00
ta264
54604e45e0 Emacs gitignore 2019-08-31 22:23:39 +02:00
Taloth Saldono
9ed0f9eee8 Fixed DownloadFile when file already exists 2019-08-31 21:35:01 +02:00
Taloth Saldono
b764c44318 Fixed tests 2019-08-31 12:25:13 +02:00
Taloth Saldono
adbd519061 noreferrer for images to allow images to be loaded from tvdb 2019-08-30 23:47:18 +02:00
Taloth Saldono
b0415299ca Fixed: Download mediacover using configured proxy.
closes #3283
2019-08-30 23:36:30 +02:00
Taloth Saldono
e96d05149c Added missing SentryEnabled check 2019-08-30 20:40:35 +02:00
Taloth Saldono
354ddcfee5 Fixed: Removed .Net update notice on Windows LTSB 2015 2019-08-30 20:39:54 +02:00
Taloth Saldono
6d232778e2 Fixed: Root Folder display when free diskspace cannot be determined (FreeBSD)
closes #3275
2019-08-27 23:48:34 +02:00
Taloth Saldono
95ee7daf21 New: Added Auth-* log entries for fail2ban purposes
closes #2760
2019-08-27 23:29:16 +02:00
Taloth Saldono
2238ac5d17 Fixed: Added missing ca-certificates-mono dependency to debian package
closes #3257
2019-08-26 23:07:15 +02:00
Taloth Saldono
c209c1c034 Typo 2019-08-26 22:35:21 +02:00
Taloth Saldono
b1eec16333 Updated way Sentry gets configured and enabled. 2019-08-26 22:35:21 +02:00
Taloth Saldono
e126c45fb3 Added BuildInfo.AppName to centralize 'Sonarr' 2019-08-26 22:35:21 +02:00
Taloth Saldono
c89ff93be4 Revised webpack bundling 2019-08-26 22:33:19 +02:00
Taloth Saldono
c82c27a5c5 Added active detection for updatecheck so we know which os/runtime versions don't need to be supported anymore. 2019-08-26 22:33:19 +02:00
Taloth Saldono
b3e84f407a New: Removed libcurl http fallback since mono 5.16+ doesn't need it. Also bumped minimum mono version check to 5.16 (5.20 is the best choice atm) 2019-08-26 22:33:19 +02:00
Taloth Saldono
72902c8984 Test framework version 2019-08-24 01:39:16 +02:00
Taloth Saldono
2c47c5eb99 Fixed: Missing debian package dependency and made them optional. 2019-08-24 01:23:04 +02:00
Taloth Saldono
398129f3e1 Cleanup obsolete files 2019-08-23 21:20:54 +02:00
Taloth Saldono
d74ab12d9e Flaky CommandExecutorFixture tests 2019-08-22 23:28:17 +02:00
Taloth Saldono
679c0599dd Flaky CommandExecutorFixture tests 2019-08-22 22:20:39 +02:00
Taloth Saldono
4d04ad5632 Fixed typos 2019-08-22 21:58:57 +02:00
Taloth Saldono
3fdc50b354 Fixed flaky test by flushing logs and getting them via the api 2019-08-22 21:49:06 +02:00
Taloth Saldono
7eeff32185 Another Daily format with no series title. 2019-08-21 21:43:36 +02:00
Taloth Saldono
d40f2cb852 Fixed assembly configuration/branch attribute generation. 2019-08-21 21:02:14 +02:00
Qstick
f9dc2fb6d5 New: Replace SharpRaven with new Sentry SDK
Co-Authored-By: ta264 <ta264@users.noreply.github.com>
2019-08-20 19:39:49 +02:00
Taloth Saldono
de31dfb11e Fixed several tests and test infrastructure issues 2019-08-20 19:39:49 +02:00
Taloth Saldono
ef6a648189 Fixed Automation Tests for Firefox and Sonarr v3 UI. 2019-08-20 19:39:49 +02:00
Taloth Saldono
09953e2af8 Updated xmlrpc and SocksProxy 2019-08-20 19:39:49 +02:00
Taloth Saldono
be240119e8 Updated Test harnass, NUnit to 3.12.0, NBuilder to 6.0.0, Moq to 4.12.0, FluentAssertions to 5.8.0 2019-08-20 19:39:49 +02:00
Taloth Saldono
2b7893c834 Updated NLog to 4.6.6, Newtonsoft.Json to 12.0.2, RestSharp to 106.6.10 2019-08-20 19:39:49 +02:00
Taloth Saldono
896e824ca1 Updated FluentValidation to 8.4.0 2019-08-20 19:39:49 +02:00
Taloth Saldono
7a94725808 Updated SharpZipLib to 1.2.0 2019-08-20 19:39:49 +02:00
Taloth Saldono
a66fb76e9a Converted all projects to the new csproj format. 2019-08-20 19:39:49 +02:00
Taloth Saldono
b453d48fee Removed excluded source files. 2019-08-20 19:39:49 +02:00
Mark McDowall
a7f2c07998 Fixed: Improve parsing of anime file names without standard release group/hash
Closes #3117
2019-08-17 13:05:20 -07:00
Mark McDowall
3cff878f74 New: Parse more poor p2p file naming
Closes #3266
2019-08-17 12:41:42 -07:00
Mark McDowall
665d536481 Fixed: Infinite spinner when toggling seasons on multiple series from season pass 2019-08-16 22:46:12 -07:00
Mark McDowall
ec6d407fbb Fixed: Special title matching when special title has an apostrophe
Closes #2872
2019-08-16 21:48:43 -07:00
Mark McDowall
72bc7ed6d4 Fixed: Waiting a long time for unavailable root folders
Closes #2877
2019-08-16 20:54:03 -07:00
Mark McDowall
ac407ca2c0 New: Show Hardlink/Copy in manual import 2019-08-16 00:05:22 -07:00
Mark McDowall
6af5f2b528 New: URL Base support for NZBVortex, Hadouken, qBittorrent and uTorrent
Closes #1651
2019-08-16 00:04:53 -07:00
Mark McDowall
8fd4a98fbe New: Sort by series year in series list
Closes #3245
2019-08-15 23:28:54 -07:00
Mark McDowall
07d553fae3 New: Sort preferred words in profile on save
Closes #3241
2019-08-15 23:23:36 -07:00
Mark McDowall
34e0eea173 Menu fixes
Fixed: Menus in modals on iOS
Fixed: Menu not closing on outside touch on mobile
2019-08-15 22:51:30 -07:00
Mark McDowall
73e6db9a12 Fixed: Scrolling of modals with tabular content in iOS
Fixes #3264
2019-08-15 22:48:39 -07:00
Mark McDowall
0df464ac03 Fixed prop type warning on MenuItem 2019-08-15 21:06:04 -07:00
Mark McDowall
78ee6afbae Fixed: Episode Progress custom filtering on series list page 2019-08-15 18:12:19 -07:00
Mark McDowall
31be74e6d3 New: Add Tabula Rasa Newznab Preset 2019-08-15 00:40:44 -07:00
Mark McDowall
767a09894a Health UI improvements
Fixed: Failing to get items from SABnzbd will report health error properly
Fixed: Some health checks not showing test all button on System: Health
2019-08-15 00:24:09 -07:00
datahodor
0d410d107d New: Treat MaxdomeHD as Web-DL 2019-08-14 23:22:07 -07:00
Ken Murphy
7829b18b3c New: User configurable minimum free disk space
Closes #3233
2019-08-14 22:14:59 -07:00
Mark McDowall
b2267a55ce New: Improved parsing of poorly named multi-episode anime-like releases
Closes #3259
2019-08-14 20:50:12 -07:00
Mark McDowall
eca016fe61 Fixed: Prevent moving to recycling bin causing a failed import 2019-08-13 17:31:05 -07:00
Mark McDowall
81723f7fa9 Retry HttpLogFixture 2019-08-12 22:18:06 -07:00
Mark McDowall
44c91fb90c Fixed: Ensure correct series is used for Manual File Import from series details page 2019-08-12 21:57:11 -07:00
Mark McDowall
7cb5bd9c95 And another one to retry 2019-08-11 00:30:11 -07:00
Mark McDowall
8196f6b9db New: Cleanup Recycling Bin folders older than X days (0 to disable) 2019-08-11 00:22:26 -07:00
Mark McDowall
d72b16531b New: Add TVDB Link to add new series search result 2019-08-11 00:03:22 -07:00
Mark McDowall
f333196efe Retry up to 5 times for disk tests that sometimes fail 2019-08-10 23:14:39 -07:00
Wu Haotian
6ea047dcb4 New: Add support for Lilith-Raws release group 2019-08-09 19:05:40 +02:00
Mark McDowall
ea65867b23 Fixed: Logging file release group for repack 2019-08-08 10:26:27 -07:00
Mark McDowall
c41200e762 csproj update to match the file rename 2019-08-07 20:14:47 -07:00
Mark McDowall
4c70afbb53 Make powershell test explicit 2019-08-07 19:10:29 -07:00
Qstick
0c1ce66053 Cleanup Multiple Compiler Warnings 2019-08-07 19:08:03 -07:00
rbraunschweig
fa8b8cebf9 More repost exclusions to clean release group 2019-08-07 18:57:39 -07:00
Mark McDowall
72fa89ba76 Fixed: Repack don't being grabbed when cutoff already met
Fixes #3250
2019-08-06 19:52:49 -07:00
Mark McDowall
dc7b4cebf2 New: Add warning that recycle bin will be cleaned up automatically after 1 week 2019-08-06 19:52:49 -07:00
emyarod
3c1dd94915 Fix README hyperlink formatting 2019-08-06 17:27:27 -07:00
Mark McDowall
3decbbac3a Fix RARBG parsing test 2019-08-06 08:54:50 -07:00
Mark McDowall
27f43569f5 Fixed: Edge case where import fails due to DB relationship mismatch
Closes #3243
2019-08-05 13:55:19 -07:00
Mark McDowall
bd9bded73b Fixed: Improved failed series search messaging
Closes #3187
2019-08-04 09:01:12 -07:00
Mark McDowall
0ce81e1ab6 Fix SeriesFolderAsRootFolderValidator 2019-08-04 08:38:36 -07:00
Mark McDowall
2926201694 Fixed: RARBG links in Interactive Search
Fixes #3239
2019-08-04 01:01:40 -07:00
Mark McDowall
059be2c853 New: Add root folder from Media Management settings 2019-08-04 01:01:40 -07:00
Mark McDowall
dd09f31abb New: Series folder hint when selecting a root folder while adding a new series 2019-08-04 01:01:40 -07:00
Mark McDowall
1da20da3ff Fixed: Season actions on mobile not indicating when they are disabled 2019-08-04 01:01:40 -07:00
Mark McDowall
341773830b Fixed: Modal scrolling causing app to scroll on iOS 2019-08-04 01:01:40 -07:00
Mark McDowall
c65452bb01 Fixed: Edit path on series index resetting cursor to end on change 2019-08-04 01:01:40 -07:00
Mark McDowall
34d81356a3 New: Limit filenames to a maximum of 255 characters
Closes #2699
2019-08-03 13:20:34 -07:00
Mark McDowall
c9b84a5202 Update yarn.lock 2019-08-02 17:39:27 -07:00
Mark McDowall
5394cc2dc9 Interactive search fixes
Fixed: Sorting of Quality column in Interactive Search
Fixed: column widths in Interactive Search
2019-07-31 14:54:59 -07:00
Mark McDowall
63141f339f New: Bulk select episodes in Manual Import 2019-07-30 19:07:13 -07:00
Mark McDowall
079a0b56c3 Fixed: Manual import from queue showing error when download name failed to parse 2019-07-30 08:44:55 -07:00
Mark McDowall
66721affe7 Fix setup package creation 2019-07-28 09:52:34 -07:00
Mark McDowall
d8ab23e9ba Fix setup package creation 2019-07-28 00:23:19 -07:00
Mark McDowall
11b0a5c9cc Appease eslint 2019-07-26 22:07:49 -07:00
Mark McDowall
d273a72cb3 Recycle bin file cleanup
Fixed: Recycle bin will clean up files older than 7 days and remove empty folders left behind
2019-07-26 22:07:25 -07:00
Mark McDowall
08641a6694 Update redux 2019-07-26 18:14:13 -07:00
Mark McDowall
9ac5c0d886 Upgrade sentry 2019-07-26 18:14:13 -07:00
Mark McDowall
8a57d33223 Upgrade del 2019-07-26 18:13:47 -07:00
Mark McDowall
1945b53e43 Upgrade various packages 2019-07-26 18:13:47 -07:00
Mark McDowall
161e1820a8 Upgrade React DND 2019-07-26 18:13:47 -07:00
Mark McDowall
22b5ac8622 Update react router packages 2019-07-26 18:13:47 -07:00
Mark McDowall
f75a70e42b Update react packages 2019-07-26 18:13:47 -07:00
Mark McDowall
c9076606be Upgrade CSS packages 2019-07-26 18:13:47 -07:00
Mark McDowall
853d22b947 Upgrade font awesome 2019-07-26 18:13:47 -07:00
Mark McDowall
82d6719d91 Upgrade linter packages 2019-07-26 18:13:47 -07:00
Mark McDowall
3f02c150e3 Set corejs version 2019-07-26 18:13:47 -07:00
Mark McDowall
d7d46a93a7 Update webpack packages 2019-07-26 18:13:47 -07:00
Mark McDowall
dfd51635a6 Upgrade gulp tooling 2019-07-26 18:13:47 -07:00
Mark McDowall
c04366d505 Update babel packages 2019-07-26 18:13:47 -07:00
Mark McDowall
fd89e88d40 Fixed: Manage Episodes not showing whether language/quality meets cutoff 2019-07-26 18:10:02 -07:00
Mark McDowall
894de923b9 Fixed: Don't reject standard/absolute numbering mismatch due to season number 2019-07-26 17:59:41 -07:00
Mark McDowall
c47e7cd91d Fixed: Canceling editing a custom filter won't close the Custom filter modal 2019-07-26 17:52:05 -07:00
Mark McDowall
e359347a3b Fixed: Anime season searches rejecting season packs 2019-07-26 17:52:05 -07:00
Mark McDowall
d320017e3c Cleanup migration 131 2019-07-26 17:52:05 -07:00
devbrian
e6c34f4311 Fixed: Season mismatch between file and folder not rejecting import 2019-07-26 17:51:54 -07:00
Mark McDowall
9b0c945086 Fix NZBGet Delete Status Copy test 2019-07-25 16:48:03 -07:00
Mark McDowall
bc85f5de1d Add logging to Windows setup 2019-07-25 07:49:32 -07:00
Mark McDowall
4df219161c New: Dim episode/air time on calendar 2019-07-24 20:08:26 -07:00
Mark McDowall
06f157e634 Fixed: Tags in settings getting cutoff 2019-07-24 19:59:27 -07:00
Mark McDowall
54addbdd28 Fixed: Don't ignore Delete:Copy items in NZBGet 2019-07-22 21:15:27 -07:00
Mark McDowall
0e721917e7 Fix stylelint once and for all (hopefully) 2019-07-22 19:44:07 -07:00
Mark McDowall
4dc7089f89 Fixed: Add tooltip to tag delete button when in use 2019-07-22 10:43:40 -07:00
Mark McDowall
30b5a35db2 Fixed: tag input alignment and height 2019-07-22 10:43:40 -07:00
Mark McDowall
dc8f81b536 Double instead of single quotes in CSS 2019-07-22 10:43:40 -07:00
Mark McDowall
a018770a18 UI fixes 2019-07-22 10:43:40 -07:00
Mark McDowall
5e4f7c5d8e Minor cleanup 2019-07-22 10:43:40 -07:00
Mark McDowall
1d9d665ed0 Fixed: Stripping subtitles from series titles after parsing
Closes #3219
2019-07-22 10:43:40 -07:00
linxchaos
68477c09a7 Improve grammar in Import Series 2019-07-21 17:13:31 -07:00
Mark McDowall
574b9086d4 Fix oAuth actions in UI 2019-07-17 17:25:20 -07:00
Mark McDowall
d74c323c66 Remove unused prop 2019-07-17 08:16:35 -07:00
Mark McDowall
8e85a1b84e Remove unused import 2019-07-16 22:54:54 -07:00
Mark McDowall
6ce1cb4325 Refetch series when signalR reconnects 2019-07-16 22:42:32 -07:00
Mark McDowall
fbbd85d8b2 Fix boolean for title prop warning 2019-07-16 22:42:22 -07:00
Mark McDowall
e611dc43c5 Fix stylelint 2019-07-16 16:30:00 -07:00
Mark McDowall
c86309cfc0 New: Show relative file name when selecting episode in Manual Import
Closes #3197
2019-07-16 10:52:54 -07:00
Taloth Saldono
ec74e9bce0 Incremented package version 2019-07-14 21:57:29 +02:00
Taloth Saldono
f371e8a523 Fixed stylelint errors 2019-07-14 21:57:29 +02:00
Taloth Saldono
57a059eecb Updated debian install script to handle old nzbdrone systemd unit named sonarr.service 2019-07-14 21:57:29 +02:00
Taloth Saldono
2cb149c647 Added alternative libcurl4 dependency to satisfy ubuntu cosmic. 2019-07-14 21:57:29 +02:00
Taloth Saldono
ee5371b582 Added alternative libmediainfo0 dependency for debian jessie
closes #3205
2019-07-14 21:57:29 +02:00
Taloth Saldono
70e4dbe3bd Updated debian build to fix stray msbuild dependency 2019-07-14 21:57:29 +02:00
Taloth Saldono
18ead9a64f Added MediaInfo AudioLanguagesAll.
closes #3190
2019-07-14 12:14:31 +02:00
Taloth Saldono
d2764cee2a Fixed: Heavy qbit api load when CDH Remove is disabled and Seeding time has been reached
ref #3108
2019-07-14 12:13:54 +02:00
Mark McDowall
082c098420 New: Include HDR is naming examples
Closes #3199
2019-07-11 17:51:48 -07:00
Mark McDowall
46a42e2901 New: Update examples for Kodi metadata
Closes #3201
2019-07-11 17:45:29 -07:00
Mark McDowall
c21cacd309 Fixed: Monitoring latest season ignoring unaired episodes
Fixes #3200
2019-07-11 17:45:04 -07:00
Mark McDowall
81ac359f71 Default to System Tray for Windows installer 2019-07-11 17:43:52 -07:00
Mark McDowall
f5b91c90bc Fixed: Parsing BD release group as Bluray quality 2019-07-09 17:23:50 -07:00
Mark McDowall
0a92a3012e Add warning to remove from queue dialog 2019-07-06 11:27:17 -07:00
Mark McDowall
ff8fc237e2 Darker border for calendar 2019-07-04 19:59:11 -07:00
Mark McDowall
b99d943b4d New: Wider and taller scroll bar for the click to scrollers out there 2019-07-04 19:53:18 -07:00
Mark McDowall
3199fe08e8 Custom Filter improvements
Fixed: Removing Custom Filter left spinner visible
Fixed: Custom filter/tag input being cutoff on iOS
2019-07-04 19:10:59 -07:00
Taloth Saldono
7503ce62af Fixed: Workaround for mono 5.16+ bug preventing the closure of sockets on timeouts (Jackett connections)
ref #2802
2019-07-02 20:52:12 +02:00
Taloth Saldono
df8ca250aa Fixed: Executing powershell and python scripts directly in Connect->Custom Scripts 2019-07-02 20:50:32 +02:00
Taloth Saldono
c71b4bde86 Added test for turkish FirstCharToUpper 2019-07-02 20:32:35 +02:00
Mark McDowall
3f67802e3d Fixed: Delay profile being ignored for non-revision upgrades 2019-07-01 00:45:05 -07:00
Mark McDowall
093ed23140 New: Improve logging when checking if release is an upgrade for an existing file 2019-07-01 00:44:37 -07:00
Mark McDowall
0f8dee7011 New: Treat WEBMux as WebRip
Closes #3186
2019-06-29 15:39:31 -07:00
Mark McDowall
0cb557b716 New: Improve help text for extra file importing 2019-06-29 15:39:31 -07:00
Mark McDowall
8137a776b6 New: Command line arguments for Custom Scripts are no longer supported 2019-06-29 15:33:49 -07:00
Taloth Saldono
1af3e0bd93 Created generic Hinted EnhancedSelectInput components and use it instead of SelectInput 2019-06-20 19:09:28 +02:00
Taloth Saldono
d3662f2302 Added test for turkish FirstCharToLower 2019-06-15 20:38:17 +02:00
Taloth Saldono
5fe34cb593 Fixed: Tag deletion via api if tag is still in use 2019-06-15 20:11:50 +02:00
Taloth Saldono
af5166e95d Fixed: Transmission seeding idle time handling 2019-06-15 19:31:55 +02:00
desimaniac
13907d6711 New: Remove some more retagging groups from filenames. 2019-06-15 10:10:48 -07:00
Mark McDowall
c4c9f0e368 Fixed: Issue searching for series in the UI when tag is removed 2019-06-15 10:09:21 -07:00
Mark McDowall
394932b57f Fixed: Remote path mapping host comparison ignores case
Closes #3169
2019-06-15 09:46:47 -07:00
Mark McDowall
7dff9bc696 Fixed: Errors logged during import when existing episode file is partial removed in the DB
Fixes #3159
2019-06-15 00:48:03 -07:00
Mark McDowall
4713eaffdb Fixed: Mass Editor not showing delete button on narrow screens
Fixes #3142
2019-06-11 23:06:14 -07:00
Mark McDowall
3a7992b1c8 Small UI fixes
Fixed: Season count popover styling
Fixed: URL base of /series linking to the wrong path in some cases
Fixed: Manual import showing error when a different series is selected
Fixed: Error when deleting series from poster list
2019-06-11 23:05:17 -07:00
Mark McDowall
5275aa72fb Clean up FirstCharacterToLower extension + tests 2019-06-10 21:32:42 -07:00
Mark McDowall
9e45b9e808 Fixed: Selecting a release from Interactive Search with an unknown episode 2019-06-10 21:32:42 -07:00
Taloth Saldono
88dfa14046 Wrong escape in help message 2019-06-10 16:30:28 +02:00
Taloth Saldono
dd4216d432 Fixed: Regression preventing empty qbittorrent category
fixes #3158
2019-06-10 12:13:39 +02:00
Taloth Saldono
628ab85de4 New: Configurable Specials folder format 2019-06-10 00:46:46 +02:00
jtpavlock
39ea2dd32f New: Ability to set a post-import label in Deluge, rTorrent, qBittorrent, and uTorrent 2019-06-09 19:54:53 +02:00
Taloth Saldono
1d77c40d0e Support for primary and fallback download client 2019-06-08 15:49:54 +02:00
Taloth Saldono
a3cbb4158c New: Round-robin over available Download Client instead of the first enabled one 2019-05-30 00:38:18 +02:00
Taloth Saldono
52aa84e9f9 Tweaked mediainfo api call to better handle unsupported locales. 2019-05-30 00:32:52 +02:00
lps-rocks
f08fc7493d New: Added downloadId filter to v3 history api for third-party applications
closes #3105
2019-05-30 00:32:17 +02:00
Taloth Saldono
a80b1bbcb3 Added more logging to MediaInfo encoding check for linux. 2019-05-22 19:54:40 +02:00
Carl Downing
7ce8bac3ea Fix grammar and punctuation in DeleteSeriesModalContent 2019-05-18 22:09:19 -07:00
Mark McDowall
5c258797ec Fixed: tag input height not growing in height
Fixes #3124
2019-05-16 22:47:28 -07:00
Taloth Saldono
0dccc7e91e Fixed: Various performance improvements for large collections 2019-05-16 00:22:11 +02:00
Taloth Saldono
9e68653949 Fixed: Slow db migration when upgrading from v2 to v3 with a large collection 2019-05-16 00:07:02 +02:00
Taloth Saldono
83c09b4540 Fixed: Support for SignalR's Server Sent Events transport as an alternative to websockets and long polling 2019-05-16 00:05:15 +02:00
Mark McDowall
5cf2672469 Fixed: Files not replacing a lower quality proper/repack 2019-05-15 14:08:02 -07:00
Mark McDowall
50144721d7 Don't double log exception setting file permissions 2019-05-12 21:53:31 -07:00
Mark McDowall
0fe7da80ab Fixed: Error logged when checking if v2+ anime release is a valid upgrade
Fixes #3114
2019-05-12 16:25:57 -07:00
Mark McDowall
068eb33bf6 New: TVDB ID filter when getting series from API
Closes #2486
2019-05-12 16:14:56 -07:00
Mark McDowall
98b1a7681b Fixed: Monitored status being reset after refresh when series is edited manually 2019-05-12 16:03:31 -07:00
Mark McDowall
488967c6ef Fixed: Parsing of WEB from some file names 2019-05-11 22:20:41 -07:00
Mark McDowall
a5aab95ecf Fixed NZBGet tests take 2 2019-05-09 10:25:09 -07:00
Mark McDowall
345de3654a Fixed NZBGet tests 2019-05-09 09:31:05 -07:00
Mark McDowall
6ea7e785e3 New: Additional information when Sonarr is unable to access a path during import
Closes #1106
2019-05-08 22:56:30 -07:00
Mark McDowall
0c2331f638 Fixed: Ignore deleted duplicates from Nzbget
Fixes #1721
2019-05-08 22:25:10 -07:00
Mark McDowall
5fe1ce1eff Fixed: Don't import duplicate NFO extra files
Fixes #2641
2019-05-08 21:58:50 -07:00
Mark McDowall
6a6d6f9e0d Fixed: Importing of preferred release over a proper/repack 2019-05-08 21:04:12 -07:00
Mark McDowall
30a512c880 Fixed: Episode details on history episode file information 2019-05-08 20:15:21 -07:00
Mark McDowall
2b4519a4ad Fixed: Loading of fonts.css with a URL Base
Fixes #3103
2019-05-08 19:33:47 -07:00
Mark McDowall
3e25d41c0f Another entry into the hall of shame 2019-05-06 08:22:55 -07:00
Mark McDowall
d8baa93289 Only check repacks for revision upgrades 2019-05-05 20:39:52 -07:00
Mark McDowall
d8c2640959 Fixed: Queue tooltips appearing offscreen on mobile devices 2019-05-05 20:03:26 -07:00
Mark McDowall
2ae4337d0d FirstCharToLower 2019-05-05 18:57:33 -07:00
Mark McDowall
0416060643 Tests for repack fix and improve behaviour when release group is unknown 2019-05-05 13:01:16 -07:00
Mark McDowall
2b1fd77ad7 Fixed: Repack check failing for episode file without a known release group 2019-05-05 11:09:48 -07:00
Mark McDowall
43567a3119 Remove old twitter keys 2019-05-05 11:09:48 -07:00
desimaniac
d463c2fbc5 New: Remove 'AsRequested' suffix from release group names 2019-05-04 23:24:13 -07:00
Mark McDowall
940cba5f90 Fixed: Possible issue with manual import of an unknown release 2019-05-04 08:57:59 -07:00
Mark McDowall
7321075631 New: Option to not prefer repacks/propers (for use with Preferred Words)
Closes #3084
2019-05-04 00:33:13 -07:00
Mark McDowall
a06cbc44cd Fixed: Ignore episode title when parsing release group
Fixes #3097
2019-05-03 20:14:35 -07:00
Mark McDowall
088b4af795 Appease stylelint 2019-05-03 18:44:06 -07:00
Mark McDowall
fc0b1e8941 Extra warning for Windows Service issues when prompted to restart after changing host settings
Closes #3094
2019-05-03 17:52:23 -07:00
Mark McDowall
9ad3b12403 Manual Import: Reprocess after selecting series
New: Reprocess changed items when series is changed
Closes #1893
2019-05-03 17:38:06 -07:00
Mark McDowall
88ecec2f9a Fix SAB test 2019-05-03 14:09:19 -07:00
Mark McDowall
4ea5e9ce9b Ignore older episodes in latest season
New: Ignore episodes that aired more than 90 days ago when adding with Latest Season
Closes #826
2019-05-01 23:29:54 -07:00
Mark McDowall
9b617af713 New: Option to opt out of TBA episode title import delays
Closes #3086
2019-05-01 20:36:09 -07:00
Mark McDowall
e70d92f670 New: Restrict repack upgrades to the same release group
Closes #946
2019-04-29 23:38:18 -07:00
Mark McDowall
1b3acb52f1 Fixed: Don't treat NZBs rejected by SABnzbd as successful 2019-04-29 18:18:06 -07:00
Mark McDowall
052ddc11b7 Added a unit test for the NZBGet Final dir fix 2019-04-28 19:27:34 -07:00
Mark McDowall
4e3a5a8823 Only use NZBGet's FinalDir if it's not empty
Fixed: Importing from NZBGet
2019-04-28 19:23:56 -07:00
Mark McDowall
05e17b70b5 New: Show health warning if system time is off expected time
Closes #1422
2019-04-28 11:50:18 -07:00
Mark McDowall
949d764638 Use popper placement for tooltip arrow 2019-04-28 01:08:09 -07:00
Mark McDowall
5c2cb4de80 Improve tooltip performance 2019-04-28 01:08:09 -07:00
Mark McDowall
f68c5cb4f7 QualityDefinition UI fixes 2019-04-28 01:08:08 -07:00
Mark McDowall
06c1f376bc Improve performance of search input selecting series 2019-04-28 01:08:05 -07:00
Mark McDowall
7c7a6a4514 Throw exception if ports are the same at startup 2019-04-28 01:07:56 -07:00
Mark McDowall
5293349785 Limit search input to first character matching when only one character is typed 2019-04-27 20:14:44 -07:00
Mark McDowall
2ee0ae1f9e New: Don't search for unaired anime episodes when searching for season
Closes #2530
2019-04-27 19:13:27 -07:00
Mark McDowall
8143237d25 Re-order PMS settings and rename Kodi connection 2019-04-27 18:55:09 -07:00
Mark McDowall
a426068273 New: Option to use HTTPS with Emby
Closes #2923
2019-04-27 18:54:45 -07:00
Mark McDowall
599b19102e Fixed: Don't allow HTTP and HTTPS to use the same port
Closes #2890
2019-04-27 18:48:23 -07:00
Mark McDowall
e7a979d6b4 Fixed tests after removing sentry logging 2019-04-27 18:44:56 -07:00
Mark McDowall
7991ed0154 New: Reject multi-season releases
Closes #683
2019-04-27 18:27:35 -07:00
Mark McDowall
a9a3e50179 Fixed: Parsing of some anime batches
Closes #2705
2019-04-27 18:27:34 -07:00
Mark McDowall
7642fe046b New: Log when release is matched by ID instead of title
Closes #446
2019-04-27 18:01:45 -07:00
Mark McDowall
ccc2c39d43 Fixed: Cleaning percent signs from release names
Fixes #1998
2019-04-27 16:15:53 -07:00
Mark McDowall
26228e546e Improve error messaging for missing information when searching
Fixed: Show missing absolute episode number/air date error message in interactive search
2019-04-27 16:15:53 -07:00
Mark McDowall
6036bc17c5 New: Use NZBget's FinalDir is set by post-processing script
Closes #2006
2019-04-27 16:15:52 -07:00
Taloth Saldono
ca4b03f48a Fixed typos. 2019-04-26 20:09:12 +02:00
Mark McDowall
b0f59ad988 Removed unused var 2019-04-25 22:22:07 -07:00
Mark McDowall
c9bdf43a0d Use Portal component in AutoSuggestInput 2019-04-25 21:47:29 -07:00
Mark McDowall
dadab50f3b Fixed: Backup path URL
Fixes #3079
2019-04-25 20:30:55 -07:00
Mark McDowall
0b49eba77a Fixed: Root folder selection scrolling
Fixes #3077
2019-04-25 20:24:05 -07:00
Mark McDowall
004b7391c6 Fixed: Math on quality definition limits 2019-04-24 21:46:46 -07:00
Mark McDowall
45c221a3b2 Fixed: Ensure max sized posters aren't returned for some devices 2019-04-24 21:00:15 -07:00
Mark McDowall
364f074be1 Fixed: Removed nzbs.org Newznab preset 2019-04-24 20:39:45 -07:00
Qstick
e82eded1e9 Fixed: Support new feed url format IPTorrents
Fixes #3071
2019-04-24 00:12:16 -07:00
Mark McDowall
b298f84f51 Fixed: Parsing of first aired date on Arabic systems 2019-04-24 00:12:16 -07:00
Mark McDowall
26ff28aae6 New: Tooltips for quality size limits 2019-04-24 00:12:16 -07:00
netpok
588eb6f691 New: Detect mergerfs mounts 2019-04-22 20:28:11 -07:00
Qstick
c10448af0b Fixed: Roksbox SeriesImages can lead to NullRef 2019-04-22 20:27:07 -07:00
Mark McDowall
0eb7973ab0 New: Show tooltips for changeable columns on Manual Import
Closes #3069
2019-04-22 20:19:20 -07:00
Taloth Saldono
150a87f2ea Fix VideoFileInfoReader tests after mediainfo update... take 2 2019-04-21 00:31:27 +02:00
Taloth Saldono
2505a19a88 Fixed: Air-time adjustment for Amazon/Hulu releasing 4+ episodes on one day 2019-04-21 00:06:13 +02:00
Mark McDowall
beea02cea9 Fixed: Don't reject import with missing episode title if renaming is off 2019-04-17 22:46:58 -07:00
Mark McDowall
600b5cfa8e Menu separator shown when scrollbar is visible 2019-04-17 22:43:35 -07:00
Mark McDowall
8055b5e5da New: Output Path column in Queue
Closes #3058
2019-04-17 22:39:37 -07:00
Mark McDowall
4933a75d15 Fixed: Don't include year 0 in series folder name
Fixes #3057
2019-04-17 22:25:41 -07:00
Mark McDowall
478e13b0fd Replace react-tether with react-popper 2019-04-17 02:21:58 -07:00
Mark McDowall
9c26da70da Fix VideoFileInfoReader tests after MediaInfo upgrade 2019-04-17 02:20:26 -07:00
Mark McDowall
872a8d983b Fixed: Manual import of unknown series items in Activity: Queue 2019-04-17 02:20:24 -07:00
Mark McDowall
47d3fe1de5 Fixed: Manage episode files for season text 2019-04-13 23:29:39 -07:00
Mark McDowall
9421af2c3f Backup directory is a path 2019-04-13 23:28:47 -07:00
Stephan Renggli
90626e353f New: Gotify notifications
Closes #3033
2019-04-13 15:50:22 -07:00
Mark McDowall
b3e019e7a0 New: Sort preferred words by score when displaying in the UI 2019-04-13 12:56:17 -07:00
Mark McDowall
84a0a0743b New: Upgrade MediaInfo to 18.12 (macOS and Windows) 2019-04-13 11:32:18 -07:00
Mark McDowall
377bd6e2b7 Collapse calendar view buttons on narrower screens (<= 1200px) 2019-04-13 11:08:59 -07:00
Mark McDowall
dc42c6a1df Fixed: Refresh on series list spinning forever in some cases 2019-04-12 23:33:51 -07:00
Mark McDowall
0ca70a3197 Fixed: Long path support on Windows 2019-04-12 19:21:49 -07:00
Mark McDowall
889f92268e Fixed: Series footer shows statistics based on filtered series list 2019-04-12 19:05:23 -07:00
morpheus133
24fba7a36d New: Use IMDB ID when searching supported indexers 2019-04-12 18:02:08 -07:00
Mark McDowall
c90672a5ab More renaming tokens
New: Always show Air Date renaming token in help modal
Fixed: Added missing media info renaming tokens
2019-04-12 17:48:45 -07:00
Mark McDowall
81c8fc0381 Fixed: Improve exception logging when unable to connect to Plex Media Server 2019-04-12 17:46:47 -07:00
Mark McDowall
7922a3856e updateMechanism isn't available while fetching 2019-04-11 23:56:58 -07:00
Mark McDowall
9aea452829 History details for unknown event type 2019-04-11 23:56:37 -07:00
Mark McDowall
e797b759b7 Fixed: Use Download Client name for grabbed history events 2019-04-11 23:43:41 -07:00
Mark McDowall
b60d5f837e Remove DownloadProtocol from v3 ReleaseResource 2019-04-11 23:41:06 -07:00
Mark McDowall
877235c8a2 Fixed: Already Imported check failing for some torrent releases 2019-04-11 17:49:09 -07:00
Mark McDowall
558bbeaa34 Fixed: SSL Certificate validation when port is used
Closes #3039
2019-04-11 09:00:59 -07:00
Mark McDowall
0911abcfc0 Improve certificate validation registration
Fixed: Certificate validation during startup
Fixed: Errors removing Windows service

Closes #3037
Closes #3038
2019-04-10 19:34:37 -07:00
Mark McDowall
04850331ce Fix long path support overrides in mono 2019-04-10 00:14:26 -07:00
Mark McDowall
b58336f4c8 Fix case of LegendIconItem.css 2019-04-10 00:13:56 -07:00
Mark McDowall
4665b4fb37 New: Target .net 4.6.2 2019-04-09 22:02:43 -07:00
Mark McDowall
49197a2ae0 Update executable icon 2019-04-09 21:54:44 -07:00
Mark McDowall
c718db21da Fixed: Certificate validation for local IP addresses instead of hostnames 2019-04-09 20:57:12 -07:00
Mark McDowall
35f28bdc71 Update docs
- Fix project names
- Unify dev environment setup
2019-04-09 20:47:50 -07:00
Mark McDowall
bf86b09f4e Fixed: Interactive search grabs rejected due to validation 2019-04-09 09:17:14 -07:00
Mark McDowall
cdde8cfdbe Protocol instead of download protocol 2019-04-08 22:47:56 -07:00
Mark McDowall
cd26b8f728 DownloadProtocol is an integer for release/push 2019-04-08 17:51:54 -07:00
Mark McDowall
8abfc7609e Send downloadProtocol in release/push integration test 2019-04-07 22:15:12 -07:00
Mark McDowall
7d06e5d684 HTTPS certificate validation options
New: Enable HTTPS certificate validation by default
New: Option to disable certificate validation for all or only local addresses
2019-04-06 23:43:47 -07:00
Mark McDowall
439870a546 Don't render table options modal content when it's closed 2019-04-06 23:22:52 -07:00
Mark McDowall
82b35f095e Improve series index performance during series refresh 2019-04-06 23:22:52 -07:00
Mark McDowall
b40d7d89a1 Improve selectors in PageConnector to reduce re-rendering 2019-04-06 23:22:52 -07:00
Mark McDowall
8f3dbbc356 Fixed: Return better error message if username or password is null for forms login 2019-04-06 21:33:48 -07:00
Mark McDowall
f748891b4b Fixed: Ensure loading message doesn't change on re-render 2019-04-06 19:22:24 -07:00
Mark McDowall
e325a5c27e Better response if invalid JSON is received through the API 2019-04-06 19:21:59 -07:00
Mark McDowall
7d131fbb3d ReleasePushModule uses ReadResourceFromRequest 2019-04-05 20:23:59 -07:00
Mark McDowall
2b63110323 Series index selector improvements 2019-04-05 20:17:24 -07:00
Mark McDowall
a63ca0f0e9 More file browsing improvements 2019-04-05 20:16:57 -07:00
Mark McDowall
5b2d0a2ade Fixed: Store columns for History table between refreshes 2019-04-05 17:53:11 -07:00
Mark McDowall
1a984df11a Fixed: Error on calendar with unknown items in the queue 2019-04-05 17:52:02 -07:00
Mark McDowall
fdc7a19628 Fixed: Error displayed occasionally after removing series from the series list
Fixes #3018
2019-04-04 19:35:06 -07:00
Mark McDowall
8087996c8e Better selection of executing commands in series list 2019-04-04 18:45:22 -07:00
Mark McDowall
e5f264a510 PahtInputConnector default prop for includeFiles 2019-04-04 18:45:21 -07:00
Mark McDowall
0a2eb74c26 Release module validation in v3 2019-04-04 18:45:20 -07:00
Mark McDowall
d5bb3bd799 Fixed: Centering of expand/collapse icon for season 2019-04-01 17:26:31 -07:00
addisonbabcock
cfa9d88be6 Fixed quality typo on manual import 2019-03-28 20:06:11 -07:00
Taloth Saldono
ac4617ae51 Fixed eslint error. 2019-03-26 19:11:51 +01:00
Taloth Saldono
f6bcadfeec Merge branch 'develop' into phantom-develop 2019-03-26 19:07:26 +01:00
Mark McDowall
5272078ea3 Fixed: Sorting by age when releases are less than a day old
Fixes #3012
2019-03-25 23:33:00 -07:00
Mark McDowall
b6257400ec Fixed: Sorting of search results in series search box
Closes #3013
2019-03-25 23:33:00 -07:00
Mark McDowall
c3a6e01040 Fix file browser when files should be included 2019-03-25 23:33:00 -07:00
Mark McDowall
b63cbbdaaa New: Release title column in queue 2019-03-25 23:33:00 -07:00
desimaniac
81d3f35034 Remove WhiteRev and BUYMORE suffixes from release group names 2019-03-24 19:18:58 +01:00
Mark McDowall
00a66e9030 Fixed: Parsing of some WEB releases
Fixes #3001
2019-03-23 11:56:17 -07:00
Mark McDowall
775c8780a6 Fixed: Consistent icon position for toolbar buttons 2019-03-23 11:56:17 -07:00
Mark McDowall
50a968ace8 Renamed Manual Import on series details page 2019-03-23 11:56:16 -07:00
Mark McDowall
db41104d9b Fixed: Queue count badge showing warning/error incorrectly 2019-03-23 11:56:16 -07:00
Mark McDowall
95bb73c5ac Eliminate gulp-flatten 2019-03-23 11:56:16 -07:00
Alan Yee
7ed2776476 Updated links in README.md 2019-03-23 11:14:29 -07:00
Taloth Saldono
341dfb934d Fixed: Typo in ical url handling when choosing premieres only. 2019-03-17 23:23:23 +01:00
hatharry
ecebe73c33 Fixed: Emby library update
Fixes #2662
2019-03-16 15:56:33 -07:00
Mark McDowall
1b0c6b919f Update readme with new requirements for v3 2019-03-16 15:25:03 -07:00
Mark McDowall
06b876cf8b On Download to On Import on card 2019-03-16 14:53:30 -07:00
Mark McDowall
de0d0a3526 New: Discord Notifications
Closes #1511
2019-03-16 14:51:12 -07:00
Mark McDowall
7f99ac0efa Added discord link to UI 2019-03-15 18:02:27 -07:00
Mark McDowall
d2980c58ec Fixed: MediaInfo AudioCodec token helper in UI 2019-03-15 18:02:27 -07:00
Taloth Saldono
d244ed6c64 More descriptive message if indexer connection test was successful but yielded no results. 2019-03-14 21:01:13 +01:00
Mark McDowall
a30d9a1af2 Fixed: Plex authentication 2019-03-14 00:53:53 -07:00
Mark McDowall
7acd6a4d3c Can't login with a username and a blank password 2019-03-14 00:53:53 -07:00
desimaniac
a6fdcb7493 Parser: Removes any combination of 'rakuv*` from release group names. 2019-03-12 20:05:54 +01:00
Taloth Saldono
0cc2437a9d Fixed typo in XDG_CONFIG_HOME handling.
closes #2989
2019-03-12 08:57:30 +01:00
Taloth Saldono
8102cb63ae Fixed: Interactive Search for Specials on BTN 2019-03-10 14:44:18 +01:00
Taloth Saldono
5062d74041 Reverted in-memory signalr keypair in favor of a .config directory. 2019-03-10 13:16:27 +01:00
Taloth Saldono
feebb349d5 Linting error. 2019-03-09 00:21:06 +01:00
Taloth Saldono
1036813b97 Fixed: Finetuned color-impaired mode styling in Calendar. 2019-03-08 23:48:45 +01:00
Taloth Saldono
6b405700ec Make sure something appears in the trace file before trying to read it. 2019-03-08 20:58:54 +01:00
Taloth Saldono
29b4a83d93 Wait for commands to finish between tests. 2019-03-08 20:29:38 +01:00
Taloth Saldono
7b159c1e63 Removed Nyaa Integration tests and increased logging detail during integration tests. 2019-03-08 19:37:59 +01:00
Taloth Saldono
02c64ad3a5 Fixed: Not being able to use MediaInfo VideoDynamicRange token to renaming options. 2019-03-08 18:37:10 +01:00
Taloth Saldono
13c625d7c0 Fixd test on mono. 2019-03-06 23:19:13 +01:00
Taloth Saldono
9a3f49bf9c Merge branch 'develop' into phantom-develop
# Conflicts:
#	src/NzbDrone.Common.Test/Http/HttpClientFixture.cs
#	src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs
2019-03-06 22:36:23 +01:00
Taloth Saldono
6698ca400c Handle special mount filtering at a higher level.
closes #2743
2019-03-06 22:34:17 +01:00
Mark McDowall
6bb649bac5 autoprefixer and webpack use the same browser list config 2019-03-05 20:01:21 -08:00
Mark McDowall
b72b74b6c6 Upgraded react and react-dom packages 2019-03-05 19:58:58 -08:00
Mark McDowall
e7bfea8c69 Update react-tether package 2019-03-05 19:38:39 -08:00
Mark McDowall
de7e805718 Limit replacement of colons 2019-03-05 18:08:34 -08:00
Mark McDowall
7b5e8646eb Transpile UI for old browsers 2019-03-05 18:07:51 -08:00
Mark McDowall
966e147a20 Replaced gulp-util with ansi-colors, updated packages 2019-03-05 00:32:21 -08:00
Mark McDowall
269a5bd914 New: Log conflicting TVDB ID when unknown series is an alias for another series 2019-03-05 00:30:37 -08:00
Mark McDowall
4f1f56f653 Another broken test 2019-03-04 21:06:32 -08:00
Mark McDowall
6b517d7ffd Fix broken tests 2019-03-04 19:47:24 -08:00
Mark McDowall
4eb9a1cfa5 New: Replace colon with space and dash instead of just dash
Closes #2961
2019-03-04 19:12:00 -08:00
Mark McDowall
db3aeb9ab5 Removed unused babel-plugin-transform-react-jsx-source 2019-03-04 19:00:22 -08:00
Mark McDowall
984b7bbeea Fixed: All preferred words being added to filename 2019-03-04 18:31:53 -08:00
Mark McDowall
582beed977 Fixed: Fonts not loading on reload 2019-03-04 18:31:19 -08:00
Mark McDowall
7fa8bd5613 Appease stylelint 2019-03-03 21:16:36 -08:00
Mark McDowall
4474172c40 Fix index.css 2019-03-03 21:14:21 -08:00
Mark McDowall
1dde397e2b Upgrade del 2019-03-03 20:58:53 -08:00
Mark McDowall
7ea3b6ca15 Upgraded to gulp 4
Use `yarn watch` to use local gulp
2019-03-03 20:56:16 -08:00
Mark McDowall
956e7b564c Upgrade eslint and stylelint-order... again 2019-03-03 11:39:17 -08:00
Mark McDowall
08990dd58a Upgraded to webpack 4 2019-03-03 11:29:12 -08:00
Mark McDowall
ca32434535 Update redux, reselect and moved to connected-react-router 2019-02-28 20:01:06 -08:00
Mark McDowall
ebf4f17f17 Fix route to series details from search input 2019-02-28 20:00:08 -08:00
Mark McDowall
22778091f9 RelativeDateCell PureComponent 2019-02-28 18:39:12 -08:00
Mark McDowall
4d389ae5ce Upgrade prop-types package 2019-02-27 21:37:49 -08:00
Mark McDowall
39e3120058 Fix page jump bar not rendering/rendering in the wrong order 2019-02-27 21:00:35 -08:00
Mark McDowall
6b15d7e260 Fix casing of RegexTermMatcher 2019-02-27 21:00:35 -08:00
Mark McDowall
277025775d Upgraded most react packages 2019-02-27 20:50:19 -08:00
Mark McDowall
dbd649bfb5 Upgraded sentry, clipboard, filesize, moment, normalize.css and qs packages 2019-02-27 18:54:25 -08:00
Mark McDowall
df4ddba1ab Missing root folder health check icon 2019-02-27 18:42:58 -08:00
Mark McDowall
21985d0814 Upgrade linting and CSS packages 2019-02-27 18:38:56 -08:00
Mark McDowall
f7031dcb7f Upgrade fontawesome packages 2019-02-27 18:33:09 -08:00
Mark McDowall
0219e62979 Use fuse.js for series searching in UI
Closes #2954
2019-02-27 17:52:05 -08:00
Mark McDowall
e66725047a Updated yarn packages for node 10 support 2019-02-27 17:13:27 -08:00
Mark McDowall
84fa99a126 Icon, SeriesIndexFooter -> PureComponent 2019-02-26 19:46:18 -08:00
Mark McDowall
78b3c9552b Fixed: Include matching value of preferred word regex, not the actual regex 2019-02-26 19:06:05 -08:00
Mark McDowall
1222aeaab6 Fixed: Select all in Episode File editor 2019-02-26 19:06:05 -08:00
Mark McDowall
cbbfc5b58c Remove logging of Unable to format audio channels using 'AudioChannels' due to old schema 2019-02-26 19:06:05 -08:00
Mark McDowall
11164ab838 New: Bulk select language and quality in Manual Import 2019-02-26 19:06:05 -08:00
Mark McDowall
8339f7fdb3 Fixed: Don't add TV Maze ID to format if unknown 2019-02-26 19:06:05 -08:00
Taloth Saldono
220cd84ef5 Fixed: SignalR requiring a home directory to function properly. 2019-02-23 21:18:52 +01:00
Wu Haotian
e5fa446159 Downgrade event-stream
https://github.com/dominictarr/event-stream/issues/116
2019-02-22 16:27:47 -08:00
Matt Evans
70c320e98b New: Added {MediaInfo VideoDynamicRange} renaming token to include HDR in the filename 2019-02-22 19:45:02 +01:00
Wu Haotian
8e486da928 New: Added parser support for common Chinese release formats 2019-02-20 20:04:05 +01:00
Wu Haotian
7ae906863d Fix filename in PostBuildEvent
NzbDrone.{Mono, Windows} has been renamed to Sonarr.{Mono, Windows} in adaf428aa7
2019-02-20 20:04:05 +01:00
Mark McDowall
fb4483fdcf Switch to https for httpbin URL test 2019-02-20 00:31:39 -08:00
Mark McDowall
e32e6e0bec Groups must contain multiple qualities 2019-02-19 18:48:54 -08:00
Mark McDowall
05e7b90aab Fixed: Correct rejection message when profile does not allow upgrades
Fixes #2958
2019-02-19 18:30:57 -08:00
Mark McDowall
ee59f91ba2 Pending releases have languages too 2019-02-19 18:27:48 -08:00
Mark McDowall
ece3241041 Fixed: Adding series with unknown IMDB ID and series folder includes IMDB ID 2019-02-19 18:27:26 -08:00
Mark McDowall
fcb1bcb91b New: Setting monitor to None when adding series will unmonitor the series as well 2019-02-19 18:26:34 -08:00
Mark McDowall
728c0e8272 Fixed: Select all on Activity: Queue 2019-02-19 17:54:57 -08:00
Mark McDowall
9b212d11f0 Fixed: Error when editing torrent indexer 2019-02-14 09:14:16 -08:00
Taloth Saldono
223209e1eb Tweaked language parser since PR isn't merged yet. 2019-02-12 21:59:26 +01:00
Taloth Saldono
5b741a10db Fixed: Season pack with Special in series title was treated as unknown special 2019-02-12 21:56:55 +01:00
Matt Evans
1606ea19a8 New: Added support for DTS-HD MA and TrueHD Atmos in MediaInfo AudioCodec. 2019-02-11 07:50:50 +11:00
Taloth Saldono
e5632019db Simplified more RegexReplace instances. 2019-02-09 21:13:13 +01:00
Taloth Saldono
ff994d594a Fixed error in unicode cleanup code removing most non-latin characters instead of just invalid ones. 2019-02-09 21:13:13 +01:00
Taloth Saldono
0214ced8f0 New: Added Icelandic language and improved Chinese language detection 2019-02-09 20:57:22 +01:00
Mark McDowall
813e5e1db8 New: Sort queue by status 2019-02-07 18:48:51 -08:00
Mark McDowall
69627911b3 New: Highlight currently installed version on System: Updates 2019-02-07 18:44:22 -08:00
Mark McDowall
29f905b942 Root folder handler for signalR 2019-02-07 18:43:56 -08:00
Mark McDowall
551fa7fe10 Fixed: Banner not growing when most columns are hidden 2019-02-07 18:43:43 -08:00
Mark McDowall
2ce3cd4c2a Fixed: Improve readability of text on light blue labels 2019-02-07 18:42:54 -08:00
Mark McDowall
8ea24a6b09 Fix QualityModelComparer test when respecting group order 2019-02-07 09:25:42 -08:00
Taloth Saldono
00ca91399a ESlint error 2019-02-07 13:33:08 +01:00
Taloth Saldono
cf327077e9 Fixed: Regression in folder move logic preventing updater from working. 2019-02-07 12:57:45 +01:00
Taloth Saldono
f215ba9bac Fixed: Additional reverse title parser patterns.
fixes #2943
2019-02-07 12:57:45 +01:00
Mark McDowall
b319cb9525 Fixed: Importing completed downloads from NZBGet with post processing script failing
Fixes #2919
2019-02-06 19:30:02 -08:00
Mark McDowall
95cd327022 Already is spelled already 2019-02-06 19:30:01 -08:00
Mark McDowall
807cfebf76 Number input and max release size limit increased
Fixed: Number input changing value while typing
New: Maximum size limit has been doubled

Closes #2921
2019-02-06 19:30:01 -08:00
Mark McDowall
a29b1259b5 Sort search input by sortTitle 2019-02-06 19:30:00 -08:00
Mark McDowall
102b8afd66 Various UI fixes
Fixed: Manual Import not working if no episodes are Missing
Fixed: Allow spaces in Must/Must not contain fields
Fixed: Show loading indicator when managing episodes and fetching data from the server
Fixed: Series images not loading for all search results
New: Auto focus search input when navigating to Add Series page
2019-02-06 19:30:00 -08:00
Mark McDowall
561fdef815 Fixed: Don't use extended episode number as release group 2019-02-06 19:30:00 -08:00
Mark McDowall
47db1db861 Minimize data sent when adding a new Indexer, Download Client, etc 2019-02-06 19:30:00 -08:00
Mark McDowall
de3d7e925a Updated yarn.lock with postcss-color-function 2019-02-06 19:29:59 -08:00
Mark McDowall
b04c286efc Fixed: Settings changes being cleared when leaving page despite confirmation they would be 2019-02-06 19:29:59 -08:00
Mark McDowall
b8b82189f7 Fixed: Quality Profile group order no longer used when ordering results 2019-02-06 19:29:59 -08:00
Mark McDowall
08b65a954d Fixed: Cutoff unmet episode search failing when there are unknown items in the queue 2019-02-06 19:29:59 -08:00
Mark McDowall
c6c998dc9f Fixed: poster not showing when adding a new series on a larger screen 2019-02-06 19:29:59 -08:00
Taloth Saldono
b3ff91608e Fixed: Ignore series title before SxxExx when parsing language.
ref #861
2019-02-04 22:01:25 +01:00
Taloth Saldono
1d862db7c9 Fixed: Korean shows with more than 2 digit episode numbers.
closes #2901
2019-02-04 21:39:28 +01:00
Taloth Saldono
070cbeebbe Allow -suffix in PackageVersion and added that and PackageAuthor to the About page. 2019-02-04 20:44:47 +01:00
Taloth Saldono
86c74b3ee0 Fixed failing ConfigFileProvider tests due to ConsoleLogLevel property error. 2019-01-21 22:28:45 +01:00
Taloth Saldono
b1a8c70d20 Moved fast MoveSeriesFolder logic if same RootFolder into DiskTransferService. 2019-01-21 22:18:37 +01:00
Taloth Saldono
9107d1678c Fixed: Failure to match S12E00 special due to episode file vs folder being parsed differently. 2019-01-21 21:24:27 +01:00
Taloth Saldono
095234babc Added Console log level option in configfile, which defaults to Info. 2019-01-21 21:24:27 +01:00
Mark McDowall
8aecec507e New: Ability to forcibly grab a release from Interactive Search
Closes #395
2019-01-18 16:35:19 -08:00
Mark McDowall
70fb1551af New: Log when media info is unavailable for a file when building a file name 2019-01-18 16:35:19 -08:00
Mark McDowall
fb67e123f4 Fixed: Changing series view 2019-01-18 16:35:19 -08:00
Mark McDowall
ae2efbc116 Fixed: QueueSpecification failing when an unknown item is in the queue 2019-01-18 16:35:19 -08:00
Mark McDowall
4bc0ffa74d Improve renaming of series folder within the same root folder 2019-01-18 16:35:19 -08:00
Taloth Saldono
6fed932a61 Tweaked Color-Impaired styling for Series Index. 2019-01-18 23:50:08 +01:00
Taloth Saldono
939ebcf897 Added missing references to test projects. 2019-01-12 13:40:28 +01:00
Taloth Saldono
1239fa874d Merge branch 'develop' into phantom-develop
# Conflicts:
#	src/NzbDrone.Api/Extensions/Pipelines/GZipPipeline.cs
#              Merged changes to src/Sonarr.Http/Extensions/Pipelines/GZipPipeline.cs
2019-01-12 13:32:11 +01:00
Mark McDowall
8abdb8bf51 Update test for disabling cache 2019-01-11 11:55:41 -08:00
Mark McDowall
e217068dbd Another path test fix 2019-01-10 23:26:25 -08:00
Mark McDowall
e3a9f753d2 Fix path tests 2019-01-10 20:32:41 -08:00
Mark McDowall
fc2a586453 Set max-age=0 on resources that should not be cached 2019-01-10 20:32:41 -08:00
Mark McDowall
979ea449bd Fixed: Edit button for Remote Path Mapping hidden on small screens 2019-01-10 20:32:41 -08:00
Mark McDowall
ba5e2cfc45 Series type filter/sort
New: Filter/sort by series type
Fixed: Filtering excluding multiple values (is not x or y)
2019-01-10 20:32:41 -08:00
Mark McDowall
3b565d8bb1 New: Table options in page toolbar in addition to table header 2019-01-10 20:32:41 -08:00
Mark McDowall
21a92b62fd Fixed: Various issues with unknown items in queue 2019-01-10 20:32:40 -08:00
Mark McDowall
7e33261ccc Fixed: Move series logging a failure and a success message 2019-01-10 18:15:43 -08:00
Mark McDowall
6a489a0b8f Fixed: Importing of completed download when not a child of the download client output path 2019-01-10 18:15:42 -08:00
Mark McDowall
44e9c77568 UI styling/propType fixes 2019-01-10 18:15:42 -08:00
Mark McDowall
77816aebac Fixed: Series index table header when banners are shown 2019-01-10 18:15:41 -08:00
Mark McDowall
9dd967f2aa Fixed: Getting parent of UNC paths 2019-01-10 18:15:41 -08:00
Mark McDowall
ef7a08879f New: Alternate styling for progress bars when color impaired mode is enabled 2019-01-10 18:15:40 -08:00
Mark McDowall
647e444a07 New: Add root folder to media management settings 2019-01-10 18:15:40 -08:00
Mark McDowall
c417239652 Fixed: Don't auto zoom when focusing inputs on mobile devices, namely iOS 2019-01-10 18:15:39 -08:00
Mark McDowall
e10c92878d Fixed: Calendar error after queue is refreshed 2019-01-10 18:15:39 -08:00
Mark McDowall
fc376bfe3f Fixed: Validation failures not being shown if adding a series fails 2019-01-10 18:15:34 -08:00
Mark McDowall
36fe4eaa49 Fixed: Log events not loading from the first page when revisiting 2019-01-10 18:13:56 -08:00
Mark McDowall
a3baab9671 Fixed: Failing to search for recently added series when there are unknown items in the queue 2019-01-10 18:13:55 -08:00
Mark McDowall
edd6c0bd4c Fixed getting parent path from a path without another slash
Fixed: Manual Import failing for some paths
2019-01-10 18:13:54 -08:00
Taloth Saldono
c14b339d80 Fixed typo in postinst preventing it from properly upgrading v3 alpha installs. 2019-01-02 22:06:58 +01:00
Taloth Saldono
8f4067adbb Also deal with migrations where the user installed using a different user. 2018-12-30 15:27:41 +01:00
Taloth Saldono
54160850b2 Increased debconf priority for username to high. 2018-12-29 13:51:34 +01:00
Taloth Saldono
524048c4b4 Also force branch if an external updater is used. 2018-12-29 13:51:34 +01:00
Taloth Saldono
565e625e21 Updated selection in UpdateSettings for external updaters. 2018-12-29 13:51:34 +01:00
Taloth Saldono
1ccae530d9 Added missing interval unit to Backup Settings. 2018-12-29 13:51:34 +01:00
Taloth Saldono
e8161aa9f4 Added specific external updater messages for Apt and Docker. 2018-12-29 13:51:34 +01:00
Mark McDowall
5a24b8d294 Add PackageUpdateMechanism to system/status response 2018-12-29 13:49:42 +01:00
Mark McDowall
aafa9cb6be Update UI
Squash into v3 UI
2018-12-29 13:49:42 +01:00
Taloth Saldono
dbdb8e4436 Added System.Native to the ignored list since afaik it's not used by SharpRaven. 2018-12-29 13:49:42 +01:00
Taloth Saldono
bfe2976463 Fixed failing tests. 2018-12-29 13:49:42 +01:00
Taloth Saldono
080bf6787a Fixed wrong sed wildcard. 2018-12-29 13:49:42 +01:00
Taloth Saldono
066a9de7ae Parse the package_info file to determine whether the UpdateMechanism is configured properly. 2018-12-29 13:49:42 +01:00
Taloth Saldono
f87e2dd717 Copy unix-specific System.Runtime.InteropServices.RuntimeInformation to linux output. 2018-12-29 13:49:42 +01:00
Taloth Saldono
1cf80c3ba0 Added release_info to build output instead of only in the debian package. 2018-12-29 13:49:42 +01:00
Taloth Saldono
6345d0e73b Replace Major.Minor.Revision in the TC provided BuildNumber with the packageVersion. 2018-12-29 13:49:42 +01:00
Taloth Saldono
7f5c1b0d5f Added support to migrate existing nzbdrone+systemd installs. 2018-12-29 13:49:42 +01:00
Taloth Saldono
b7259e3ebb Added support to handle the BuiltIn Updater for 3.0.1 packages. 2018-12-29 13:49:42 +01:00
Taloth Saldono
fb6e4c0130 Various fixes 2018-12-29 13:49:42 +01:00
Taloth Saldono
241c26e099 Purge should use the data folder as specified by debconf 2018-12-29 13:49:42 +01:00
Taloth Saldono
e2ccb4c049 Deal with wrong permissions for folders. 2018-12-29 13:49:42 +01:00
Taloth Saldono
975fe98cbf Moved from /opt back to /usr/lib based on debian policy. 2018-12-29 13:49:42 +01:00
Taloth Saldono
40a7cf32c5 Added debconf to allow user to set user, group and config dir. Only the group is high prio and thus asked for by default. 2018-12-29 13:49:42 +01:00
Taloth Saldono
9e909cafdd Added check in preinst to cancel install if NzbDrone is still running. 2018-12-29 13:49:42 +01:00
Taloth Saldono
db47308762 Tell dpkg that sonarr replaces nzbdrone instead of a pure conflict. 2018-12-29 13:49:42 +01:00
Taloth Saldono
6d41f7895f Move binaries to subdir for easier builtin updater changes. 2018-12-29 13:49:42 +01:00
Taloth Saldono
7cf4c6f655 Use clideps to determine mono dependencies instead of the monolithic libmono-cil-dev. 2018-12-29 13:49:42 +01:00
Taloth Saldono
c63186a798 Use dh_systemd to configure systemd unit installation. 2018-12-29 13:49:42 +01:00
Mark McDowall
a0ce2d7cdf New: Parse release in square brackets at end of file name
Closes #966
2018-12-29 13:08:57 +01:00
Taloth Saldono
de61ecbfd2 Show unknown items in queue
New: Download items from unknown series now appear on the queue and can be imported with Manual Import.
2018-12-29 13:08:57 +01:00
Mark McDowall
5f6f4915a1 Delay import when absolute episode number is missing
New: Delay import is absolute episode number is required and is missing for EpisodeFormat
2018-12-29 13:08:56 +01:00
Mark McDowall
f345977e3f Add upgrade allowed to language and profiles 2018-12-29 13:08:56 +01:00
Mark McDowall
853f25468c Preferred words
New: Ability to prefer releases based on terms in release title
2018-12-29 13:08:56 +01:00
Mark McDowall
ac709c39ab New: Default size limits 2018-12-29 13:08:55 +01:00
Mark McDowall
4939b77a6c Upgrade signalR to 2.4.0 2018-12-29 13:08:55 +01:00
Mark McDowall
ded0caee39 New: Series title first character renaming token 2018-12-29 13:08:55 +01:00
Mark McDowall
3b9ed49d0f New: Option to disable rescanning of series folder after RefreshSeriesInfo
Closes #1592
2018-12-29 13:08:54 +01:00
Mark McDowall
7e79ccd710 Fixed: Finding files with unexpected quality in the filename 2018-12-29 13:08:54 +01:00
Mark McDowall
575c5af1f8 Upgrade SharpRaven to 2.4.0 2018-12-29 13:08:54 +01:00
Mark McDowall
ca079a77ce New: Renaming tokens for IMDB ID, TVDB ID and TV Maze ID
Closes #2659
2018-12-29 13:08:54 +01:00
Mark McDowall
a550186337 New: Choose extension for magnet links in Torrent Blackhole
Closes #2165
2018-12-29 13:08:53 +01:00
Mark McDowall
8594a93cf5 New: Pushover device setting 2018-12-29 13:08:53 +01:00
Mark McDowall
a86397f4bd New: Choose PushBullet device from the UI 2018-12-29 13:08:53 +01:00
Mark McDowall
d52b63e5e9 New: Add tags to Kodi metadata 2018-12-29 13:08:53 +01:00
Mark McDowall
400838c79a New: Series Title with Year renaming token 2018-12-29 13:08:52 +01:00
Mark McDowall
62b03adb53 Removed NotifyMyAndroid and Pushalot
Fixed: Removed NotifyMyAndroid notifications
Fixed: Remove Pushalot notifications
2018-12-29 13:08:52 +01:00
Mark McDowall
ffc49c9049 Fixed: Removed old Media Browser metadata 2018-12-29 13:08:52 +01:00
Mark McDowall
3b042707f5 Interactive Season Search
New: Interactive Season Search
Fixed: BTN will no longer include season packs for individual episode searches
2018-12-29 13:08:52 +01:00
Mark McDowall
36b9c51163 Improved Command Queue
New: Limit concurrent tasks that require disk access
New: Prevent other tasks from running during application update
2018-12-29 13:08:51 +01:00
Mark McDowall
07be9cf47a New: Improved Plex Media Server authentication (Manually update settings) 2018-12-29 13:08:51 +01:00
Mark McDowall
897f3fea99 New: Bluray 1080p and 2160p remux qualities 2018-12-29 13:08:51 +01:00
Mark McDowall
a3b90650be Remove unused references 2018-12-29 13:08:50 +01:00
Mark McDowall
673efe46fb MSBuild 15 2018-12-29 13:08:50 +01:00
Mark McDowall
a17a60f914 Updated Debian package 2018-12-29 13:08:48 +01:00
Mark McDowall
07cbc71aa2 Secure URLs for Skyhook and Services 2018-12-29 13:08:48 +01:00
Mark McDowall
81d6c0d210 New: Backup options and restoration 2018-12-29 13:08:48 +01:00
Mark McDowall
fdbe45c0ab New: Ability to rename using long paths when available 2018-12-29 13:08:47 +01:00
Mark McDowall
5666369cc4 Fixed: Default Windows Service Account 2018-12-29 13:08:47 +01:00
Mark McDowall
e3b3e65409 ESLint and Stylelint during build 2018-12-29 13:08:47 +01:00
Mark McDowall
c3166e08b4 Migrate AppData folder 2018-12-29 13:08:47 +01:00
Mark McDowall
adaf428aa7 v3 Binaries 2018-12-29 13:08:47 +01:00
Mark McDowall
ef70df1db3 Update Logos 2018-12-29 13:08:46 +01:00
Keivan Beigi
c69ca290cf Removed anycpu from sln file 2018-12-29 13:08:46 +01:00
Keivan Beigi
50d4d7a19d removed legacy UI components 2018-12-29 13:08:46 +01:00
Keivan Beigi
ab12c51e0f removed idea folder 2018-12-29 13:08:45 +01:00
Keivan Beigi
e343f8e35e Removed old UI 2018-12-29 13:08:45 +01:00
Mark McDowall
5894b4fd95 v3 UI 2018-12-29 13:08:43 +01:00
Mark McDowall
99feff549d Upgrade Owin to 3.1.0 2018-12-29 13:08:42 +01:00
Mark McDowall
37518349b9 Upgrade Nancy to 1.4.4 2018-12-29 13:08:42 +01:00
Mark McDowall
5b4e194f25 Upgrade signalR to 2.2.2 2018-12-29 13:08:42 +01:00
Mark McDowall
296881b358 Target .net 4.6.1 2018-12-29 13:08:41 +01:00
Mark McDowall
efb9c0791f New: Testing Custom Script executes the script and verifies the exit code 2018-12-29 13:08:41 +01:00
Mark McDowall
acc901455b New: Separate automatic and interactive searches
Closes #253
2018-12-29 13:08:40 +01:00
Mark McDowall
cfb7494992 Removed Drone Factory 2018-12-29 13:08:40 +01:00
Mark McDowall
f31ac39e37 Quality groups 2018-12-29 13:08:39 +01:00
vawen
068ea1e934 New: Language Profiles
Closes #274
2018-12-29 13:08:38 +01:00
Mark McDowall
7297c1b8e4 v3 API 2018-12-29 13:08:37 +01:00
Mark McDowall
211f3769e1 Sonarr.sln 2018-12-29 13:08:23 +01:00
Mark McDowall
2686c78f06 Simplified logo 2018-12-29 13:08:22 +01:00
Mark McDowall
5b385d9900 Build fixes and cleanup 2018-12-29 13:08:22 +01:00
3688 changed files with 136040 additions and 138598 deletions

View File

@@ -2,14 +2,14 @@
# editorconfig.org
root = true
[*.{cs,html,js,hbs}]
[*.{cs}]
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4
[*.less]
[*.{js,html,js,hbs,less,css}]
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

9
.esprintrc Normal file
View File

@@ -0,0 +1,9 @@
{
"paths": [
"frontend/src/**/*.js"
],
"ignored": [
"**/node_modules/**/*"
],
"port": 5004
}

24
.gitattributes vendored
View File

@@ -1,22 +1,12 @@
# Auto detect text files and perform LF normalization
*text eol=lf
* text=auto
# Explicitly set bash scripts to have unix endings
# when checked out on windows
*.sh text eol=lf
distribution/debian/* text eol=lf
macOS/Sonarr text eol=lf
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

11
.gitignore vendored
View File

@@ -45,6 +45,10 @@ _dotCover*
# DevExpress CodeRush
src/.cr/
# Emacs
*~
\#*\#
# NCrunch
*.ncrunch*
.*crunch*.local.xml
@@ -115,12 +119,14 @@ node_modules/
_output*
_rawPackage/
_dotTrace*
_tests/
_tests*
_publish*
_temp*
*.Result.xml
setup/Output/
*.~is
UI.Phantom/
UI/
#VS outout folders
bin
@@ -133,6 +139,5 @@ output/*
.DS_Store
_start
_temp_*/**/*
src/.idea/

4
.gitmodules vendored
View File

@@ -1,4 +0,0 @@
[submodule "src/ExternalModules/CurlSharp"]
path = src/ExternalModules/CurlSharp
url = https://github.com/Sonarr/CurlSharp.git
branch = master

1
.idea/.name generated
View File

@@ -1 +0,0 @@
Sonarr

25
.idea/Sonarr.iml generated
View File

@@ -1,25 +0,0 @@
<?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>

View File

@@ -1,59 +0,0 @@
<?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/encodings.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<includedPredefinedLibrary name="ECMAScript 6" />
</component>
</project>

View File

@@ -1,14 +0,0 @@
<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
View File

@@ -1,14 +0,0 @@
<?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
View File

@@ -1,8 +0,0 @@
<?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
View File

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

2
.yarnrc Normal file
View File

@@ -0,0 +1,2 @@
save-exact true
registry "https://registry.yarnpkg.com"

View File

@@ -7,21 +7,7 @@ Setup guides, FAQ, the more information we have on the wiki the better.
## Development ##
### Tools required ###
- Visual Studio 2015
- HTML/Javascript editor of choice (Sublime Text/Webstorm/Atom/etc)
- npm (node package manager)
- git
### Getting started ###
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 `npm start` - Used to compile the UI components and copy them.
Leave this window open.
If you have gulp globally installed you can use `gulp watch` instead
5. Compile in Visual Studio
See the readme for information on setting up your development environment.
### 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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Logo/72.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 929 B

View File

@@ -1,240 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="218px"
height="218px" viewBox="0 0 218 218" enable-background="new 0 0 218 218" xml:space="preserve">
<symbol id="hex_grid" viewBox="-114.25 -98.617 228.55 197.233">
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#989898" stroke-width="0.5" stroke-linecap="square" stroke-miterlimit="1" d="
M72.15,90.3l4.7-2.7l4.65,2.7v5.4l-4.65,2.7l-4.7-2.7V90.3z M62.85,95.7l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7V95.7l4.65,2.7
l4.65-2.7 M62.85,90.3l4.65-2.7l4.65,2.7 M62.85,79.55v-5.4l4.65-2.7l4.65,2.7v5.4L67.5,82.2L62.85,79.55L58.2,82.2l-4.65-2.65
M72.15,74.15l4.7-2.7l4.65,2.7v5.4l-4.65,2.65l-4.7-2.65 M76.85,87.6v-5.4 M67.5,87.6v-5.4 M81.5,95.7l4.65,2.7l4.65-2.7l4.65,2.7
l4.65-2.7l4.65,2.7l4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7v-5.4l-4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4
l4.65-2.7v-5.4L109.4,31v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7v-5.4l-4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7
V-31l-4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7v-5.4l-4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7v-5.4
l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.7-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7
l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.7-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7L7-98.4l-4.65,2.7l-4.65-2.7
l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.7-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7
l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.7-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7v5.4l-4.65,2.7
v5.4l4.65,2.65v5.4l-4.65,2.7v5.4l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65v5.4l-4.65,2.7v5.4l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65
v5.4l-4.65,2.7v5.4l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65v5.4l-4.65,2.7V31l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65v5.4l-4.65,2.7
v5.4l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65v5.4l-4.65,2.7v5.4l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.7,2.7
l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.7,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7
l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7L7,95.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.7,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7
l4.65-2.7 M44.25,95.7v-5.4l4.65-2.7l4.65,2.7 M44.25,79.55v-5.4l4.65-2.7l4.65,2.7v5.4L48.9,82.2L44.25,79.55L39.6,82.2
l-4.65-2.65 M58.2,87.6v-5.4 M48.9,87.6v-5.4 M53.55,63.35v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7L53.55,63.35l-4.65,2.7l-4.65-2.7
v-5.4l4.65-2.7l4.65,2.7 M62.85,74.15l-4.65-2.7v-5.4 M53.55,74.15l4.65-2.7 M48.9,71.45v-5.4 M48.9,55.25v-5.4l4.65-2.65
l4.65,2.65v5.4 M67.5,71.45v-5.4l4.65-2.7l4.7,2.7v5.4 M67.5,66.05l-4.65-2.7 M58.2,49.85l4.65-2.65l4.65,2.65v5.4l-4.65,2.7
M72.15,63.35v-5.4l4.7-2.7l4.65,2.7v5.4l-4.65,2.7 M76.85,55.25v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M67.5,55.25l4.65,2.7
M34.95,95.7v-5.4l4.65-2.7l4.65,2.7 M16.3,95.7v-5.4l4.65-2.7l4.65,2.7v5.4 M25.6,90.3l4.7-2.7l4.65,2.7 M25.6,79.55v-5.4l4.7-2.7
l4.65,2.7v5.4L30.3,82.2L25.6,79.55l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M20.95,87.6v-5.4 M39.6,87.6v-5.4 M30.3,87.6
v-5.4 M7,95.7v-5.4l4.65-2.7l4.65,2.7 M-2.3,95.7v-5.4l4.65-2.7L7,90.3 M2.35,82.2l-4.65-2.65v-5.4l4.65-2.7L7,74.15v5.4L2.35,82.2
z M16.3,79.55l-4.65,2.65L7,79.55 M2.35,87.6v-5.4 M11.65,87.6v-5.4 M16.3,74.15l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M2.35,71.45
v-5.4L7,63.35l4.65,2.7 M2.35,49.85L7,47.2l4.65,2.65v5.4L7,57.95l-4.65-2.7V49.85L-2.3,47.2v-5.4l4.65-2.7L7,41.8v5.4
M11.65,55.25l4.65,2.7v5.4 M7,74.15l4.65-2.7 M7,57.95v5.4 M30.3,71.45v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M16.3,57.95
l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M30.3,66.05l-4.7-2.7 M30.3,49.85l4.65-2.65l4.65,2.65v5.4l-4.65,2.7l-4.65-2.7V49.85l-4.7-2.65
v-5.4l-4.65-2.7v-5.4L25.6,31l4.7,2.7v5.4l-4.7,2.7 M11.65,49.85l4.65-2.65l4.65,2.65v5.4 M25.6,57.95l4.7-2.7 M34.95,57.95v5.4
M34.95,47.2v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M25.6,31v-5.4l4.7-2.7l4.65,2.7V31l-4.65,2.7 M34.95,25.6l4.65-2.7l4.65,2.7
V31l-4.65,2.7L34.95,31 M30.3,39.1l4.65,2.7 M39.6,39.1v-5.4 M20.95,39.1l-4.65,2.7l-4.65-2.7v-5.4L16.3,31l4.65,2.7 M16.3,41.8
v5.4 M2.35,33.7L-2.3,31v-5.4l4.65-2.7L7,25.6V31L2.35,33.7z M7,25.6l4.65-2.7l4.65,2.7V31 M2.35,39.1v-5.4 M11.65,33.7L7,31
M7,41.8l4.65-2.7 M11.65,17.5L7,14.85v-5.4l4.65-2.7l4.65,2.7v5.4L11.65,17.5z M11.65,22.9v-5.4 M2.35,22.9v-5.4L7,14.85 M7,9.45
l-4.65-2.7v-5.4L7-1.35l4.65,2.7v5.4 M34.95,14.85v-5.4l4.65-2.7l4.65,2.7v5.4L39.6,17.5L34.95,14.85z M39.6,22.9v-5.4 M25.6,25.6
l-4.65-2.7v-5.4l4.65-2.65l4.7,2.65v5.4 M16.3,9.45l4.65-2.7l4.65,2.7v5.4 M34.95,9.45l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4
M11.65,1.35l4.65-2.7l4.65,2.7v5.4 M25.6,9.45l4.7-2.7 M30.3,17.5l4.65-2.65 M16.3,25.6l4.65-2.7 M20.95,17.5l-4.65-2.65
M76.85,49.85l-4.7-2.65v-5.4l4.7-2.7l4.65,2.7v5.4 M62.85,47.2v-5.4l4.65-2.7l4.65,2.7 M62.85,25.6l4.65-2.7l4.65,2.7V31
l-4.65,2.7L62.85,31V25.6l-4.65-2.7v-5.4 M72.15,25.6l4.7-2.7l4.65,2.7V31l-4.65,2.7l-4.7-2.7 M76.85,39.1v-5.4 M67.5,39.1v-5.4
M53.55,47.2v-5.4l4.65-2.7l4.65,2.7 M44.25,41.8l4.65-2.7l4.65,2.7 M44.25,25.6l4.65-2.7l4.65,2.7V31l-4.65,2.7L44.25,31
M62.85,31l-4.65,2.7L53.55,31 M58.2,39.1v-5.4 M48.9,39.1v-5.4 M53.55,14.85v-5.4l4.65-2.7l4.65,2.7v5.4L58.2,17.5L53.55,14.85
L48.9,17.5l-4.65-2.65 M48.9,22.9v-5.4 M53.55,9.45l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M44.25,9.45l4.65-2.7 M76.85,22.9v-5.4
l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M76.85,17.5l-4.7-2.65v-5.4l4.7-2.7l4.65,2.7v5.4 M67.5,22.9v-5.4l4.65-2.65 M67.5,17.5
l-4.65-2.65 M72.15,9.45l-4.65-2.7v-5.4l4.65-2.7l4.7,2.7v5.4 M62.85,9.45l4.65-2.7 M53.55,25.6l4.65-2.7 M44.25,63.35l-4.65,2.7
M39.6,55.25l4.65,2.7 M39.6,71.45l4.65,2.7 M67.5,49.85l4.65-2.65 M48.9,49.85l-4.65-2.65 M25.6,47.2l-4.65,2.65 M104.75,87.6
l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65V87.6l4.65,2.7 M109.4,79.55l-4.65,2.65 M100.1,95.7v-5.4 M81.5,90.3l4.65-2.7
l4.65,2.7v5.4 M81.5,74.15l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65 M90.8,79.55l4.65,2.65 M86.15,87.6v-5.4 M90.8,90.3
l4.65-2.7 M95.45,71.45v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7L95.45,71.45l-4.65,2.7 M86.15,55.25l4.65,2.7v5.4l-4.65,2.7
l-4.65-2.7 M86.15,71.45v-5.4 M95.45,55.25v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7L95.45,55.25l-4.65,2.7 M100.1,63.35v-5.4
M90.8,63.35l4.65,2.7 M109.4,63.35l-4.65,2.7 M104.75,71.45l4.65,2.7 M104.75,55.25l4.65,2.7 M100.1,79.55v-5.4 M100.1,47.2v-5.4
l4.65-2.7l4.65,2.7 M100.1,41.8l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M109.4,31l-4.65,2.7 M81.5,41.8l4.65-2.7l4.65,2.7v5.4
l-4.65,2.65 M86.15,22.9l4.65,2.7V31l-4.65,2.7L81.5,31 M100.1,31v-5.4l4.65-2.7l4.65,2.7 M90.8,31l4.65,2.7 M86.15,39.1v-5.4
M90.8,41.8l4.65-2.7 M86.15,17.5l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M90.8,14.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65
M81.5,9.45l4.65-2.7l4.65,2.7 M86.15,6.75v-5.4l4.65-2.7l4.65,2.7v5.4 M100.1,14.85l4.65,2.65v5.4 M109.4,14.85l-4.65,2.65
M100.1,9.45l4.65-2.7l4.65,2.7 M95.45,1.35l4.65-2.7l4.65,2.7v5.4 M95.45,22.9l4.65,2.7 M109.4,47.2l-4.65,2.65 M90.8,47.2
l4.65,2.65 M104.75-9.45l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65V-9.45l4.65,2.7 M109.4-17.5l-4.65,2.65 M100.1-1.35v-5.4
M90.8-1.35v-5.4l4.65-2.7 M81.5-6.75l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4L81.5-6.75v5.4l-4.65,2.7 M90.8-6.75l-4.65-2.7
M95.45-14.85L90.8-17.5v-5.4l4.65-2.7l4.65,2.7v5.4 M76.85-14.85l-4.7-2.65v-5.4l4.7-2.7l4.65,2.7v5.4 M86.15-14.85l4.65-2.65
M95.45-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L95.45-31z M95.45-25.6V-31 M90.8-22.9l-4.65-2.7V-31l4.65-2.7 M86.15-31
l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M86.15-41.8v-5.4l4.65-2.65l4.65,2.65v5.4 M100.1-33.7l4.65,2.7v5.4l-4.65,2.7 M109.4-33.7
l-4.65,2.7 M95.45-47.2l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M104.75-41.8l4.65,2.7 M81.5-22.9l4.65-2.7 M104.75-25.6l4.65,2.7
M100.1-49.85v-5.4l4.65-2.7l4.65,2.7 M109.4-66.05l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M104.75-63.35v5.4 M100.1-55.25
l-4.65-2.7v-5.4l4.65-2.7 M86.15-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M86.15-74.15l4.65,2.7v5.4l-4.65,2.7l-4.65-2.7v-5.4
L86.15-74.15v-5.4l4.65-2.65l4.65,2.65 M90.8-71.45l4.65-2.7l4.65,2.7 M95.45-63.35l-4.65-2.7 M90.8-55.25l4.65-2.7 M86.15-57.95
v-5.4 M95.45-74.15v-5.4l4.65-2.65l4.65,2.65v5.4 M81.5-71.45l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65 M81.5-82.2v-5.4l4.65-2.7
l4.65,2.7v5.4 M86.15-90.3v-5.4 M104.75-95.7v5.4l-4.65,2.7l-4.65-2.7v-5.4 M100.1-82.2v-5.4 M95.45-90.3l-4.65,2.7 M109.4-82.2
l-4.65,2.65 M104.75-90.3l4.65,2.7 M109.4-49.85l-4.65,2.65 M72.15-1.35v-5.4l4.7-2.7 M67.5,1.35l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7
M72.15-17.5l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M67.5-14.85v5.4 M53.55-1.35v-5.4l4.65-2.7l4.65,2.7 M48.9,1.35
l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M44.25-22.9l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65V-22.9l-4.65-2.7V-31 M53.55-17.5
l4.65,2.65v5.4 M48.9-9.45v-5.4 M53.55-33.7v-5.4l4.65-2.7l4.65,2.7v5.4L58.2-31L53.55-33.7z M62.85-22.9l-4.65-2.7V-31 M48.9-25.6
V-31l4.65-2.7 M48.9-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M48.9-41.8v-5.4l4.65-2.65l4.65,2.65v5.4 M76.85-25.6V-31l4.65-2.7
M76.85-31l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7 M62.85-33.7L67.5-31v5.4 M72.15-39.1l-4.65-2.7v-5.4l4.65-2.65l4.7,2.65v5.4
M62.85-39.1l4.65-2.7 M72.15-33.7L67.5-31 M53.55-22.9l4.65-2.7 M58.2-14.85l4.65-2.65 M30.3,1.35l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7
v5.4 M30.3-9.45v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M16.3-1.35v-5.4l4.65-2.7l4.65,2.7 M30.3-14.85l-4.7-2.65v-5.4l4.7-2.7
l4.65,2.7v5.4 M25.6-17.5l-4.65,2.65L16.3-17.5v-5.4l4.65-2.7l4.65,2.7 M20.95-14.85v5.4 M16.3-6.75l-4.65-2.7v-5.4l4.65-2.65
M2.35,1.35l-4.65-2.7v-5.4l4.65-2.7L7-6.75v5.4 M7-17.5l-4.65,2.65L-2.3-17.5v-5.4l4.65-2.7L7-22.9V-17.5l4.65,2.65 M11.65-9.45
L7-6.75 M2.35-9.45v-5.4 M11.65-31L7-33.7v-5.4l4.65-2.7l4.65,2.7v5.4L11.65-31z M16.3-22.9l-4.65-2.7V-31 M2.35-25.6V-31L7-33.7
M7-39.1l-4.65-2.7v-5.4L7-49.85l4.65,2.65v5.4 M44.25-33.7L39.6-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M20.95-25.6V-31l4.65-2.7
l4.7,2.7v5.4 M20.95-47.2l4.65-2.65l4.7,2.65v5.4l-4.7,2.7l-4.65-2.7V-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M30.3-47.2
l4.65-2.65l4.65,2.65v5.4 M30.3-41.8l4.65,2.7 M25.6-33.7v-5.4 M34.95-33.7L30.3-31 M34.95-22.9l4.65-2.7 M20.95-31l-4.65-2.7
M16.3-39.1l4.65-2.7 M7-22.9l4.65-2.7 M34.95-55.25l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L34.95-55.25v5.4 M25.6-49.85v-5.4
l4.7-2.7 M30.3-63.35l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7v5.4 M25.6-66.05l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M30.3-74.15
v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M20.95-63.35v5.4 M7-49.85v-5.4l4.65-2.7l4.65,2.7 M2.35-47.2l-4.65-2.65v-5.4l4.65-2.7
L7-55.25 M2.35-63.35l-4.65-2.7v-5.4l4.65-2.7L7-71.45v5.4L2.35-63.35z M16.3-71.45l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4
M11.65-57.95v-5.4l4.65-2.7 M2.35-57.95v-5.4 M7-66.05l4.65,2.7 M11.65-74.15L7-71.45 M2.35-74.15v-5.4L7-82.2l4.65,2.65
M11.65-95.7v5.4L7-87.6l-4.65-2.7v-5.4 M20.95-95.7v5.4l-4.65,2.7l-4.65-2.7 M7-87.6v5.4 M16.3-87.6v5.4 M20.95-90.3l4.65,2.7v5.4
l-4.65,2.65 M30.3-79.55l-4.7-2.65 M30.3-95.7v5.4l-4.7,2.7 M48.9-95.7v5.4l-4.65,2.7l-4.65-2.7v-5.4 M34.95-82.2v-5.4l4.65-2.7
M30.3-90.3l4.65,2.7 M72.15-49.85v-5.4l4.7-2.7l4.65,2.7 M67.5-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M67.5-74.15l4.65,2.7v5.4
l-4.65,2.7l-4.65-2.7v-5.4L67.5-74.15v-5.4l4.65-2.65l4.7,2.65 M81.5-66.05l-4.65,2.7l-4.7-2.7 M72.15-71.45l4.7-2.7 M76.85-63.35
v5.4 M67.5-57.95v-5.4 M53.55-49.85v-5.4l4.65-2.7l4.65,2.7 M48.9-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M44.25-66.05v-5.4
l4.65-2.7l4.65,2.7v5.4l-4.65,2.7L44.25-66.05l-4.65,2.7 M62.85-66.05l-4.65,2.7l-4.65-2.7 M53.55-71.45l4.65-2.7l4.65,2.7
M58.2-57.95v-5.4 M48.9-57.95v-5.4 M48.9-74.15v-5.4l4.65-2.65l4.65,2.65v5.4 M48.9-79.55l-4.65-2.65v-5.4 M58.2-95.7v5.4
l-4.65,2.7l-4.65-2.7 M53.55-87.6v5.4 M58.2-79.55l4.65-2.65l4.65,2.65 M62.85-82.2v-5.4l4.65-2.7l4.65,2.7v5.4 M67.5-90.3v-5.4
M76.85-95.7v5.4l-4.7,2.7 M58.2-90.3l4.65,2.7 M44.25-17.5l-4.65,2.65 M39.6-9.45l4.65,2.7 M39.6-74.15l4.65,2.7 M39.6-57.95
l4.65,2.7 M44.25-49.85L39.6-47.2 M62.85-49.85L58.2-47.2 M16.3-49.85l-4.65,2.65 M44.25-82.2l-4.65,2.65 M76.85-90.3l4.65,2.7
M81.5-49.85l-4.65,2.65 M86.15,1.35l-4.65-2.7 M44.25-1.35l-4.65,2.7 M62.85-1.35l-4.65,2.7 M109.4-1.35l-4.65,2.7 M25.6-1.35
l-4.65,2.7 M-95.4,95.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-86.1,90.3l4.7-2.7l4.65,2.7v5.4 M-104.7,95.7v-5.4l4.65-2.7l4.65,2.7
M-100.05,82.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4L-100.05,82.2z M-95.4,74.15l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65
M-86.1,74.15l4.7-2.7l4.65,2.7v5.4l-4.65,2.65l-4.7-2.65 M-100.05,87.6v-5.4 M-90.75,87.6v-5.4 M-81.4,87.6v-5.4 M-109.35,87.6
l4.65,2.7 M-104.7,79.55l-4.65,2.65 M-109.35,55.25l4.65,2.7v5.4l-4.65,2.7 M-109.35,71.45l4.65,2.7 M-90.75,66.05l-4.65-2.7v-5.4
l4.65-2.7l4.65,2.7v5.4L-90.75,66.05v5.4 M-86.1,57.95l4.7-2.7l4.65,2.7v5.4l-4.65,2.7l-4.7-2.7 M-81.4,71.45v-5.4 M-100.05,71.45
v-5.4l4.65-2.7 M-95.4,57.95l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-81.4,55.25v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7
M-100.05,66.05l-4.65-2.7 M-104.7,57.95l4.65-2.7 M-86.1,41.8l-4.65-2.7v-5.4l4.65-2.7l4.7,2.7v5.4L-86.1,41.8z M-81.4,49.85
l-4.7-2.65v-5.4 M-100.05,49.85l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M-95.4,31l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7V31
l4.65,2.7 M-86.1,31v-5.4l4.7-2.7l4.65,2.7V31l-4.65,2.7 M-100.05,39.1v-5.4 M-90.75,39.1l-4.65,2.7 M-109.35,39.1l4.65,2.7
M-104.7,31l-4.65,2.7 M-109.35,6.75l4.65,2.7v5.4l-4.65,2.65 M-86.1,14.85v-5.4l4.7-2.7l4.65,2.7v5.4l-4.65,2.65L-86.1,14.85z
M-81.4,22.9v-5.4 M-86.1,25.6l-4.65-2.7v-5.4l4.65-2.65 M-100.05,22.9v-5.4l4.65-2.65l4.65,2.65 M-100.05,6.75v-5.4l4.65-2.7
l4.65,2.7v5.4l-4.65,2.7L-100.05,6.75z M-81.4,6.75v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M-90.75,6.75l4.65,2.7 M-95.4,14.85v-5.4
M-95.4,25.6l4.65-2.7 M-100.05,17.5l-4.65-2.65 M-104.7,9.45l4.65-2.7 M-109.35,22.9l4.65,2.7 M-86.1,47.2l-4.65,2.65
M-104.7,47.2l-4.65,2.65 M-11.6,95.7v-5.4l4.65-2.7l4.65,2.7 M-20.9,95.7v-5.4l4.65-2.7l4.65,2.7 M-16.25,82.2l-4.65-2.65v-5.4
l4.65-2.7l4.65,2.7v5.4L-16.25,82.2v5.4 M-2.3,79.55l-4.65,2.65l-4.65-2.65 M-6.95,82.2v5.4 M-30.2,95.7v-5.4l4.65-2.7l4.65,2.7
M-39.55,95.7v-5.4l4.7-2.7l4.65,2.7 M-39.55,79.55v-5.4l4.7-2.7l4.65,2.7v5.4l-4.65,2.65L-39.55,79.55l-4.65,2.65l-4.65-2.65
M-20.9,79.55l-4.65,2.65l-4.65-2.65 M-34.85,87.6v-5.4 M-25.55,87.6v-5.4 M-20.9,74.15l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4
M-30.2,74.15l4.65-2.7 M-25.55,66.05l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-39.55,74.15l-4.65-2.7v-5.4l4.65-2.7l4.7,2.7v5.4
M-30.2,57.95l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-39.55,63.35v-5.4l4.7-2.7 M-30.2,63.35l-4.65,2.7 M-11.6,74.15l4.65-2.7
l4.65,2.7 M-6.95,66.05l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L-6.95,66.05v5.4 M-16.25,66.05l4.65-2.7 M-11.6,57.95l-4.65-2.7v-5.4
l4.65-2.65l4.65,2.65v5.4 M-16.25,55.25l-4.65,2.7 M-48.85,95.7v-5.4l4.65-2.7l4.65,2.7 M-58.15,95.7v-5.4l4.65-2.7l4.65,2.7
M-58.15,79.55v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65L-58.15,79.55l-4.65,2.65l-4.65-2.65 M-44.2,87.6v-5.4 M-53.5,87.6v-5.4
M-67.45,95.7v-5.4l4.65-2.7l4.65,2.7 M-76.75,90.3l4.65-2.7l4.65,2.7 M-76.75,74.15l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65
M-62.8,87.6v-5.4 M-72.1,87.6v-5.4 M-67.45,74.15l4.65-2.7l4.65,2.7 M-62.8,71.45v-5.4l4.65-2.7l4.65,2.7v5.4 M-62.8,66.05
l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-76.75,63.35l4.65,2.7v5.4 M-62.8,55.25v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7
M-67.45,63.35l-4.65,2.7 M-72.1,55.25l4.65,2.7 M-48.85,74.15l4.65-2.7 M-44.2,66.05l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7
M-53.5,49.85l4.65-2.65l4.65,2.65v5.4 M-53.5,66.05l4.65-2.7 M-53.5,55.25l4.65,2.7 M-48.85,47.2v-5.4l4.65-2.7l4.65,2.7v5.4
l-4.65,2.65 M-58.15,47.2v-5.4l4.65-2.7l4.65,2.7 M-58.15,25.6l4.65-2.7l4.65,2.7V31l-4.65,2.7l-4.65-2.7V25.6l-4.65-2.7v-5.4
M-48.85,25.6l4.65-2.7l4.65,2.7V31l-4.65,2.7l-4.65-2.7 M-44.2,39.1v-5.4 M-53.5,39.1v-5.4 M-62.8,49.85l-4.65-2.65v-5.4l4.65-2.7
l4.65,2.7 M-76.75,47.2v-5.4l4.65-2.7l4.65,2.7 M-76.75,25.6l4.65-2.7l4.65,2.7V31l-4.65,2.7l-4.65-2.7 M-58.15,31l-4.65,2.7
l-4.65-2.7 M-72.1,39.1v-5.4 M-62.8,39.1v-5.4 M-67.45,14.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65L-67.45,14.85l-4.65,2.65
l-4.65-2.65 M-72.1,22.9v-5.4 M-62.8,6.75v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M-72.1,6.75l4.65,2.7 M-44.2,22.9v-5.4l4.65-2.65
l4.7,2.65v5.4l-4.7,2.7 M-44.2,17.5l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M-48.85,14.85l-4.65,2.65l-4.65-2.65 M-53.5,22.9v-5.4
M-44.2,6.75v-5.4l4.65-2.7l4.7,2.7v5.4l-4.7,2.7 M-53.5,6.75l4.65,2.7 M-67.45,25.6l4.65-2.7 M-11.6,47.2v-5.4l4.65-2.7l4.65,2.7
M-11.6,41.8l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-16.25,33.7L-20.9,31v-5.4l4.65-2.7l4.65,2.7V31 M-2.3,31l-4.65,2.7
M-30.2,47.2v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M-39.55,41.8l4.7-2.7l4.65,2.7 M-34.85,22.9l4.65,2.7V31l-4.65,2.7l-4.7-2.7
M-20.9,31l-4.65,2.7L-30.2,31 M-34.85,39.1v-5.4 M-25.55,39.1v-5.4 M-20.9,25.6l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4
M-25.55,17.5l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M-25.55,6.75v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M-30.2,14.85l-4.65,2.65
M-34.85,6.75l4.65,2.7 M-6.95,17.5l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4L-6.95,17.5v5.4l-4.65,2.7 M-11.6,14.85l-4.65,2.65
M-16.25,6.75l4.65,2.7 M-16.25,1.35l4.65-2.7l4.65,2.7v5.4 M-6.95,22.9l4.65,2.7 M-30.2,25.6l4.65-2.7 M-16.25,39.1l-4.65,2.7
M-67.45,47.2l-4.65,2.65 M-2.3,47.2l-4.65,2.65 M-34.85,49.85l-4.7-2.65 M-16.25,49.85l-4.65-2.65 M-81.4,39.1l4.65,2.7
M-11.6-1.35v-5.4l4.65-2.7l4.65,2.7 M-11.6-6.75l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-16.25-14.85l-4.65-2.65v-5.4l4.65-2.7
l4.65,2.7v5.4 M-2.3-17.5l-4.65,2.65 M-20.9-1.35v-5.4l4.65-2.7 M-20.9-6.75l-4.65-2.7v-5.4l4.65-2.65 M-25.55-9.45l-4.65,2.7
l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65 M-30.2-6.75v5.4l-4.65,2.7 M-39.55-1.35v-5.4l4.7-2.7 M-34.85-14.85l-4.7-2.65v-5.4l4.7-2.7
l4.65,2.7v5.4 M-30.2-33.7v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7L-30.2-33.7l-4.65,2.7l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7 M-20.9-22.9
l-4.65-2.7V-31 M-34.85-25.6V-31 M-39.55-39.1l-4.65-2.7v-5.4l4.65-2.65l4.7,2.65v5.4 M-25.55-41.8v-5.4l4.65-2.65l4.65,2.65v5.4
l-4.65,2.7 M-6.95-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L-6.95-31v5.4l-4.65,2.7 M-16.25-25.6V-31l4.65-2.7 M-16.25-41.8
l4.65,2.7 M-16.25-47.2l4.65-2.65l4.65,2.65v5.4 M-30.2-22.9l4.65-2.7 M-16.25-31l-4.65-2.7 M-6.95-25.6l4.65,2.7 M-44.2,1.35
l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M-58.15-1.35v-5.4l4.65-2.7l4.65,2.7 M-58.15-6.75l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4
M-62.8-14.85l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M-39.55-17.5l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M-44.2-9.45v-5.4
M-53.5-14.85l4.65-2.65 M-62.8,1.35l-4.65-2.7v-5.4l4.65-2.7 M-76.75-6.75l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4L-76.75-6.75
v5.4 M-76.75-17.5v-5.4l4.65-2.7l4.65,2.7 M-67.45-17.5l-4.65,2.65 M-72.1-9.45l4.65,2.7 M-67.45-33.7v-5.4l4.65-2.7l4.65,2.7v5.4
L-62.8-31L-67.45-33.7z M-62.8-25.6V-31 M-72.1-25.6V-31l4.65-2.7 M-72.1-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M-76.75-39.1
l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-62.8-41.8v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M-44.2-25.6V-31l4.65-2.7 M-44.2-31
l-4.65-2.7v-5.4l4.65-2.7 M-48.85-33.7L-53.5-31l-4.65-2.7 M-48.85-22.9l-4.65-2.7V-31 M-53.5-41.8l4.65,2.7 M-58.15-22.9l4.65-2.7
M-58.15-49.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M-48.85-55.25l4.65-2.7l4.65,2.7v5.4 M-58.15-71.45l4.65-2.7l4.65,2.7v5.4
l-4.65,2.7l-4.65-2.7V-71.45z M-48.85-71.45l4.65-2.7l4.65,2.7v5.4l-4.65,2.7l-4.65-2.7 M-44.2-57.95v-5.4 M-53.5-57.95v-5.4
M-76.75-49.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M-67.45-55.25l4.65-2.7l4.65,2.7 M-76.75-55.25l-4.65-2.7v-5.4l4.65-2.7
l4.65,2.7v5.4 M-81.4-63.35l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7v5.4 M-81.4-74.15v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7
M-58.15-66.05l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M-62.8-57.95v-5.4 M-72.1-74.15l4.65,2.7 M-67.45-66.05l-4.65,2.7
M-67.45-82.2v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65L-67.45-82.2l-4.65,2.65 M-76.75-82.2v-5.4l4.65-2.7l4.65,2.7 M-72.1-90.3
v-5.4 M-62.8-90.3v-5.4 M-53.5-74.15v-5.4l4.65-2.65l4.65,2.65v5.4 M-58.15-82.2l4.65,2.65 M-58.15-87.6l4.65-2.7l4.65,2.7v5.4
M-53.5-90.3v-5.4 M-44.2-95.7v5.4l-4.65,2.7 M-62.8-74.15v-5.4 M-11.6-49.85v-5.4l4.65-2.7l4.65,2.7 M-20.9-49.85v-5.4l4.65-2.7
l4.65,2.7 M-16.25-63.35l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L-16.25-63.35v5.4 M-2.3-66.05l-4.65,2.7l-4.65-2.7 M-11.6-71.45
l4.65-2.7l4.65,2.7 M-6.95-63.35v5.4 M-25.55-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M-39.55-55.25l4.7-2.7l4.65,2.7
M-39.55-71.45l4.7-2.7l4.65,2.7v5.4l-4.65,2.7l-4.7-2.7 M-20.9-71.45l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-20.9-66.05
l-4.65,2.7l-4.65-2.7 M-25.55-74.15l-4.65,2.7 M-34.85-63.35v5.4 M-25.55-57.95v-5.4 M-34.85-74.15v-5.4l4.65-2.65l4.65,2.65
M-44.2-79.55l4.65-2.65l4.7,2.65 M-39.55-82.2v-5.4l4.7-2.7l4.65,2.7v5.4 M-34.85-90.3v-5.4 M-16.25-95.7v5.4l-4.65,2.7l-4.65-2.7
v-5.4 M-25.55-90.3l-4.65,2.7 M-20.9-82.2v-5.4 M-6.95-79.55l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4L-6.95-79.55v5.4 M-16.25-79.55
l4.65-2.65 M-11.6-87.6l-4.65-2.7 M-6.95-95.7v5.4 M-44.2-90.3l4.65,2.7 M-62.8-47.2l-4.65-2.65 M-44.2-47.2l-4.65-2.65
M-30.2-49.85l-4.65,2.65 M-2.3-49.85l-4.65,2.65 M-95.4-1.35v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M-86.1-6.75l4.7-2.7
M-100.05,1.35l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M-95.4-17.5l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7V-17.5z M-95.4-22.9
l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65 M-81.4-14.85l-4.7-2.65 M-100.05-9.45v-5.4 M-90.75-14.85v5.4 M-109.35-9.45
l4.65,2.7 M-104.7-17.5l-4.65,2.65 M-109.35-41.8l4.65,2.7v5.4l-4.65,2.7 M-90.75-25.6V-31l4.65-2.7l4.7,2.7v5.4l-4.7,2.7
M-100.05-25.6V-31l4.65-2.7l4.65,2.7 M-100.05-47.2l4.65-2.65l4.65,2.65v5.4l-4.65,2.7l-4.65-2.7V-47.2l-4.65-2.65 M-90.75-41.8
l4.65,2.7v5.4 M-86.1-39.1l4.7-2.7 M-95.4-33.7v-5.4 M-109.35-25.6l4.65,2.7 M-100.05-31l-4.65-2.7 M-104.7-39.1l4.65-2.7
M-95.4-49.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M-86.1-55.25l4.7-2.7 M-95.4-55.25l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4
M-100.05-63.35l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-95.4-71.45l4.65-2.7l4.65,2.7 M-86.1-66.05l-4.65,2.7 M-109.35-57.95
l4.65,2.7v5.4l-4.65,2.65 M-109.35-74.15l4.65,2.7 M-104.7-66.05l-4.65,2.7 M-109.35-90.3l4.65,2.7v5.4l-4.65,2.65 M-81.4-79.55
l-4.7-2.65v-5.4l4.7-2.7l4.65,2.7 M-86.1-82.2l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M-100.05-74.15v-5.4l4.65-2.65
M-95.4-87.6l-4.65-2.7v-5.4 M-81.4-95.7v5.4 M-90.75-95.7v5.4 M-90.75-79.55v5.4 M-104.7-55.25l4.65-2.7 M-100.05-79.55
l-4.65-2.65 M-104.7-87.6l4.65-2.7 M-81.4-47.2l-4.7-2.65 M-76.75-33.7L-81.4-31 M-81.4-25.6l4.65,2.7 M-67.45-1.35l-4.65,2.7
M-104.7-1.35l-4.65,2.7 M-81.4,1.35l-4.7-2.7 M-25.55,1.35l-4.65-2.7 M-53.5,1.35l4.65-2.7 M-2.3-1.35l-4.65,2.7 M-2.3,57.95
l4.65-2.7 M2.35,66.05l-4.65-2.7 M-2.3-39.1l4.65-2.7 M2.35-31l-4.65-2.7 M2.35-79.55L-2.3-82.2 M-2.3-87.6l4.65-2.7 M-2.3,9.45
l4.65-2.7 M2.35,17.5l-4.65-2.65"/>
</symbol>
<g id="Layer_1">
</g>
<g id="Layer_6">
<path fill-rule="evenodd" clip-rule="evenodd" fill="#EFEEEE" d="M217.5,108.95c0,29.833-10.533,55.399-31.6,76.7
c-0.7,0.833-1.484,1.6-2.351,2.3c-3.466,3.399-7.134,6.483-11,9.25c-18.267,13.467-39.366,20.2-63.3,20.2
c-23.967,0-45.033-6.733-63.2-20.2c-4.8-3.4-9.3-7.25-13.5-11.55c-16.367-16.267-26.417-35.167-30.15-56.7
c-0.733-4.2-1.217-8.467-1.45-12.8c-0.1-2.4-0.15-4.801-0.15-7.2c0-2.534,0.05-4.95,0.15-7.25c0-0.233,0.066-0.467,0.2-0.7
c1.567-26.6,12.033-49.583,31.4-68.95C53.85,11.017,79.417,0.5,109.25,0.5c29.934,0,55.483,10.517,76.65,31.55
C206.967,53.483,217.5,79.117,217.5,108.95z"/>
</g>
<g id="Layer_5">
<path fill-rule="evenodd" clip-rule="evenodd" fill="#010101" d="M195.45,43l-22.4,22.4c-8.833,13-13.25,27.867-13.25,44.6
c0,17.934,5.067,33.833,15.2,47.7l19,18.95c-2.5,3.066-5.2,6.066-8.1,9c-0.7,0.833-1.484,1.6-2.351,2.3
c-2.533,2.5-5.167,4.816-7.899,6.95L158.1,177.35c-13.934-10.733-30.133-16.1-48.6-16.1c-17.933,0-33.833,5.1-47.7,15.3
L43.25,195.15c-3.767-2.867-7.333-6.034-10.7-9.5c-2.8-2.801-5.417-5.667-7.85-8.601l19.15-19.2
c10.066-13.966,15.1-29.916,15.1-47.85c0-17.5-4.867-33.017-14.6-46.55l-21.05-21c2.833-3.6,5.917-7.067,9.25-10.4
c2.934-2.867,5.934-5.55,9-8.05L61.9,44.35C75.7,54.583,91.567,59.7,109.5,59.7c18.467,0,34.666-5.367,48.6-16.1L177.4,24.35
c2.899,2.367,5.732,4.933,8.5,7.7C189.367,35.583,192.55,39.233,195.45,43z"/>
</g>
<g id="Layer_4">
<defs>
<path id="SVGID_1_" d="M159.8,110c0-16.733,4.417-31.6,13.25-44.6l22.4-22.4c-2.9-3.767-6.083-7.417-9.55-10.95
c-2.768-2.767-5.601-5.333-8.5-7.7L158.1,43.6c-13.934,10.733-30.133,16.1-48.6,16.1c-17.933,0-33.8-5.117-47.6-15.35L41.55,24
c-3.066,2.5-6.066,5.183-9,8.05c-3.333,3.333-6.417,6.8-9.25,10.4l21.05,21c9.733,13.533,14.6,29.05,14.6,46.55
c0,17.934-5.034,33.884-15.1,47.85l-19.15,19.2c2.433,2.934,5.05,5.8,7.85,8.601c3.367,3.466,6.934,6.633,10.7,9.5L61.8,176.55
c13.867-10.2,29.767-15.3,47.7-15.3c18.467,0,34.666,5.366,48.6,16.1L175.65,194.9c2.732-2.134,5.366-4.45,7.899-6.95
c0.866-0.7,1.65-1.467,2.351-2.3c2.899-2.934,5.6-5.934,8.1-9l-19-18.95C164.867,143.833,159.8,127.934,159.8,110z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<use xlink:href="#hex_grid" width="228.55" height="197.233" x="-114.25" y="-98.617" transform="matrix(1.1415 0 0 -1.1415 105.5 107.75)" overflow="visible"/>
</g>
</g>
<g id="Layer_2">
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#35C6F4" d="M79.1,110.95c-0.033-0.667-0.05-1.333-0.05-2
c0-0.7,0.017-1.366,0.05-2c0-0.067,0.017-0.134,0.05-0.2c0.434-7.367,3.333-13.733,8.7-19.1c5.9-5.833,12.983-8.75,21.25-8.75
c8.301,0,15.384,2.917,21.25,8.75c5.834,5.934,8.75,13.033,8.75,21.3c0,8.267-2.916,15.35-8.75,21.25
c-0.199,0.233-0.416,0.45-0.649,0.649c-0.967,0.934-1.983,1.784-3.05,2.551c-5.066,3.733-10.917,5.6-17.551,5.6
c-6.633,0-12.466-1.866-17.5-5.6c-1.333-0.934-2.583-2-3.75-3.2c-4.533-4.5-7.317-9.733-8.35-15.7
C79.3,113.334,79.167,112.15,79.1,110.95z M126.1,127.25l3.601,3.6L126.1,127.25z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#35C6F4" stroke-width="2" stroke-miterlimit="1" d="
M158.6,60.25l-15,14.65 M31.7,33.1l40.75,40.65 M126.1,127.25l3.601,3.6 M157.05,158l27.65,28.6 M153.05,153.95l-10.75-11.2
M186.6,33l-28,27.25 M33.15,186.25l27.35-27.4"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#35C6F4" stroke-width="7" stroke-miterlimit="1" d="
M158.6,60.25l-16.949,17.2 M59.4,61.35L76.6,78.5 M60.5,158.85l16.75-17.399 M153.05,153.95l4,4.05 M139.45,140.4l13.6,13.55"/>
</g>
</g>
</svg>
<svg height="216.9" viewBox="0 0 216.7 216.9" width="216.7" xmlns="http://www.w3.org/2000/svg">
<path clip-rule="evenodd" d="M216.7 108.45c0 29.833-10.533 55.4-31.6 76.7-.7.833-1.483 1.6-2.35 2.3-3.466 3.4-7.133 6.484-11 9.25-18.267 13.467-39.367 20.2-63.3 20.2-23.967 0-45.033-6.733-63.2-20.2-4.8-3.4-9.3-7.25-13.5-11.55-16.367-16.266-26.417-35.167-30.15-56.7-.733-4.2-1.217-8.467-1.45-12.8-.1-2.4-.15-4.8-.15-7.2 0-2.533.05-4.95.15-7.25 0-.233.066-.467.2-.7 1.567-26.6 12.033-49.583 31.4-68.95C53.05 10.517 78.617 0 108.45 0c29.933 0 55.484 10.517 76.65 31.55 21.067 21.433 31.6 47.067 31.6 76.9z" fill="#EEE" fill-rule="evenodd"/>
<path clip-rule="evenodd" d="M194.65 42.5l-22.4 22.4C159.152 77.998 158 89.4 158 109.5c0 17.934 2.852 34.352 16.2 47.7 9.746 9.746 19 18.95 19 18.95-2.5 3.067-5.2 6.067-8.1 9-.7.833-1.483 1.6-2.35 2.3-2.533 2.5-5.167 4.817-7.9 6.95l-17.55-17.55c-15.598-15.6-27.996-17.1-48.6-17.1-19.77 0-33.223 1.822-47.7 16.3-8.647 8.647-18.55 18.6-18.55 18.6-3.767-2.867-7.333-6.034-10.7-9.5-2.8-2.8-5.417-5.667-7.85-8.6 0 0 9.798-9.848 19.15-19.2 13.852-13.853 16.1-29.916 16.1-47.85 0-17.5-2.874-33.823-15.6-46.55-8.835-8.836-21.05-21-21.05-21 2.833-3.6 5.917-7.067 9.25-10.4 2.934-2.867 5.934-5.55 9-8.05L61.1 43.85C74.102 56.852 90.767 60.2 108.7 60.2c18.467 0 35.077-3.577 48.6-17.1 8.32-8.32 19.3-19.25 19.3-19.25 2.9 2.367 5.733 4.933 8.5 7.7 3.467 3.533 6.65 7.183 9.55 10.95z" fill="#3A3F51" fill-rule="evenodd"/>
<g clip-rule="evenodd">
<path d="M78.7 114c-.2-1.167-.332-2.35-.4-3.55-.032-.667-.05-1.333-.05-2 0-.7.018-1.367.05-2 0-.067.018-.133.05-.2.435-7.367 3.334-13.733 8.7-19.1 5.9-5.833 12.984-8.75 21.25-8.75 8.3 0 15.384 2.917 21.25 8.75 5.834 5.934 8.75 13.033 8.75 21.3 0 8.267-2.916 15.35-8.75 21.25-.2.233-.416.45-.65.65-.966.933-1.982 1.783-3.05 2.55-5.065 3.733-10.916 5.6-17.55 5.6s-12.466-1.866-17.5-5.6c-1.332-.934-2.582-2-3.75-3.2-4.532-4.5-7.316-9.734-8.35-15.7z" fill="#0CF" fill-rule="evenodd"/>
<path d="M157.8 59.75l-15 14.65M30.785 32.526L71.65 73.25m84.6 84.25l27.808 28.78m1.855-153.894L157.8 59.75m-125.45 126l27.35-27.4" fill="none" stroke="#0CF" stroke-miterlimit="1" stroke-width="2"/>
<path d="M157.8 59.75l-16.95 17.2M58.97 60.604l17.2 17.15M59.623 158.43l16.75-17.4m61.928-1.396l18.028 17.945" fill="none" stroke="#0CF" stroke-miterlimit="1" stroke-width="7"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

9
Logo/sonarr-simple.svg Normal file
View File

@@ -0,0 +1,9 @@
<svg height="216.9" viewBox="0 0 216.7 216.9" width="216.7" xmlns="http://www.w3.org/2000/svg">
<path clip-rule="evenodd" d="M216.7 108.45c0 29.833-10.533 55.4-31.6 76.7-.7.833-1.483 1.6-2.35 2.3-3.466 3.4-7.133 6.484-11 9.25-18.267 13.467-39.367 20.2-63.3 20.2-23.967 0-45.033-6.733-63.2-20.2-4.8-3.4-9.3-7.25-13.5-11.55-16.367-16.266-26.417-35.167-30.15-56.7-.733-4.2-1.217-8.467-1.45-12.8-.1-2.4-.15-4.8-.15-7.2 0-2.533.05-4.95.15-7.25 0-.233.066-.467.2-.7 1.567-26.6 12.033-49.583 31.4-68.95C53.05 10.517 78.617 0 108.45 0c29.933 0 55.484 10.517 76.65 31.55 21.067 21.433 31.6 47.067 31.6 76.9z" fill="#EEE" fill-rule="evenodd"/>
<path clip-rule="evenodd" d="M194.65 42.5l-22.4 22.4C159.152 77.998 158 89.4 158 109.5c0 17.934 2.852 34.352 16.2 47.7 9.746 9.746 19 18.95 19 18.95-2.5 3.067-5.2 6.067-8.1 9-.7.833-1.483 1.6-2.35 2.3-2.533 2.5-5.167 4.817-7.9 6.95l-17.55-17.55c-15.598-15.6-27.996-17.1-48.6-17.1-19.77 0-33.223 1.822-47.7 16.3-8.647 8.647-18.55 18.6-18.55 18.6-3.767-2.867-7.333-6.034-10.7-9.5-2.8-2.8-5.417-5.667-7.85-8.6 0 0 9.798-9.848 19.15-19.2 13.852-13.853 16.1-29.916 16.1-47.85 0-17.5-2.874-33.823-15.6-46.55-8.835-8.836-21.05-21-21.05-21 2.833-3.6 5.917-7.067 9.25-10.4 2.934-2.867 5.934-5.55 9-8.05L61.1 43.85C74.102 56.852 90.767 60.2 108.7 60.2c18.467 0 35.077-3.577 48.6-17.1 8.32-8.32 19.3-19.25 19.3-19.25 2.9 2.367 5.733 4.933 8.5 7.7 3.467 3.533 6.65 7.183 9.55 10.95z" fill="#3A3F51" fill-rule="evenodd"/>
<g clip-rule="evenodd">
<path d="M78.7 114c-.2-1.167-.332-2.35-.4-3.55-.032-.667-.05-1.333-.05-2 0-.7.018-1.367.05-2 0-.067.018-.133.05-.2.435-7.367 3.334-13.733 8.7-19.1 5.9-5.833 12.984-8.75 21.25-8.75 8.3 0 15.384 2.917 21.25 8.75 5.834 5.934 8.75 13.033 8.75 21.3 0 8.267-2.916 15.35-8.75 21.25-.2.233-.416.45-.65.65-.966.933-1.982 1.783-3.05 2.55-5.065 3.733-10.916 5.6-17.55 5.6s-12.466-1.866-17.5-5.6c-1.332-.934-2.582-2-3.75-3.2-4.532-4.5-7.316-9.734-8.35-15.7z" fill="#0CF" fill-rule="evenodd"/>
<path d="M157.8 59.75l-15 14.65M30.785 32.526L71.65 73.25m84.6 84.25l27.808 28.78m1.855-153.894L157.8 59.75m-125.45 126l27.35-27.4" fill="none" stroke="#0CF" stroke-miterlimit="1" stroke-width="2"/>
<path d="M157.8 59.75l-16.95 17.2M58.97 60.604l17.2 17.15M59.623 158.43l16.75-17.4m61.928-1.396l18.028 17.945" fill="none" stroke="#0CF" stroke-miterlimit="1" stroke-width="7"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,52 +1,73 @@
# Sonarr
# <img width="24px" src="./Logo/256.png" alt="Sonarr"></img> Sonarr
Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.
## Major Features Include:
## Getting Started
* Support for major platforms: Windows, Linux, macOS, 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*
* Automatic failed download handling will try another release if one fails
* Manual search so you can pick any release or to see why a release was not downloaded automatically
* Fully configurable episode renaming
* Full integration with SABnzbd and NZBGet
* Full integration with Kodi, Plex (notification, library update, metadata)
* Full support for specials and multi-episode releases
* And a beautiful UI
- [Download](https://sonarr.tv/#download) (Linux, MacOS, Windows, Docker, etc.)
- [Installation](https://github.com/Sonarr/Sonarr/wiki/Installation)
- [FAQ](https://github.com/Sonarr/Sonarr/wiki/FAQ)
- [Wiki](https://github.com/Sonarr/Sonarr/wiki)
- [API Documentation](https://github.com/Sonarr/Sonarr/wiki/API)
## Support
- [Donate](https://sonarr.tv/donate)
- [Discord](https://discord.gg/M6BvZn5)
- [Reddit](https://www.reddit.com/r/sonarr)
## Features
### Current Features
- Support for major platforms: Windows, Linux, macOS, 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*
- Automatic failed download handling will try another release if one fails
- Manual search so you can pick any release or to see why a release was not downloaded automatically
- Fully configurable episode renaming
- Full integration with SABnzbd and NZBGet
- Full integration with Kodi, Plex (notification, library update, metadata)
- Full support for specials and multi-episode releases
- And a beautiful UI
## Configuring Development Environment:
### Requirements
* Visual Studio 2015 (https://www.visualstudio.com/vs/)
* [Git](https://git-scm.com/downloads)
* [NodeJS](https://nodejs.org/en/download/)
- [Visual Studio 2017](https://www.visualstudio.com/vs)
- [Git](https://git-scm.com/downloads)
- [NodeJS](https://nodejs.org/en/download)
- [Yarn](https://yarnpkg.com)
### Setup
* Make sure all the required software mentioned above are installed.
* Clone the repository into your development machine. [*info*](https://help.github.com/articles/working-with-repositories)
* Grab the submodules `git submodule init && git submodule update`
* Install the required Node Packages `npm install`
* Start gulp to monitor your dev environment for any changes that need post processing using `npm start` command.
- Make sure all the required software mentioned above are installed
- Clone the repository recursively to get Sonarr and it's submodules
- You can do this by running `git clone --recursive https://github.com/Sonarr/Sonarr.git`
- Install the required Node Packages using `yarn`
*Please note gulp must be running at all times while you are working with Sonarr client source files.*
### Backend Development
### Development
- Run `yarn build` to build the UI
- Open `Sonarr.sln` in Visual Studio
- Make sure `Sonarr.Console` is set as the startup project
- Build `Sonarr.Windows` and `Sonarr.Mono` projects
- Build Solution
* Open `NzbDrone.sln` in Visual Studio
* Make sure `NzbDrone.Console` is set as the startup project
### UI Development
### License
- Run `yarn watch` to build UI and rebuild automatically when changes are detected
- Run Sonarr.Console.exe (or debug in Visual Studio)
* [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
* Copyright 2010-2017
### Licenses
- [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
- Copyright 2010-2020
### Sponsors
* [JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools
* [ReSharper](http://www.jetbrains.com/resharper/)
* [WebStorm](http://www.jetbrains.com/webstorm/)
* [TeamCity](http://www.jetbrains.com/teamcity/)
- [JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools
- [ReSharper](http://www.jetbrains.com/resharper/)
- [TeamCity](http://www.jetbrains.com/teamcity/)

View File

@@ -1 +0,0 @@
Write-Warning "DEPRECATED -- Please use build.sh instead."

378
build.sh
View File

@@ -1,17 +1,22 @@
#! /bin/bash
msBuild='/c/Program Files (x86)/MSBuild/14.0/Bin'
msBuildVersion='15.0'
outputFolder='./_output'
outputFolderMono='./_output_mono'
outputFolderOsx='./_output_osx'
outputFolderOsxApp='./_output_osx_app'
testPackageFolder='./_tests/'
testSearchPattern='*.Test/bin/x86/Release'
outputFolderWindows='./_output_windows'
outputFolderLinux='./_output_linux'
outputFolderMacOS='./_output_macos'
outputFolderMacOSApp='./_output_macos_app'
testPackageFolder='./_tests'
testPackageFolderWindows='./_tests_windows'
testPackageFolderLinux='./_tests_linux'
sourceFolder='./src'
slnFile=$sourceFolder/NzbDrone.sln
updateFolder=$outputFolder/NzbDrone.Update
updateFolderMono=$outputFolderMono/NzbDrone.Update
slnFile=$sourceFolder/Sonarr.sln
updateSubFolder=Sonarr.Update
nuget='tools/nuget/nuget.exe';
vswhere='tools/vswhere/vswhere.exe';
. ./version.sh
CheckExitCode()
{
"$@"
@@ -23,12 +28,44 @@ CheckExitCode()
return $status
}
ProgressStart()
{
echo "##teamcity[blockOpened name='$1']"
echo "##teamcity[progressStart '$1']"
}
ProgressEnd()
{
echo "##teamcity[progressFinish '$1']"
echo "##teamcity[blockClosed name='$1']"
}
UpdateVersionNumber()
{
if [ "$BUILD_NUMBER" != "" ]; then
echo "Updating Version Info"
verMajorMinorRevision=`echo "$buildVersion" | cut -d. -f1,2,3`
verBuild=`echo "${BUILD_NUMBER}" | cut -d. -f4`
BUILD_NUMBER=$verMajorMinorRevision.$verBuild
echo "##teamcity[buildNumber '$BUILD_NUMBER']"
sed -i "s/<AssemblyVersion>[0-9.*]\+<\/AssemblyVersion>/<AssemblyVersion>$BUILD_NUMBER<\/AssemblyVersion>/g" ./src/Directory.Build.props
sed -i "s/<AssemblyConfiguration>[\$()A-Za-z-]\+<\/AssemblyConfiguration>/<AssemblyConfiguration>${BRANCH:-dev}<\/AssemblyConfiguration>/g" ./src/Directory.Build.props
fi
}
CreateReleaseInfo()
{
if [ "$BUILD_NUMBER" != "" ]; then
echo "Create Release Info"
echo -e "# Do Not Edit\nReleaseVersion=$BUILD_NUMBER\nBranch=${BRANCH:-dev}" > $outputFolder/release_info
fi
}
CleanFolder()
{
local path=$1
local keepConfigFiles=$2
find $path -name "*.transform" -exec rm "{}" \;
if [ $keepConfigFiles != true ] ; then
@@ -39,9 +76,6 @@ CleanFolder()
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 "{}" \;
@@ -54,8 +88,15 @@ CleanFolder()
BuildWithMSBuild()
{
export PATH=$msBuild:$PATH
CheckExitCode MSBuild.exe $slnFile //t:Clean //m
msBuildPath=`$vswhere -latest -products \* -requires Microsoft.Component.MSBuild -find MSBuild\\\\\*\*\\\\Bin\\\\MSBuild.exe`
msBuildPath=${msBuildPath/C:\\/\/c\/}
msBuildPath=${msBuildPath//\\/\/}
msBuildDir=$(dirname "$msBuildPath")
echo $msBuildDir
export PATH=$msBuildDir:$PATH
CheckExitCode MSBuild.exe $slnFile //p:Configuration=Release //p:Platform=x86 //t:Clean //m
$nuget restore $slnFile
CheckExitCode MSBuild.exe $slnFile //p:Configuration=Release //p:Platform=x86 //t:Build //m //p:AllowedReferenceRelatedFileExtensions=.pdb
}
@@ -63,16 +104,28 @@ BuildWithMSBuild()
BuildWithXbuild()
{
export MONO_IOMAP=case
CheckExitCode xbuild /t:Clean $slnFile
CheckExitCode msbuild /t:Clean $slnFile
mono $nuget restore $slnFile
CheckExitCode xbuild /p:Configuration=Release /p:Platform=x86 /t:Build /p:AllowedReferenceRelatedFileExtensions=.pdb $slnFile
CheckExitCode msbuild /p:Configuration=Release /p:Platform=x86 /t:Build /p:AllowedReferenceRelatedFileExtensions=.pdb $slnFile
}
LintUI()
{
ProgressStart 'ESLint'
CheckExitCode yarn lint
ProgressEnd 'ESLint'
ProgressStart 'Stylelint'
CheckExitCode yarn stylelint
ProgressEnd 'Stylelint'
}
Build()
{
echo "##teamcity[progressStart 'Build']"
ProgressStart 'Build'
rm -rf $outputFolder
rm -rf $testPackageFolder
if [ $runtime = "dotnet" ] ; then
BuildWithMSBuild
@@ -85,18 +138,20 @@ Build()
echo "Removing Mono.Posix.dll"
rm $outputFolder/Mono.Posix.dll
echo "##teamcity[progressFinish 'Build']"
ProgressEnd 'Build'
}
RunGulp()
{
echo "##teamcity[progressStart 'npm install']"
npm-cache install npm || CheckExitCode npm install
echo "##teamcity[progressFinish 'npm install']"
ProgressStart 'yarn install'
yarn install
ProgressEnd 'yarn install'
echo "##teamcity[progressStart 'Running gulp']"
CheckExitCode npm run build
echo "##teamcity[progressFinish 'Running gulp']"
LintUI
ProgressStart 'Running gulp'
CheckExitCode yarn run build --production
ProgressEnd 'Running gulp'
}
CreateMdbs()
@@ -116,121 +171,252 @@ CreateMdbs()
fi
}
PatchMono()
{
local path=$1
# Below we deal with some mono incompatibilities with windows-only dotnet core/standard libs
# See: https://github.com/mono/mono/blob/master/tools/nuget-hash-extractor/download.sh
# That list defines assemblies that are prohibited from being loaded from the appdir, instead loading from mono GAC.
# We have debian dependencies to get these installed or facades from mono 5.10+
for assembly in System.IO.Compression System.Runtime.InteropServices.RuntimeInformation System.Net.Http System.Globalization.Extensions System.Text.Encoding.CodePages System.Threading.Overlapped
do
if [ -e $path/$assembly.dll ]; then
if [ -e $sourceFolder/Libraries/Mono/$assembly.dll ]; then
echo "Copy Mono-specific facade $assembly.dll (uses win32 interop)"
cp $sourceFolder/Libraries/Mono/$assembly.dll $path/$assembly.dll
else
echo "Remove $assembly.dll (uses win32 interop)"
rm $path/$assembly.dll
fi
fi
done
# Copy more stable version of Vectors for mono <5.12
if [ -e $path/System.Numerics.Vectors.dll ]; then
packageDir="$HOME/.nuget/packages/system.numerics.vectors/4.5.0"
if [ ! -d "$HOME/.nuget/packages/system.numerics.vectors/4.5.0" ]; then
# May reside in the NuGetFallback folder, which is harder to find
# Download somewhere to get the real cache populated
if [ $runtime = "dotnet" ] ; then
$nuget install System.Numerics.Vectors -Version 4.5.0 -Output ./_temp/System.Numerics.Vectors
else
mono $nuget install System.Numerics.Vectors -Version 4.5.0 -Output ./_temp/System.Numerics.Vectors
fi
rm -rf ./_temp/System.Numerics.Vectors
fi
# Copy the netstandard2.0 version rather than net46
cp "$packageDir/lib/netstandard2.0/System.Numerics.Vectors.dll" $path/
fi
}
PackageMono()
{
echo "##teamcity[progressStart 'Creating Mono Package']"
rm -rf $outputFolderMono
cp -r $outputFolder $outputFolderMono
ProgressStart 'Creating Mono Package'
rm -rf $outputFolderLinux
echo "Copying Binaries"
cp -r $outputFolder $outputFolderLinux
echo "Creating MDBs"
CreateMdbs $outputFolderMono
CreateMdbs $outputFolderLinux
echo "Removing PDBs"
find $outputFolderMono -name "*.pdb" -exec rm "{}" \;
find $outputFolderLinux -name "*.pdb" -exec rm "{}" \;
echo "Removing Service helpers"
rm -f $outputFolderMono/ServiceUninstall.*
rm -f $outputFolderMono/ServiceInstall.*
rm -f $outputFolderLinux/ServiceUninstall.*
rm -f $outputFolderLinux/ServiceInstall.*
echo "Removing native windows binaries Sqlite, MediaInfo"
rm -f $outputFolderMono/sqlite3.*
rm -f $outputFolderMono/MediaInfo.*
rm -f $outputFolderLinux/sqlite3.*
rm -f $outputFolderLinux/MediaInfo.*
echo "Adding NzbDrone.Core.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Core/NzbDrone.Core.dll.config $outputFolderMono
PatchMono $outputFolderLinux
echo "Adding CurlSharp.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Common/CurlSharp.dll.config $outputFolderMono
echo "Adding Sonarr.Core.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Core/Sonarr.Core.dll.config $outputFolderLinux
echo "Renaming NzbDrone.Console.exe to NzbDrone.exe"
rm $outputFolderMono/NzbDrone.exe*
for file in $outputFolderMono/NzbDrone.Console.exe*; do
# Remove Http binding redirect by renaming it
# We don't need this anymore once our minimum mono version is 5.10
sed -i "s/System.Net.Http/System.Net.Http.Mono/g" $outputFolderLinux/Sonarr.Console.exe.config
echo "Renaming Sonarr.Console.exe to Sonarr.exe"
rm $outputFolderLinux/Sonarr.exe*
for file in $outputFolderLinux/Sonarr.Console.exe*; do
mv "$file" "${file//.Console/}"
done
echo "Removing NzbDrone.Windows"
rm $outputFolderMono/NzbDrone.Windows.*
echo "Removing Sonarr.Windows"
rm $outputFolderLinux/Sonarr.Windows.*
echo "Adding NzbDrone.Mono to UpdatePackage"
cp $outputFolderMono/NzbDrone.Mono.* $updateFolderMono
echo "Adding Sonarr.Mono to UpdatePackage"
cp $outputFolderLinux/Sonarr.Mono.* $outputFolderLinux/$updateSubFolder/
echo "##teamcity[progressFinish 'Creating Mono Package']"
ProgressEnd 'Creating Mono Package'
}
PackageOsx()
PackageMacOS()
{
echo "##teamcity[progressStart 'Creating OS X Package']"
rm -rf $outputFolderOsx
cp -r $outputFolderMono $outputFolderOsx
ProgressStart 'Creating MacOS Package'
echo "Adding sqlite dylibs"
cp $sourceFolder/Libraries/Sqlite/*.dylib $outputFolderOsx
echo "Adding MediaInfo dylib"
cp $sourceFolder/Libraries/MediaInfo/*.dylib $outputFolderOsx
rm -rf $outputFolderMacOS
mkdir $outputFolderMacOS
echo "Adding Startup script"
cp ./osx/Sonarr $outputFolderOsx
cp ./macOS/Sonarr $outputFolderMacOS
dos2unix $outputFolderMacOS/Sonarr
echo "##teamcity[progressFinish 'Creating OS X Package']"
echo "Copying Binaries"
cp -r $outputFolderLinux/* $outputFolderMacOS
echo "Adding sqlite dylibs"
cp $sourceFolder/Libraries/Sqlite/*.dylib $outputFolderMacOS
echo "Adding MediaInfo dylib"
cp $sourceFolder/Libraries/MediaInfo/*.dylib $outputFolderMacOS
ProgressEnd 'Creating MacOS Package'
}
PackageOsxApp()
PackageMacOSApp()
{
echo "##teamcity[progressStart 'Creating OS X App Package']"
rm -rf $outputFolderOsxApp
mkdir $outputFolderOsxApp
ProgressStart 'Creating macOS App Package'
cp -r ./osx/Sonarr.app $outputFolderOsxApp
cp -r $outputFolderOsx $outputFolderOsxApp/Sonarr.app/Contents/MacOS
rm -rf $outputFolderMacOSApp
mkdir $outputFolderMacOSApp
cp -r ./macOS/Sonarr.app $outputFolderMacOSApp
mkdir -p $outputFolderMacOSApp/Sonarr.app/Contents/MacOS
echo "##teamcity[progressFinish 'Creating OS X App Package']"
echo "Adding Startup script"
cp ./macOS/Sonarr $outputFolderMacOSApp/Sonarr.app/Contents/MacOS
dos2unix $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/Sonarr
echo "Copying Binaries"
cp -r $outputFolderLinux/* $outputFolderMacOSApp/Sonarr.app/Contents/MacOS
echo "Adding sqlite dylibs"
cp $sourceFolder/Libraries/Sqlite/*.dylib $outputFolderMacOSApp/Sonarr.app/Contents/MacOS
echo "Adding MediaInfo dylib"
cp $sourceFolder/Libraries/MediaInfo/*.dylib $outputFolderMacOSApp/Sonarr.app/Contents/MacOS
echo "Removing Update Folder"
rm -r $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/Sonarr.Update
ProgressEnd 'Creating macOS App Package'
}
PackageTests()
PackageTestsMono()
{
echo "Packaging Tests"
echo "##teamcity[progressStart 'Creating Test Package']"
rm -rf $testPackageFolder
mkdir $testPackageFolder
ProgressStart 'Creating Mono Test Package'
find $sourceFolder -path $testSearchPattern -exec cp -r -u -T "{}" $testPackageFolder \;
rm -rf $testPackageFolderLinux
echo "Copying Binaries"
cp -r $testPackageFolder $testPackageFolderLinux
if [ $runtime = "dotnet" ] ; then
$nuget install NUnit.ConsoleRunner -Version 3.2.0 -Output $testPackageFolder
$nuget install NUnit.ConsoleRunner -Version 3.10.0 -Output $testPackageFolderLinux
else
mono $nuget install NUnit.ConsoleRunner -Version 3.2.0 -Output $testPackageFolder
mono $nuget install NUnit.ConsoleRunner -Version 3.10.0 -Output $testPackageFolderLinux
fi
cp $outputFolder/*.dll $testPackageFolder
cp ./*.sh $testPackageFolder
echo "Creating MDBs"
CreateMdbs $testPackageFolderLinux
echo "Creating MDBs for tests"
CreateMdbs $testPackageFolder
echo "Removing PDBs"
find $testPackageFolderLinux -name "*.pdb" -exec rm "{}" \;
rm -f $testPackageFolder/*.log.config
PatchMono $testPackageFolderLinux
CleanFolder $testPackageFolder true
echo "Adding Sonarr.Core.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Core/Sonarr.Core.dll.config $testPackageFolderLinux
echo "Adding NzbDrone.Core.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Core/NzbDrone.Core.dll.config $testPackageFolder
# Remove Http binding redirect by renaming it
# We don't need this anymore once our minimum mono version is 5.10
sed -i "s/System.Net.Http/System.Net.Http.Mono/g" $testPackageFolderLinux/Sonarr.Common.Test.dll.config
echo "Adding CurlSharp.dll.config (for dllmap)"
cp $sourceFolder/NzbDrone.Common/CurlSharp.dll.config $testPackageFolder
cp ./test.sh $testPackageFolderLinux/
dos2unix $testPackageFolderLinux/test.sh
echo "Copying CurlSharp libraries"
cp $sourceFolder/ExternalModules/CurlSharp/libs/i386/* $testPackageFolder
echo "Removing Sonarr.Windows"
rm $testPackageFolderLinux/Sonarr.Windows.*
echo "##teamcity[progressFinish 'Creating Test Package']"
rm -f $testPackageFolderLinux/*.log.config
CleanFolder $testPackageFolderLinux true
ProgressEnd 'Creating Linux Test Package'
}
CleanupWindowsPackage()
PackageTestsWindows()
{
echo "Removing NzbDrone.Mono"
rm -f $outputFolder/NzbDrone.Mono.*
ProgressStart 'Creating Windows Test Package'
echo "Adding NzbDrone.Windows to UpdatePackage"
cp $outputFolder/NzbDrone.Windows.* $updateFolder
rm -rf $testPackageFolderWindows
echo "Copying Binaries"
cp -r $testPackageFolder $testPackageFolderWindows
if [ $runtime = "dotnet" ] ; then
$nuget install NUnit.ConsoleRunner -Version 3.10.0 -Output $testPackageFolderWindows
else
mono $nuget install NUnit.ConsoleRunner -Version 3.10.0 -Output $testPackageFolderWindows
fi
cp ./test.sh $testPackageFolderWindows
echo "Removing Sonarr.Mono"
rm -f $testPackageFolderWindows/Sonarr.Mono.*
rm -f $testPackageFolderWindows/*.log.config
CleanFolder $testPackageFolderWindows true
ProgressEnd 'Creating Windows Test Package'
}
PackageWindows()
{
ProgressStart 'Creating Windows Package'
rm -rf $outputFolderWindows
echo "Copying Binaries"
cp -r $outputFolder $outputFolderWindows
echo "Removing Sonarr.Mono"
rm -f $outputFolderWindows/Sonarr.Mono.*
echo "Adding Sonarr.Windows to UpdatePackage"
cp $outputFolderWindows/Sonarr.Windows.* $outputFolderWindows/$updateSubFolder/
ProgressEnd 'Creating Windows Package'
}
PublishArtifacts()
{
ProgressStart 'Publishing Artifacts'
# Tests
echo "##teamcity[publishArtifacts '$testPackageFolderWindows/** => tests.windows.zip']"
echo "##teamcity[publishArtifacts '$testPackageFolderLinux/** => tests.linux.zip']"
# Releases
echo "##teamcity[publishArtifacts '$outputFolderWindows/** => Sonarr.$BRANCH.$BUILD_NUMBER.windows.zip!Sonarr']"
echo "##teamcity[publishArtifacts '$outputFolderLinux/** => Sonarr.$BRANCH.$BUILD_NUMBER.linux.tar.gz!Sonarr']"
echo "##teamcity[publishArtifacts '$outputFolderMacOS/** => Sonarr.$BRANCH.$BUILD_NUMBER.macos.tar.gz!Sonarr']"
echo "##teamcity[publishArtifacts '$outputFolderMacOSApp/** => Sonarr.$BRANCH.$BUILD_NUMBER.macos.zip']"
# Debian Package
echo "##teamcity[publishArtifacts 'distribution/** => distribution.zip']"
ProgressEnd 'Publishing Artifacts'
}
# Use mono or .net depending on OS
@@ -245,10 +431,14 @@ case "$(uname -s)" in
;;
esac
UpdateVersionNumber
Build
CreateReleaseInfo
RunGulp
PackageMono
PackageOsx
PackageOsxApp
PackageTests
CleanupWindowsPackage
PackageMacOS
PackageMacOSApp
PackageTestsMono
PackageTestsWindows
PackageWindows
PublishArtifacts

5
debian/changelog vendored
View File

@@ -1,5 +0,0 @@
nzbdrone {version} {branch}; urgency=low
* Automatic Release.
-- NzbDrone <contact@nzbdrone.com> Mon, 26 Aug 2013 00:00:00 -0700

12
debian/control vendored
View File

@@ -1,12 +0,0 @@
Section: web
Priority: optional
Maintainer: Sonarr <contact@nzbdrone.com>
Source: nzbdrone
Homepage: https://sonarr.tv
Vcs-Git: git@github.com:Sonarr/Sonarr.git
Vcs-Browser: https://github.com/Sonarr/Sonarr
Package: nzbdrone
Architecture: all
Depends: libmono-cil-dev (>= 3.2), sqlite3 (>= 3.7), mediainfo (>= 0.7.52)
Description: Sonarr is an internet PVR

1
debian/install vendored
View File

@@ -1 +0,0 @@
nzbdrone_bin/* opt/NzbDrone

13
debian/rules vendored
View File

@@ -1,13 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@

View File

@@ -0,0 +1,7 @@
# Note, this script is only used for local dev tests, this is not the script used for building the official sonarr package
mkdir -p /${PWD}/../_output_debian
docker build -f docker-build/Dockerfile -t sonarr-packager ./docker-build
docker run --rm -v /${PWD}/../_output_linux:/data/sonarr_bin:ro -v /${PWD}:/data/build -v /${PWD}/../_output_debian:/data/output sonarr-packager

63
distribution/debian.sh Normal file
View File

@@ -0,0 +1,63 @@
fromdos ./debian/*
cp -r ./debian ./debian_backup
BuildVersion=${dependent_build_number:-3.10.0.999}
BuildBranch=${dependent_build_branch:-master}
BootstrapVersion=`echo "$BuildVersion" | cut -d. -f1,2,3`
BootstrapUpdater="BuiltIn"
PackageUpdater="apt"
echo Version: "$BuildVersion" Branch: "$BuildBranch"
rm -r ./sonarr_bin/Sonarr.Update
chmod -R ugo-x,ugo+rwX,go-w ./sonarr_bin/*
echo Updating changelog for $BuildVersion
sed -i "s:{version}:$BuildVersion:g; s:{branch}:$BuildBranch:g;" debian/changelog
sed -i "s:{version}:$BuildVersion:g; s:{updater}:$PackageUpdater:g" debian/preinst debian/postinst debian/postrm
sed -i '/#BEGIN BUILTIN UPDATER/,/#END BUILTIN UPDATER/d' debian/preinst debian/postinst debian/postrm
echo "# Do Not Edit\nPackageVersion=$BuildVersion\nReleaseVersion=$BuildVersion\nUpdateMethod=$PackageUpdater\nBranch=$BuildBranch" > package_info
echo Running debuild for $BuildVersion
if [ -z "${TEST_OUTPUT}" ]; then
debuild -b
else
debuild -us -uc -b
fi
# Restore debian directory to the original files
rm -rf ./debian
mv ./debian_backup ./debian
echo Updating changelog for $BootstrapVersion
sed -i "s:{version}:$BootstrapVersion:g; s:{branch}:$BuildBranch:g;" debian/changelog
sed -i "s:{version}:$BuildVersion:g; s:{updater}:$BootstrapUpdater:g" debian/preinst debian/postinst debian/postrm
sed -i '/#BEGIN BUILTIN UPDATER/d; /#END BUILTIN UPDATER/d' debian/preinst debian/postinst debian/postrm
echo "# Do Not Edit\nPackageVersion=$BootstrapVersion\nReleaseVersion=$BuildVersion\nUpdateMethod=$BootstrapUpdater\nBranch=$BuildBranch" > package_info
echo Running debuild for $BootstrapVersion
if [ -z "${TEST_OUTPUT}" ]; then
debuild -b
else
debuild -us -uc -b
fi
echo Moving stuff around
mv ../sonarr_*.deb ./
mv ../sonarr_*.changes ./
rm ../sonarr_*.build
if [ -z "${TEST_OUTPUT}" ]; then
echo Signing Package
dpkg-sig -k 884589CE --sign builder "sonarr_${BuildVersion}_all.deb"
dpkg-sig -k 884589CE --sign builder "sonarr_${BootstrapVersion}_all.deb"
echo running alien
alien -r -v ./*.deb
else
echo "Exporting packages to ${TEST_OUTPUT}"
dpkg -e "sonarr_${BuildVersion}_all.deb" ${TEST_OUTPUT}/sonarr-build
dpkg -e "sonarr_${BootstrapVersion}_all.deb" ${TEST_OUTPUT}/sonarr-release
cp *.deb ${TEST_OUTPUT}/
fi

View File

@@ -0,0 +1,6 @@
[*]
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2

View File

@@ -0,0 +1,5 @@
sonarr ({version}) {branch}; urgency=low
* Automatic Release.
-- Sonarr <hello@sonarr.tv> Sun, 28 Jan 2018 00:00:00 -0700

View File

@@ -0,0 +1,14 @@
#!/bin/sh -e
. /usr/share/debconf/confmodule
db_beginblock
db_input high sonarr/owning_user || true
db_input high sonarr/owning_group || true
db_endblock
db_go
db_input low sonarr/config_directory || true
db_go
exit 0

View File

@@ -0,0 +1,22 @@
Section: web
Priority: optional
Maintainer: Sonarr <hello@sonarr.tv>
Source: sonarr
Homepage: https://sonarr.tv
Vcs-Git: git@github.com:Sonarr/Sonarr.git
Vcs-Browser: https://github.com/Sonarr/Sonarr
Build-Depends: debhelper (>= 9),
dh-systemd (>= 1.5),
mono-devel (>= 5.18),
libmono-cil-dev (>= 5.18),
cli-common-dev (>= 0.9+xamarin5)
Package: sonarr
Architecture: all
Provides: nzbdrone
Conflicts: nzbdrone
Replaces: nzbdrone
Depends: adduser, libsqlite3-0 (>= 3.7), libmediainfo0v5 (>= 0.7.52) | libmediainfo0 (>= 0.7.52), mono-runtime (>= 5.18), ca-certificates-mono, libmono-system-net-http4.0-cil (>= 4.0.0~alpha1), ${cli:Depends}, ${misc:Depends}
Recommends: libmediainfo0v5 (>= 18.03) | libmediainfo0 (>= 18.03)
Suggests: sqlite3 (>= 3.7), mediainfo (>= 0.7.52)
Description: Internet PVR

48
debian/copyright → distribution/debian/copyright Executable file → Normal file
View File

@@ -1,24 +1,24 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: nzbdrone
Source: https://github.com/Sonarr/Sonarr
Files: *
Copyright: 2010-2016 Sonarr <hello@sonarr.tv>
License: GPL-3.0+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: sonarr
Source: https://github.com/Sonarr/Sonarr
Files: *
Copyright: 2010-2016 Sonarr <hello@sonarr.tv>
License: GPL-3.0+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".

View File

@@ -0,0 +1 @@
sonarr_3.0.0.0_all.deb web optional

View File

@@ -0,0 +1,2 @@
sonarr_bin/* usr/lib/sonarr/bin
package_info usr/lib/sonarr

View File

@@ -0,0 +1,107 @@
#!/bin/sh
set -e
BUILD_VERSION={version}
UPDATER={updater}
. /usr/share/debconf/confmodule
db_get sonarr/owning_user
USER="$RET"
db_get sonarr/owning_group
GROUP="$RET"
db_get sonarr/config_directory
CONFDIR="$RET"
# Add User and Group
if ! getent group "$GROUP" >/dev/null; then
groupadd "$GROUP"
fi
if ! getent passwd "$USER" >/dev/null; then
adduser --system --no-create-home --ingroup "$GROUP" "$USER"
fi
if [ $1 = "configure" ]; then
# Migrate old Sonarr v3 alpha data dir from /var/opt/sonarr or user home
if [ -d "/var/opt/sonarr" ] && [ "$CONFDIR" != "/var/opt/sonarr" ] && [ ! -d "$CONFDIR" ]; then
varoptRoot="/var/opt/sonarr"
varoptAppData="$varoptRoot/.config/Sonarr"
sonarrUserHome=`getent passwd $USER | cut -d ':' -f 6`
sonarrAppData="$sonarrUserHome/.config/Sonarr"
if [ -f "$varoptRoot/sonarr.db" ]; then
# Handle /var/opt/sonarr/sonarr.db
mv "$varoptRoot" "$CONFDIR"
elif [ -f "$varoptAppData/sonarr.db" ]; then
# Handle /var/opt/sonarr/.config/Sonarr/sonarr.db
mv "$varoptAppData" "$CONFDIR"
rm -rf "$varoptRoot"
elif [ -f "$sonarrAppData/sonarr.db" ]; then
# Handle ~/.config/Sonarr/sonarr.db
mv "$sonarrAppData" "$CONFDIR"
rm -rf "$sonarrAppData"
else
mv "$varoptRoot" "$CONFDIR"
fi
chown -R $USER:$GROUP "$CONFDIR"
chmod -R 775 "$CONFDIR"
fi
# Migrate old NzbDrone data dir
if [ -d "/usr/lib/sonarr/nzbdrone-appdata" ] && [ ! -d "$CONFDIR" ]; then
NZBDRONE_DATA=`readlink /usr/lib/sonarr/nzbdrone-appdata`
if [ -f "$NZBDRONE_DATA/config.xml" ] && [ -f "$NZBDRONE_DATA/nzbdrone.db" ]; then
echo "Found NzbDrone database in $NZBDRONE_DATA, copying to $CONFDIR."
mkdir -p "$CONFDIR"
cp $NZBDRONE_DATA/config.xml $NZBDRONE_DATA/nzbdrone.db* "$CONFDIR/"
chown -R $USER:$GROUP "$CONFDIR"
chmod -R 775 "$CONFDIR"
else
echo "Missing NzbDrone database in $NZBDRONE_DATA, skipping migration."
fi
rm /usr/lib/sonarr/nzbdrone-appdata
fi
fi
# Create data directory
if [ ! -d "$CONFDIR" ]; then
mkdir -p "$CONFDIR"
chown -R $USER:$GROUP "$CONFDIR"
fi
#BEGIN BUILTIN UPDATER
# Apply patch if present
if [ "$UPDATER" = "BuiltIn" ] && [ -f /usr/lib/sonarr/bin_patch/release_info ]; then
# It shouldn't be possible to get a wrong bin_patch, but let's check anyway and throw it away if it's wrong
currentVersion=`cat /usr/lib/sonarr/bin_patch/release_info | grep 'ReleaseVersion=' | cut -d= -f 2`
currentRelease=`echo "$currentVersion" | cut -d. -f1,2,3`
currentBuild=`echo "$currentVersion" | cut -d. -f4`
targetVersion=$BUILD_VERSION
targetRelease=`echo "$targetVersion" | cut -d. -f1,2,3`
targetBuild=`echo "$targetVersion" | cut -d. -f4`
if [ "$currentRelease" = "$targetRelease" ] && [ "$currentBuild" -gt "$targetBuild" ]; then
echo "Applying $currentVersion from BuiltIn updater instead of downgrading to $targetVersion"
rm -rf /usr/lib/sonarr/bin
mv /usr/lib/sonarr/bin_patch /usr/lib/sonarr/bin
else
rm -rf /usr/lib/sonarr/bin_patch
fi
fi
#END BUILTIN UPDATER
# Set permissions on /usr/lib/sonarr
chown -R $USER:$GROUP /usr/lib/sonarr
# Update sonarr.service file
sed -i "s:User=sonarr:User=$USER:g; s:Group=sonarr:Group=$GROUP:g; s:-data=/var/lib/sonarr:-data=$CONFDIR:g" /lib/systemd/system/sonarr.service
#BEGIN BUILTIN UPDATER
if [ "$UPDATER" = "BuiltIn" ]; then
# If we upgraded, signal Sonarr to do an update check on startup instead of scheduled.
touch $CONFDIR/update_required
chown $USER:$GROUP $CONFDIR/update_required
fi
#END BUILTIN UPDATER
#DEBHELPER#
exit 0

View File

@@ -0,0 +1,36 @@
#!/bin/sh
set -e
BUILD_VERSION={version}
UPDATER={updater}
if [ $1 = "abort-install" ]; then
# preinst was aborted, possibly due to NzbDrone still running.
# Nothing to do here
:
fi
# The bin directory is expected to be empty, unless the BuiltIn updater added files.
if [ $1 = "remove" ] && [ -d /usr/lib/sonarr/bin ]; then
rm -rf /usr/lib/sonarr/bin
fi
#BEGIN BUILTIN UPDATER
# Remove any existing patch if still present
if [ $1 = "remove" ] && [ -d /usr/lib/sonarr/bin_patch ]; then
rm -rf /usr/lib/sonarr/bin_patch
fi
#END BUILTIN UPDATER
# Purge the entire sonarr configuration directory.
# TODO: Maybe move a minimal backup to tmp?
if [ $1 = "purge" ] && [ -e /usr/share/debconf/confmodule ]; then
. /usr/share/debconf/confmodule
db_get sonarr/config_directory
CONFDIR="$RET"
if [ -d "$CONFDIR" ]; then
rm -rf "$CONFDIR"
fi
fi
#DEBHELPER#

View File

@@ -0,0 +1,91 @@
#!/bin/sh
set -e
BUILD_VERSION={version}
UPDATER={updater}
# Deal with existing nzbdrone installs
#
# Existing nzbdrone packages do not have startup scripts and the process might still be running.
# If the user manually installed nzbdrone then the process might still be running too.
if [ $1 = "install" ]; then
psNzbDrone=`ps ax -o'user,pid,ppid,unit,args' | grep mono.*NzbDrone\\\\.exe || true`
if [ ! -z "$psNzbDrone" ]; then
# Get the user and optional systemd unit
psNzbDroneUser=`echo "$psNzbDrone" | tr -s ' ' | cut -d ' ' -f 1`
psNzbDroneUnit=`echo "$psNzbDrone" | tr -s ' ' | cut -d ' ' -f 4`
# Get the appdata from the cmdline or get it from the user dir
droneAppData=`echo "$psNzbDrone" | tr ' ' '\n' | grep -- "-data=" | cut -d= -f 2`
if [ "$droneAppData" = "" ]; then
droneUserHome=`getent passwd $psNzbDroneUser | cut -d ':' -f 6`
droneAppData="$droneUserHome/.config/NzbDrone"
fi
if [ "$psNzbDroneUnit" != "-" ] && [ -d /run/systemd/system ]; then
if [ "$psNzbDroneUnit" = "sonarr.service" ]; then
# Conflicts with our new sonarr.service so we have to remove it
echo "NzbDrone systemd startup detected at $psNzbDroneUnit, stopping and removing..."
deb-systemd-invoke stop $psNzbDroneUnit >/dev/null
if [ -f "/etc/systemd/system/$psNzbDroneUnit" ]; then
rm /etc/systemd/system/$psNzbDroneUnit
fi
if [ -f "/usr/lib/systemd/system/$psNzbDroneUnit" ]; then
rm /usr/lib/systemd/system/$psNzbDroneUnit
fi
deb-systemd-helper purge $psNzbDroneUnit >/dev/null
deb-systemd-helper unmask $psNzbDroneUnit >/dev/null
systemctl --system daemon-reload >/dev/null || true
else
# Just disable it, so the user can revisit the settings later
echo "NzbDrone systemd startup detected at $psNzbDroneUnit, stopping and disabling..."
deb-systemd-invoke stop $psNzbDroneUnit >/dev/null
deb-systemd-invoke mask $psNzbDroneUnit >/dev/null
fi
else
# We don't support auto migration for other startup methods, so bail.
# This leaves the sonarr package in an incomplete state.
echo "ps: $psNzbDrone"
echo "Error: An existing Sonarr v2 (NzbDrone) process is running. Remove the NzbDrone auto-startup prior to installing sonarr."
exit 1
fi
# We don't have the debconf configuration yet so we can't migrate the data.
# Instead we symlink so postinst knows where it's at.
if [ -f "/usr/lib/sonarr/nzbdrone-appdata" ]; then
rm "/usr/lib/sonarr/nzbdrone-appdata"
else
mkdir -p "/usr/lib/sonarr"
fi
ln -s $droneAppData /usr/lib/sonarr/nzbdrone-appdata
fi
fi
#BEGIN BUILTIN UPDATER
# Check for supported upgrade paths
if [ $1 = "upgrade" ] && [ "$UPDATER" = "BuiltIn" ] && [ -f /usr/lib/sonarr/bin/release_info ]; then
# If we allow the Built-In updater to upgrade from 3.0.1.123 to 3.0.2.500 and now apt is catching up to 3.0.2.425
# then we need to deal with that 500->425 'downgrade'.
# We do that by preserving the binaries and using those instead for postinst.
currentVersion=`cat /usr/lib/sonarr/bin/release_info | grep 'ReleaseVersion=' | cut -d= -f 2`
currentRelease=`echo "$currentVersion" | cut -d. -f1,2,3`
currentBuild=`echo "$currentVersion" | cut -d. -f4`
targetVersion=$BUILD_VERSION
targetRelease=`echo "$targetVersion" | cut -d. -f1,2,3`
targetBuild=`echo "$targetVersion" | cut -d. -f4`
if [ -d /usr/lib/sonarr/bin_patch ]; then
rm -rf /usr/lib/sonarr/bin_patch
fi
# Check if the existing version is already an upgrade for the included build
if [ "$currentRelease" = "$targetRelease" ] && [ "$currentBuild" -gt "$targetBuild" ]; then
echo "Preserving $currentVersion from BuiltIn updater instead of downgrading to $targetVersion"
cp -r /usr/lib/sonarr/bin /usr/lib/sonarr/bin_patch
fi
fi
#END BUILTIN UPDATER
#DEBHELPER#
exit 0

21
distribution/debian/rules Normal file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/make -f
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
EXCLUDE_MODULEREFS = crypt32 httpapi __Internal ole32.dll libmonosgen-2.0 clr mscorlib mscoree.dll Microsoft.DiaSymReader.Native.x86.dll Microsoft.DiaSymReader.Native.amd64.dll
%:
dh $@ --with=systemd --with=cli
# No init script, only systemd
override_dh_installinit:
true
# Sonarr likes debug symbols for logging
override_dh_clistrip:
override_dh_makeclilibs:
override_dh_clideps:
dh_clideps -d -r $(patsubst %,--exclude-moduleref=%,$(EXCLUDE_MODULEREFS))

View File

@@ -0,0 +1,2 @@
ignores msbuild
ignores libmediainfo0v5

View File

@@ -0,0 +1,17 @@
[Unit]
Description=Sonarr Daemon
After=network.target
[Service]
User=sonarr
Group=sonarr
UMask=002
Type=simple
ExecStart=/usr/bin/mono --debug /usr/lib/sonarr/bin/Sonarr.exe -nobrowser -data=/var/lib/sonarr
TimeoutStopSec=20
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,21 @@
Template: sonarr/owning_user
Type: string
Default: sonarr
Description: Sonarr user:
Specify the user that is used to run Sonarr. The user will be created if it does not already exist.
The default 'sonarr' should work fine for most users. You can specify the user group next.
Template: sonarr/owning_group
Type: string
Default: sonarr
Description: Sonarr group:
Specify the group that is used to run Sonarr. The group will be created if it does not already exist.
If the user doesn't already exist then this group will be used as the user's primary group.
Any media files created by Sonarr will be writeable by this group.
It's advisable to keep the group the same between download client, Sonarr and media centers.
Template: sonarr/config_directory
Type: string
Default: /var/lib/sonarr
Description: Config directory:
Specify the directory where Sonarr stores the internal database and metadata. Media content will be stored elsewhere.

View File

@@ -0,0 +1,23 @@
FROM ubuntu:xenial AS builder
ENV DEBIAN_FRONTEND noninteractive
ENV MONO_VERSION 5.18
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \
echo "deb http://download.mono-project.com/repo/debian stable-xenial/snapshots/$MONO_VERSION main" > /etc/apt/sources.list.d/mono-official-stable.list && \
apt-get update && apt-get install -y \
devscripts build-essential tofrodos \
dh-make dh-systemd \
cli-common-dev \
mono-complete \
sqlite3 libcurl3 mediainfo
RUN apt-cache policy mono-complete
RUN apt-cache policy cli-common-dev
COPY debian-start.sh /debian-start.sh
RUN fromdos /debian-start.sh
WORKDIR /data
VOLUME [ "/data/sonarr_bin", "/data/build", "/data/output" ]
CMD /debian-start.sh

View File

@@ -0,0 +1,18 @@
echo "Debian Build Dev bootstrap..."
export TEST_OUTPUT=/data/output
mkdir ${TEST_OUTPUT}
mkdir /data/temp
cp -rf /data/build/debian.sh /data/temp
cp -rf /data/build/debian /data/temp
cp -rf /data/sonarr_bin /data/temp/sonarr_bin
cd /data/temp
ls -al .
fromdos debian.sh
sh debian.sh

View File

@@ -0,0 +1,22 @@
FROM ubuntu:xenial
ENV DEBIAN_FRONTEND noninteractive
ARG MONO_VERSION=5.20
ARG MONO_URL=stable-xenial/snapshots/$MONO_VERSION
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \
echo "deb http://download.mono-project.com/repo/debian $MONO_URL main" > /etc/apt/sources.list.d/mono-official-stable.list && \
apt-get update && apt-get install -y \
tofrodos tzdata \
mono-complete \
sqlite3 mediainfo \
&& rm -rf /var/lib/apt/lists/*
COPY startup.sh /startup.sh
RUN fromdos /startup.sh
WORKDIR /data/
VOLUME ["/data/_tests_linux", "/data/_output_linux", "/data/_tests_results"]
CMD bash /startup.sh

View File

@@ -0,0 +1,29 @@
FROM ubuntu:xenial
ENV DEBIAN_FRONTEND noninteractive
ARG MONO_VERSION=5.20
ARG MONO_URL=stable-xenial/snapshots/$MONO_VERSION
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \
echo "deb http://download.mono-project.com/repo/debian $MONO_URL main" > /etc/apt/sources.list.d/mono-official-stable.list && \
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 && \
echo "deb http://apt.sonarr.tv/ubuntu xenial main" > /etc/apt/sources.list.d/sonarr.list && \
apt-get update && apt-get install -y \
tofrodos tzdata \
sonarr \
sqlite3 mediainfo \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y \
libmono-system-runtime4.0-cil \
libmono-system-net-http4.0-cil \
&& rm -rf /var/lib/apt/lists/*
COPY startup.sh /startup.sh
RUN fromdos /startup.sh
WORKDIR /data/
VOLUME ["/data/_tests_linux", "/data/_output_linux", "/data/_tests_results"]
CMD bash /startup.sh

View File

@@ -0,0 +1,15 @@
echo "Preparing Test..."
mkdir -p /data/test
cp -r /data/_tests_linux/* /data/test/
cp -r /data/_output_linux /data/test/bin
cd /data/test
runTest()
{
bash test.sh Linux $1
cp TestResult.xml /data/_tests_results/TestResult_$1.xml
}
runTest Integration
runTest Unit

121
docker/tests/run-all.sh Normal file
View File

@@ -0,0 +1,121 @@
opt_parallel=
opt_version=
opt_mode=both
while getopts 'pv:m:r?h' c
do
case $c in
p) opt_parallel=1 ;;
v) opt_version=$OPTARG ;;
m) opt_mode=$OPTARG ;;
r) opt_report=1 ;;
?|h) printf "Usage: %s [-p] [-v mono-ver] [-m sonarr|complete]\n" $0
printf " -p run parallel\n"
printf " -v run specified mono version\n"
printf " -m run only mono-'complete' or 'sonarr' package variants\n"
printf " -r only report\n"
exit 2
esac
done
# NOTE:
# each container has a 1gb tmpfs mounted since it greatly speeds up the normally intensive db operations
# make sure that the docker host has enough memory to handle about ~300 MB per container, so 2-3 GB total
# excess goes to the swap and will slow down the entire system
MONO_VERSIONS=""
# Future versions
MONO_VERSIONS="$MONO_VERSIONS 6.10=preview-xenial"
# Semi-Supported versions
MONO_VERSIONS="$MONO_VERSIONS 6.8 6.6 6.4 6.0"
# Supported versions
MONO_VERSIONS="$MONO_VERSIONS 5.20 5.18"
# Legacy unsupported versions (but appear to work)
MONO_VERSIONS="$MONO_VERSIONS 5.16 5.14 5.12"
# Legacy unsupported versions
MONO_VERSIONS="$MONO_VERSIONS 5.10 5.8 5.4 5.0"
#MONO_VERSIONS="$MONO_VERSIONS 4.8=stable-wheezy/snapshots/4.8"
if [ "$opt_version" != "" ]; then
MONO_VERSIONS="$opt_version"
fi
mkdir -p ${PWD}/../../_tests_results
prepOne() {
local MONO_VERSION_PAIR=$1
MONO_VERSION_SPLIT=(${MONO_VERSION_PAIR//=/ })
MONO_VERSION=${MONO_VERSION_SPLIT[0]}
MONO_URL=${MONO_VERSION_SPLIT[1]:-"stable-xenial/snapshots/$MONO_VERSION"}
echo "Building Test Docker for mono $MONO_VERSION"
if [ "$opt_mode" != "sonarr" ]; then
docker build -t sonarr-test-$MONO_VERSION --build-arg MONO_VERSION=$MONO_VERSION --build-arg MONO_URL=$MONO_URL --file mono/complete/Dockerfile mono
fi
if [ "$opt_mode" != "complete" ] && [ "$MONO_VERSION" != "5.0" ]; then
docker build -t sonarr-test-$MONO_VERSION-sonarr --build-arg MONO_VERSION=$MONO_VERSION --build-arg MONO_URL=$MONO_URL --file mono/sonarr/Dockerfile mono
fi
}
runOne() {
local MONO_VERSION_PAIR=$1
MONO_VERSION_SPLIT=(${MONO_VERSION_PAIR//=/ })
MONO_VERSION=${MONO_VERSION_SPLIT[0]}
echo "Running Test Docker for mono $MONO_VERSION"
if [ "$opt_mode" != "sonarr" ]; then
dockerArgs="--rm"
dockerArgs="$dockerArgs -v /${PWD}/../../_tests_linux:/data/_tests_linux:ro"
dockerArgs="$dockerArgs -v /${PWD}/../../_output_linux:/data/_output_linux:ro"
dockerArgs="$dockerArgs -v /${PWD}/../../_tests_results/mono-$MONO_VERSION:/data/_tests_results"
dockerArgs="$dockerArgs --mount type=tmpfs,destination=//data/test,tmpfs-size=1g"
docker run $dockerArgs sonarr-test-$MONO_VERSION
fi
if [ "$opt_mode" != "complete" ] && [ "$MONO_VERSION" != "5.0" ]; then
dockerArgs="--rm"
dockerArgs="$dockerArgs -v /${PWD}/../../_tests_linux:/data/_tests_linux:ro"
dockerArgs="$dockerArgs -v /${PWD}/../../_output_linux:/data/_output_linux:ro"
dockerArgs="$dockerArgs -v /${PWD}/../../_tests_results/mono-$MONO_VERSION-sonarr:/data/_tests_results"
dockerArgs="$dockerArgs --mount type=tmpfs,destination=//data/test,tmpfs-size=1g"
docker run $dockerArgs sonarr-test-$MONO_VERSION-sonarr
fi
echo "Finished Test Docker for mono $MONO_VERSION"
}
if [ "$opt_report" != "1" ]; then
if [ "$opt_parallel" == "1" ]; then
for MONO_VERSION_PAIR in $MONO_VERSIONS; do
prepOne "$MONO_VERSION_PAIR"
done
fi
for MONO_VERSION_PAIR in $MONO_VERSIONS; do
if [ "$opt_parallel" == "1" ]; then
runOne "$MONO_VERSION_PAIR" &
else
prepOne "$MONO_VERSION_PAIR"
runOne "$MONO_VERSION_PAIR"
fi
done
if [ "$opt_parallel" == "1" ]; then
echo "Waiting for all runs to finish"
wait
echo "Finished all runs"
fi
fi
grep "<test-run" ../../_tests_results/**/*.xml | sed -r 's/.*?mono-([0-9.]+(-s)?).*?_([IU]).*?\.xml.*?failed="([0-9]*)".*/\1\t\3:\tfailed \4/g' | sort -V -t.

25
frontend/.csscomb.json Normal file
View File

@@ -0,0 +1,25 @@
{
"remove-empty-rulesets": true,
"always-semicolon": true,
"color-case": "lower",
"block-indent": " ",
"color-shorthand": false,
"element-case": "lower",
"eof-newline": true,
"leading-zero": true,
"quotes": "double",
"sort-order-fallback": "abc",
"space-before-colon": "",
"space-after-colon": " ",
"space-before-combinator": " ",
"space-after-combinator": " ",
"space-between-declarations": "\n",
"space-before-opening-brace": " ",
"space-after-opening-brace": "\n",
"space-after-selector-delimiter": " ",
"space-before-selector-delimiter": "",
"space-before-closing-brace": "\n",
"strip-spaces": true,
"tab-size": true,
"unitless-zero": false
}

335
frontend/.esformatter Normal file
View File

@@ -0,0 +1,335 @@
{
"indent": {
"value": " ",
"FunctionExpression": 1,
"ArrayExpression": 1,
"ObjectExpression": 1
},
"lineBreak": {
"value": "\n",
"before": {
"ArrayPatternClosing": 0,
"ArrayPatternComma": 0,
"ArrayPatternOpening": 0,
"ArrowFunctionExpressionArrow": 0,
"ArrowFunctionExpressionClosingBrace": ">=1",
"ArrowFunctionExpressionOpeningBrace": 0,
"AssignmentExpression": ">=1",
"AssignmentOperator": 0,
"BlockStatement": 0,
"BreakKeyword": ">=1",
"CallExpression": -1,
"CallExpressionClosingParentheses": -1,
"CallExpressionOpeningParentheses": 0,
"CatchClosingBrace": ">=1",
"CatchKeyword": 0,
"CatchOpeningBrace": 0,
"ClassDeclaration": ">=1",
"ClassDeclarationClosingBrace": ">=1",
"ClassDeclarationOpeningBrace": 0,
"ConditionalExpression": ">=1",
"DeleteOperator": ">=1",
"DoWhileStatement": ">=1",
"DoWhileStatementClosingBrace": ">=1",
"DoWhileStatementOpeningBrace": 0,
"ElseIfStatement": 0,
"ElseIfStatementClosingBrace": ">=1",
"ElseIfStatementOpeningBrace": 0,
"ElseStatement": 0,
"ElseStatementClosingBrace": ">=1",
"ElseStatementOpeningBrace": 0,
"EmptyStatement": -1,
"EndOfFile": -1,
"FinallyClosingBrace": ">=1",
"FinallyKeyword": -1,
"FinallyOpeningBrace": 0,
"ForInStatement": ">=1",
"ForInStatementClosingBrace": ">=1",
"ForInStatementExpressionClosing": 0,
"ForInStatementExpressionOpening": 0,
"ForInStatementOpeningBrace": 0,
"ForStatement": ">=1",
"ForStatementClosingBrace": ">=1",
"ForStatementExpressionClosing": "<2",
"ForStatementExpressionOpening": 0,
"ForStatementOpeningBrace": 0,
"FunctionDeclaration": ">=1",
"FunctionDeclarationClosingBrace": ">=1",
"FunctionDeclarationOpeningBrace": 0,
"FunctionExpression": 0,
"FunctionExpressionClosingBrace": 1,
"FunctionExpressionOpeningBrace":0,
"IIFEClosingParentheses": 0,
"IfStatement": ">=1",
"IfStatementClosingBrace": ">=1",
"IfStatementOpeningBrace": 0,
"LogicalExpression": -1,
"MemberExpressionClosing": 0,
"MemberExpressionOpening": 0,
"MemberExpressionPeriod": -1,
"MethodDefinition": ">=1",
"ObjectExpressionClosingBrace": "<=1",
"ObjectPatternClosingBrace": 0,
"ObjectPatternComma": 0,
"ObjectPatternOpeningBrace": 0,
"ParameterDefault": 0,
"Property": "<=2",
"PropertyValue": 0,
"ReturnStatement": -1,
"SwitchClosingBrace": ">=1",
"SwitchOpeningBrace": 0,
"ThisExpression": -1,
"ThrowStatement": ">=1",
"TryClosingBrace": ">=1",
"TryKeyword": -1,
"TryOpeningBrace": 0,
"VariableDeclaration": ">=1",
"VariableDeclarationSemiColon": 0,
"VariableDeclarationWithoutInit": ">=1",
"VariableName": ">=1",
"VariableValue": 0,
"WhileStatement": ">=1",
"WhileStatementClosingBrace": ">=1",
"WhileStatementOpeningBrace": 0
},
"after": {
"ArrayPatternClosing": 0,
"ArrayPatternComma": 0,
"ArrayPatternOpening": 0,
"ArrowFunctionExpressionArrow": 0,
"ArrowFunctionExpressionClosingBrace": -1,
"ArrowFunctionExpressionOpeningBrace": ">=1",
"AssignmentExpression": ">=1",
"AssignmentOperator": 0,
"BlockStatement": 0,
"BreakKeyword": -1,
"CallExpression": -1,
"CallExpressionClosingParentheses": -1,
"CallExpressionOpeningParentheses": -1,
"CatchClosingBrace": ">=0",
"CatchKeyword": 0,
"CatchOpeningBrace": ">=1",
"ClassDeclaration": ">=1",
"ClassDeclarationClosingBrace": ">=1",
"ClassDeclarationOpeningBrace": ">=1",
"ConditionalExpression": ">=1",
"DeleteOperator": ">=1",
"DoWhileStatement": ">=1",
"DoWhileStatementClosingBrace": 0,
"DoWhileStatementOpeningBrace": ">=1",
"ElseIfStatement": ">=1",
"ElseIfStatementClosingBrace": ">=1",
"ElseIfStatementOpeningBrace": ">=1",
"ElseStatement": ">=1",
"ElseStatementClosingBrace": ">=1",
"ElseStatementOpeningBrace": ">=1",
"EmptyStatement": -1,
"FinallyClosingBrace": ">=1",
"FinallyKeyword": -1,
"FinallyOpeningBrace": ">=1",
"ForInStatement": ">=1",
"ForInStatementClosingBrace": ">=1",
"ForInStatementExpressionClosing": -1,
"ForInStatementExpressionOpening": "<2",
"ForInStatementOpeningBrace": ">=1",
"ForStatement": ">=1",
"ForStatementClosingBrace": ">=1",
"ForStatementExpressionClosing": -1,
"ForStatementExpressionOpening": "<2",
"ForStatementOpeningBrace": ">=1",
"FunctionDeclaration": ">=1",
"FunctionDeclarationClosingBrace": ">=1",
"FunctionDeclarationOpeningBrace": ">=1",
"FunctionExpression": 0,
"FunctionExpressionClosingBrace": -1,
"FunctionExpressionOpeningBrace": 1,
"IIFEOpeningParentheses": 0,
"IfStatement": ">=1",
"IfStatementClosingBrace": ">=1",
"IfStatementOpeningBrace": ">=1",
"LogicalExpression": -1,
"MemberExpressionClosing": 0,
"MemberExpressionOpening": 0,
"MemberExpressionPeriod": 0,
"MethodDefinition": ">=1",
"ObjectExpressionOpeningBrace": "<=1",
"ObjectPatternClosingBrace": 0,
"ObjectPatternComma": 0,
"ObjectPatternOpeningBrace": 0,
"ParameterDefault": 0,
"Property": -1,
"PropertyName": 0,
"ReturnStatement": -1,
"SwitchCaseColon": ">=1",
"SwitchClosingBrace": ">=1",
"SwitchOpeningBrace": ">=1",
"ThisExpression": 0,
"ThrowStatement": ">=1",
"TryClosingBrace": 0,
"TryKeyword": -1,
"TryOpeningBrace": ">=1",
"VariableDeclaration": ">=1",
"VariableDeclarationSemiColon": ">=1",
"VariableValue": -1,
"WhileStatement": ">=1",
"WhileStatementClosingBrace": ">=1",
"WhileStatementOpeningBrace": ">=1"
}
},
"whiteSpace": {
"value": " ",
"removeTrailing": 1,
"before": {
"ArgumentComma": 0,
"ArgumentList": 0,
"ArgumentListArrayExpression": 0,
"ArgumentListFunctionExpression": 1,
"ArgumentListObjectExpression": 0,
"ArrayExpressionClosing": 0,
"ArrayExpressionComma": 0,
"ArrayExpressionOpening": 1,
"AssignmentOperator": 1,
"BinaryExpression": 0,
"BinaryExpressionOperator": 1,
"BlockComment": 1,
"CallExpression": 1,
"CatchClosingBrace": 1,
"CatchKeyword": 1,
"CatchOpeningBrace": 1,
"CatchParameterList": 0,
"CommaOperator": 0,
"ConditionalExpressionAlternate": 1,
"ConditionalExpressionConsequent": 1,
"DoWhileStatementClosingBrace": 1,
"DoWhileStatementConditional": 1,
"DoWhileStatementOpeningBrace": 1,
"ElseIfStatementClosingBrace": 1,
"ElseIfStatementOpeningBrace": 1,
"ElseStatementClosingBrace": 1,
"ElseStatementOpeningBrace": 1,
"EmptyStatement": 0,
"ExpressionClosingParentheses": 0,
"FinallyClosingBrace": 1,
"FinallyKeyword": -1,
"FinallyOpeningBrace": 1,
"ForInStatement": 1,
"ForInStatementClosingBrace": 1,
"ForInStatementExpressionClosing": 0,
"ForInStatementExpressionOpening": 1,
"ForInStatementOpeningBrace": 1,
"ForStatement": 1,
"ForStatementClosingBrace": 1,
"ForStatementExpressionClosing": 0,
"ForStatementExpressionOpening": 1,
"ForStatementOpeningBrace": 1,
"ForStatementSemicolon": 0,
"FunctionDeclarationClosingBrace": 1,
"FunctionDeclarationOpeningBrace": 1,
"FunctionExpressionClosingBrace": 1,
"FunctionExpressionOpeningBrace": 1,
"IfStatementClosingBrace": 1,
"IfStatementConditionalClosing": 0,
"IfStatementConditionalOpening": 1,
"IfStatementOpeningBrace": 1,
"LineComment": 1,
"LogicalExpressionOperator": 1,
"MemberExpressionClosing": 0,
"ObjectExpressionClosingBrace": 1,
"ParameterComma": 0,
"ParameterList": 0,
"Property": 1,
"PropertyName": 1,
"PropertyValue": 1,
"SwitchDiscriminantClosing": 0,
"SwitchDiscriminantOpening": 1,
"ThrowKeyword": 1,
"TryClosingBrace": 1,
"TryKeyword": -1,
"TryOpeningBrace": 1,
"UnaryExpressionOperator": 0,
"VariableName": 1,
"VariableValue": 1,
"WhileStatementClosingBrace": 1,
"WhileStatementConditionalClosing": 0,
"WhileStatementConditionalOpening": 1,
"WhileStatementOpeningBrace": 1
},
"after": {
"ArgumentComma": 1,
"ArgumentList": 0,
"ArgumentListArrayExpression": 1,
"ArgumentListFunctionExpression": 1,
"ArgumentListObjectExpression": 0,
"ArrayExpressionClosing": 0,
"ArrayExpressionComma": 1,
"ArrayExpressionOpening": 0,
"AssignmentOperator": 1,
"BinaryExpression": 0,
"BinaryExpressionOperator": 1,
"BlockComment": 1,
"CallExpression": 0,
"CatchClosingBrace": 1,
"CatchKeyword": 1,
"CatchOpeningBrace": 1,
"CatchParameterList": 0,
"CommaOperator": 1,
"ConditionalExpressionConsequent": 1,
"ConditionalExpressionTest": 1,
"DoWhileStatementBody": 1,
"DoWhileStatementClosingBrace": 1,
"DoWhileStatementOpeningBrace": 1,
"ElseIfStatementClosingBrace": 1,
"ElseIfStatementOpeningBrace": 1,
"ElseStatementClosingBrace": 1,
"ElseStatementOpeningBrace": 1,
"EmptyStatement": 0,
"ExpressionOpeningParentheses": 0,
"FinallyClosingBrace": 1,
"FinallyKeyword": -1,
"FinallyOpeningBrace": 1,
"ForInStatement": 1,
"ForInStatementClosingBrace": 1,
"ForInStatementExpressionClosing": 1,
"ForInStatementExpressionOpening": 0,
"ForInStatementOpeningBrace": 1,
"ForStatement": 1,
"ForStatementClosingBrace": 1,
"ForStatementExpressionClosing": 1,
"ForStatementExpressionOpening": 0,
"ForStatementOpeningBrace": 1,
"ForStatementSemicolon": 1,
"FunctionDeclarationClosingBrace": 0,
"FunctionDeclarationOpeningBrace": 0,
"FunctionExpressionClosingBrace": 0,
"FunctionExpressionOpeningBrace": 0,
"FunctionName": 0,
"FunctionReservedWord": 0,
"IfStatementClosingBrace": 1,
"IfStatementConditionalClosing": 0,
"IfStatementConditionalOpening": 0,
"IfStatementOpeningBrace": 1,
"LogicalExpressionOperator": 1,
"MemberExpressionOpening": 0,
"ObjectExpressionClosingBrace": 0,
"ObjectExpressionOpeningBrace": 1,
"ParameterComma": 1,
"ParameterList": 0,
"PropertyName": 0,
"PropertyValue": 0,
"SwitchDiscriminantClosing": 1,
"SwitchDiscriminantOpening": 0,
"ThrowKeyword": 1,
"TryClosingBrace": 1,
"TryKeyword": -1,
"TryOpeningBrace": 1,
"UnaryExpressionOperator": 0,
"VariableName": 1,
"WhileStatementClosingBrace": 1,
"WhileStatementConditionalClosing": 1,
"WhileStatementConditionalOpening": 0,
"WhileStatementOpeningBrace": 1
}
}
}

1
frontend/.eslintignore Normal file
View File

@@ -0,0 +1 @@
**/JsLibraries/**

293
frontend/.eslintrc Normal file
View File

@@ -0,0 +1,293 @@
{
"parser": "babel-eslint",
"env": {
"browser": true,
"commonjs": true,
"node": true,
"es6": true
},
"globals": {
"expect": false,
"chai": false,
"sinon": false
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"modules": true,
"impliedStrict": true
}
},
"plugins": [
"filenames",
"react"
],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"filenames/match-exported": ["error"],
# ECMAScript 6
"arrow-body-style": [0],
"arrow-parens": ["error", "always"],
"arrow-spacing": ["error", { "before": true, "after": true }],
"constructor-super": "error",
"generator-star-spacing": "off",
"no-class-assign": "error",
"no-confusing-arrow": "error",
"no-const-assign": "error",
"no-dupe-class-members": "error",
"no-duplicate-imports": "error",
"no-new-symbol": "error",
"no-this-before-super": "error",
"no-useless-escape": "error",
"no-useless-computed-key": "error",
"no-useless-constructor": "error",
"no-var": "warn",
"object-shorthand": ["error", "properties"],
"prefer-arrow-callback": "error",
"prefer-const": "warn",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "warn",
"prefer-template": "error",
"require-yield": "off",
"template-curly-spacing": ["error", "never"],
"yield-star-spacing": "off",
# Possible Errors
"comma-dangle": "error",
"no-cond-assign": "error",
"no-console": "off",
"no-constant-condition": "warn",
"no-control-regex": "error",
"no-debugger": "off",
"no-dupe-args": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-empty": "warn",
"no-empty-character-class": "error",
"no-ex-assign": "error",
"no-extra-boolean-cast": "error",
"no-extra-parens": ["error", "functions"],
"no-extra-semi": "error",
"no-func-assign": "error",
"no-inner-declarations": "error",
"no-invalid-regexp": "error",
"no-irregular-whitespace": "error",
"no-negated-in-lhs": "error",
"no-obj-calls": "error",
"no-regex-spaces": "error",
"no-sparse-arrays": "error",
"no-unexpected-multiline": "error",
"no-unreachable": "warn",
"no-unsafe-finally": "error",
"use-isnan": "error",
"valid-jsdoc": "off",
"valid-typeof": "error",
# Best Practices
"accessor-pairs": "off",
"array-callback-return": "warn",
"block-scoped-var": "warn",
"consistent-return": "off",
"curly": "error",
"default-case": "error",
"dot-location": ["error", "property"],
"dot-notation": "error",
"eqeqeq": ["error", "smart"],
"guard-for-in": "error",
"no-alert": "warn",
"no-caller": "error",
"no-case-declarations": "error",
"no-div-regex": "error",
"no-else-return": "error",
"no-empty-function": ["error", {"allow": ["arrowFunctions"]}],
"no-empty-pattern": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-fallthrough": "error",
"no-floating-decimal": "error",
"no-implicit-coercion": ["error", {
"boolean": false,
"number": true,
"string": true,
"allow": [/* "!!", "~", "*", "+" */]
}],
"no-implicit-globals": "error",
"no-implied-eval": "error",
"no-invalid-this": "off",
"no-iterator": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-loop-func": "error",
"no-magic-numbers": ["off", {"ignoreArrayIndexes": true, "ignore": [0, 1] }],
"no-multi-spaces": "error",
"no-multi-str": "error",
"no-native-reassign": ["error", {"exceptions": ["console"]}],
"no-new": "off",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-octal": "error",
"no-octal-escape": "error",
"no-param-reassign": "off",
"no-process-env": "off",
"no-proto": "error",
"no-redeclare": "error",
"no-return-assign": "warn",
"no-script-url": "error",
"no-self-assign": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-throw-literal": "error",
"no-unmodified-loop-condition": "error",
"no-unused-expressions": "error",
"no-unused-labels": "error",
"no-useless-call": "error",
"no-useless-concat": "error",
"no-void": "error",
"no-warning-comments": "off",
"no-with": "error",
"radix": ["error", "as-needed"],
"vars-on-top": "off",
"wrap-iife": ["error", "inside"],
"yoda": "error",
# Strict Mode
"strict": ["error", "never"],
# Variables
"init-declarations": ["error", "always"],
"no-catch-shadow": "error",
"no-delete-var": "error",
"no-label-var": "error",
"no-restricted-globals": "off",
"no-shadow": "error",
"no-shadow-restricted-names": "error",
"no-undef": "error",
"no-undef-init": "off",
"no-undefined": "off",
"no-unused-vars": ["error", { "args": "none", "ignoreRestSiblings": true }],
"no-use-before-define": "error",
# Node.js and CommonJS
"callback-return": "warn",
"global-require": "error",
"handle-callback-err": "warn",
"no-mixed-requires": "error",
"no-new-require": "error",
"no-path-concat": "error",
"no-process-exit": "error",
# Stylistic Issues
"array-bracket-spacing": ["error", "never"],
"block-spacing": ["error", "always"],
"brace-style": ["error", "1tbs", { "allowSingleLine": false }],
"camelcase": "off",
"comma-spacing": ["error", {"before": false, "after": true}],
"comma-style": ["error", "last"],
"computed-property-spacing": ["error", "never"],
"consistent-this": ["error", "self"],
"eol-last": "error",
"func-names": "off",
"func-style": ["error", "declaration"],
"indent": ["error", 2, {"SwitchCase": 1}],
"key-spacing": ["error", {"beforeColon": false, "afterColon": true}],
"keyword-spacing": ["error", { "before": true, "after": true}],
"lines-around-comment": ["error", { "beforeBlockComment": true, "afterBlockComment": false }],
"max-depth": ["error", {"maximum": 5}],
"max-nested-callbacks": ["error", 4],
"max-statements": "off",
"max-statements-per-line": ["error", { "max": 1 }],
"new-cap": ["error", {"capIsNewExceptions": ["$.Deferred", "DragDropContext", "DragLayer", "DragSource", "DropTarget"]}],
"new-parens": "error",
"newline-after-var": "off",
"newline-before-return": "off",
"newline-per-chained-call": "off",
"no-array-constructor": "error",
"no-bitwise": "error",
"no-continue": "error",
"no-inline-comments": "off",
"no-lonely-if": "warn",
"no-mixed-spaces-and-tabs": "error",
"no-multiple-empty-lines": ["error", { "max": 1 }],
"no-negated-condition": "warn",
"no-nested-ternary": "error",
"no-new-object": "error",
"no-plusplus": "off",
"no-restricted-syntax": "off",
"no-spaced-func": "error",
"no-ternary": "off",
"no-trailing-spaces": "error",
"no-underscore-dangle": ["error", { "allowAfterThis": true }],
"no-unneeded-ternary": "error",
"no-whitespace-before-property": "error",
"object-curly-spacing": ["error", "always"],
"one-var": ["error", "never"],
"one-var-declaration-per-line": ["error", "always"],
"operator-assignment": ["off", "never"],
"operator-linebreak": ["error", "after"],
"quote-props": ["error", "as-needed"],
"quotes": ["error", "single"],
"require-jsdoc": "off",
"semi": "error",
"semi-spacing": ["error", { "before": false, "after": true }],
"sort-vars": "off",
"space-before-blocks": ["error", "always"],
"space-before-function-paren": ["error", "never"],
"space-in-parens": "off",
"space-infix-ops": "off",
"space-unary-ops": "off",
"spaced-comment": "error",
"wrap-regex": "error",
# React
"react/jsx-boolean-value": [2, "always"],
"react/jsx-uses-vars": 2,
"react/jsx-closing-bracket-location": 2,
"react/jsx-tag-spacing": ["error"],
"react/jsx-curly-spacing": [2, "never"],
"react/jsx-equals-spacing": [2, "never"],
"react/jsx-indent-props": [2, 2],
"react/jsx-indent": [2, 2],
"react/jsx-key": 2,
"react/jsx-no-bind": [2, { "allowArrowFunctions": true }],
"react/jsx-no-duplicate-props": [2, { "ignoreCase": true }],
"react/jsx-max-props-per-line": [2, { "maximum": 2 }],
"react/jsx-handler-names": [2, { "eventHandlerPrefix": "(on|dispatch)", "eventHandlerPropPrefix": "on" }],
"react/jsx-no-undef": 2,
"react/jsx-pascal-case": 2,
"react/jsx-uses-react": 2,
// Explicitly disabled in case we want to enable them again
"react/no-did-mount-set-state": 0,
"react/no-did-update-set-state": 0,
"react/no-direct-mutation-state": 2,
"react/no-multi-comp": [2, { "ignoreStateless": true }],
"react/no-unknown-property": 2,
"react/prefer-es6-class": 2,
"react/prop-types": 2,
"react/react-in-jsx-scope": 2,
"react/self-closing-comp": 2,
"react/sort-comp": 2,
"react/jsx-wrap-multilines": 2
}
}

12
frontend/.jsbeautifyrc Normal file
View File

@@ -0,0 +1,12 @@
{
"js": {
"indent_size": 2,
"indent_char": " ",
"indent_level": 2,
"indent_with_tabs": false,
"preserve_newlines": true,
"brace_style": "collapse",
"max_preserve_newlines": 2,
"jslint_happy": true
}
}

396
frontend/.stylelintrc Normal file
View File

@@ -0,0 +1,396 @@
{
"plugins": [
"stylelint-order"
],
"ignoreFiles": [
"frontend/src/Styles/scaffolding.css",
"**/*.js"
],
"rules": {
"at-rule-empty-line-before": [
"always",
{
"except": [
"inside-block"
]
}
],
"at-rule-name-case": "lower",
"at-rule-name-newline-after": "always-multi-line",
"at-rule-name-space-after": "always",
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": [
"/^add\\-mixin$/",
"/^define\\-mixin$/"
]
}
],
"at-rule-no-vendor-prefix": true,
"at-rule-semicolon-newline-after": "always",
"at-rule-semicolon-space-before": "never",
"block-closing-brace-empty-line-before": "never",
"block-closing-brace-newline-after": "always",
"block-closing-brace-newline-before": "always",
"block-closing-brace-space-after": "always-single-line",
"block-closing-brace-space-before": "always-single-line",
"block-no-empty": true,
"block-opening-brace-newline-after": "always",
"block-opening-brace-newline-before": "never-single-line",
"block-opening-brace-space-after": "always-single-line",
"block-opening-brace-space-before": "always",
"color-hex-case": "lower",
"color-hex-length": "short",
"color-named": "never",
"color-no-invalid-hex": true,
"comment-whitespace-inside": "always",
"declaration-bang-space-after": "never",
"declaration-bang-space-before": "always",
"declaration-block-no-duplicate-properties": [
true,
{
"ignoreProperties": [
"composes"
]
}
],
"declaration-block-no-redundant-longhand-properties": true,
"declaration-block-no-shorthand-property-overrides": true,
"declaration-block-semicolon-newline-after": "always",
"declaration-block-semicolon-newline-before": "never-multi-line",
"declaration-block-semicolon-space-before": "never",
"declaration-block-single-line-max-declarations": 1,
"declaration-block-trailing-semicolon": "always",
"declaration-colon-space-after": "always",
"declaration-colon-space-before": "never",
"font-family-name-quotes": "always-unless-keyword",
"function-calc-no-unspaced-operator": true,
"function-comma-newline-after": "never-multi-line",
"function-comma-newline-before": "never-multi-line",
"function-comma-space-after": "always",
"function-comma-space-before": "never",
"function-linear-gradient-no-nonstandard-direction": true,
"function-name-case": "lower",
"function-parentheses-newline-inside": "never-multi-line",
"function-parentheses-space-inside": "never",
"function-url-quotes": "always",
"function-url-scheme-blacklist": [
"data"
],
"function-whitespace-after": "always",
"indentation": 2,
"keyframe-declaration-no-important": true,
"length-zero-no-unit": true,
"max-empty-lines": 1,
"max-line-length": [
100,
{
"ignore": [
"non-comments"
]
}
],
"max-nesting-depth": 2,
"media-feature-colon-space-after": "always",
"media-feature-colon-space-before": "never",
"media-feature-name-case": "lower",
"media-feature-name-no-vendor-prefix": true,
"media-feature-range-operator-space-after": "always",
"media-feature-range-operator-space-before": "always",
"no-empty-source": true,
"no-eol-whitespace": true,
"no-extra-semicolons": true,
"no-invalid-double-slash-comments": true,
"no-missing-end-of-source-newline": true,
"number-leading-zero": "always",
"number-no-trailing-zeros": true,
"order/order": [
"custom-properties",
"dollar-variables",
{
"hasBlock": false,
"name": "add-mixin",
"type": "at-rule"
},
"declarations",
"rules",
"at-rules"
],
"order/properties-order": [
{
"emptyLineBefore": "always",
"properties": [
"composes"
]
},
{
"emptyLineBefore": "always",
"properties": [
"position",
"top",
"right",
"bottom",
"left",
"z-index",
"display",
"visibility",
"align-content",
"align-items",
"align-self",
"justify-content",
"flex",
"flex-direction",
"flex-order",
"flex-pack",
"flex-align",
"flex-grow",
"flex-shrink",
"flex-basis",
"flex-wrap",
"flex-flow",
"float",
"clear",
"overflow",
"overflow-x",
"overflow-y",
"-webkit-overflow-scrolling",
"clip",
"box-sizing",
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"min-width",
"min-height",
"max-width",
"max-height",
"width",
"height",
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"border",
"border-spacing",
"border-collapse",
"border-width",
"border-style",
"border-color",
"border-top",
"border-top-width",
"border-top-style",
"border-top-color",
"border-right",
"border-right-width",
"border-right-style",
"border-right-color",
"border-bottom",
"border-bottom-width",
"border-bottom-style",
"border-bottom-color",
"border-left",
"border-left-width",
"border-left-style",
"border-left-color",
"border-radius",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius",
"border-image",
"border-image-source",
"border-image-slice",
"border-image-width",
"border-image-outset",
"border-image-repeat",
"border-top-image",
"border-right-image",
"border-bottom-image",
"border-left-image",
"border-corner-image",
"border-top-left-image",
"border-top-right-image",
"border-bottom-right-image",
"border-bottom-left-image",
"background",
"background-color",
"background-image",
"background-attachment",
"background-position",
"background-position-x",
"background-position-y",
"background-clip",
"background-origin",
"background-size",
"background-repeat",
"box-decoration-break",
"box-shadow",
"color",
"table-layout",
"caption-side",
"empty-cells",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image",
"quotes",
"content",
"counter-increment",
"counter-reset",
"-ms-writing-mode",
"vertical-align",
"text-align",
"text-align-last",
"text-decoration",
"text-emphasis",
"text-emphasis-position",
"text-emphasis-style",
"text-emphasis-color",
"text-indent",
"text-justify",
"text-outline",
"text-transform",
"text-wrap",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"text-shadow",
"white-space",
"word-spacing",
"word-wrap",
"word-break",
"tab-size",
"hyphens",
"letter-spacing",
"font",
"font-weight",
"font-style",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-size",
"font-family",
"font-smoothing",
"-moz-osx-font-smoothing",
"-webkit-font-smoothing",
"src",
"line-height",
"opacity",
"filter",
"resize",
"cursor",
"appearance",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"transition",
"transition-delay",
"transition-timing-function",
"transition-duration",
"transition-property",
"transform",
"transform-origin",
"transform-style",
"backface-visibility",
"animation",
"animation-name",
"animation-duration",
"animation-play-state",
"animation-timing-function",
"animation-delay",
"animation-iteration-count",
"animation-direction",
"animation-fill-mode",
"pointer-events",
"user-select",
"touch-action",
"-webkit-tap-highlight-color",
"unicode-bidi",
"direction",
"columns",
"column-span",
"column-width",
"column-count",
"column-fill",
"column-gap",
"column-rule",
"column-rule-width",
"column-rule-style",
"column-rule-color",
"break-before",
"break-inside",
"break-after",
"page-break-before",
"page-break-inside",
"page-break-after",
"orphans",
"widows",
"zoom",
"max-zoom",
"min-zoom",
"user-zoom",
"orientation"
]
}
],
"property-case": "lower",
"property-no-vendor-prefix": true,
"rule-empty-line-before": [
"always",
{
"except": [
"first-nested"
],
"ignore": [
"after-comment"
]
}
],
"selector-attribute-brackets-space-inside": "never",
"selector-attribute-operator-space-after": "never",
"selector-attribute-operator-space-before": "never",
"selector-attribute-quotes": "never",
"selector-class-pattern": "^[A-Za-z0-9]+$",
"selector-combinator-space-after": "always",
"selector-combinator-space-before": "always",
"selector-descendant-combinator-no-non-space": true,
"selector-list-comma-newline-after": "always",
"selector-list-comma-newline-before": "never-multi-line",
"selector-list-comma-space-before": "never",
"selector-max-attribute": 0,
"selector-max-class": 3,
"selector-max-compound-selectors": 3,
"selector-max-empty-lines": 0,
"selector-max-id": 0,
"selector-max-universal": 0,
"selector-pseudo-class-case": "lower",
"selector-pseudo-class-parentheses-space-inside": "never",
"selector-pseudo-element-case": "lower",
"selector-pseudo-element-colon-notation": "double",
"selector-pseudo-element-no-unknown": true,
"selector-type-case": "lower",
"selector-type-no-unknown": true,
"shorthand-property-no-redundant-values": true,
"string-no-newline": true,
"string-quotes": "single",
"time-min-milliseconds": 100,
"unit-case": "lower",
"unit-no-unknown": true,
"value-list-comma-newline-after": "never-multi-line",
"value-list-comma-newline-before": "never-multi-line",
"value-list-comma-space-after": "always",
"value-list-comma-space-before": "never",
"value-list-max-empty-lines": 0,
"value-no-vendor-prefix": true
}
}

7
frontend/.tern-project Normal file
View File

@@ -0,0 +1,7 @@
{
"ecmaVersion": 6,
"libs": [
"browser",
"jquery"
]
}

35
frontend/babel.config.js Normal file
View File

@@ -0,0 +1,35 @@
const loose = true;
module.exports = {
plugins: [
// Stage 1
'@babel/plugin-proposal-export-default-from',
['@babel/plugin-proposal-optional-chaining', { loose }],
['@babel/plugin-proposal-nullish-coalescing-operator', { loose }],
// Stage 2
'@babel/plugin-proposal-export-namespace-from',
// Stage 3
['@babel/plugin-proposal-class-properties', { loose }],
'@babel/plugin-syntax-dynamic-import'
],
env: {
development: {
presets: [
['@babel/preset-react', { development: true }]
],
plugins: [
'babel-plugin-inline-classnames'
]
},
production: {
presets: [
'@babel/preset-react'
],
plugins: [
'babel-plugin-transform-react-remove-prop-types'
]
}
}
};

17
frontend/gulp/build.js Normal file
View File

@@ -0,0 +1,17 @@
const gulp = require('gulp');
require('./clean');
require('./copy');
require('./webpack');
gulp.task('build',
gulp.series('clean',
gulp.parallel(
'webpack',
'copyHtml',
'copyFonts',
'copyImages'
)
)
);

8
frontend/gulp/clean.js Normal file
View File

@@ -0,0 +1,8 @@
const gulp = require('gulp');
const del = require('del');
const paths = require('./helpers/paths');
gulp.task('clean', () => {
return del([paths.dest.root]);
});

34
frontend/gulp/copy.js Normal file
View File

@@ -0,0 +1,34 @@
const path = require('path');
const gulp = require('gulp');
const print = require('gulp-print').default;
const cache = require('gulp-cached');
const livereload = require('gulp-livereload');
const paths = require('./helpers/paths.js');
gulp.task('copyHtml', () => {
return gulp.src(paths.src.html, { base: paths.src.root })
.pipe(cache('copyHtml'))
.pipe(print())
.pipe(gulp.dest(paths.dest.root))
.pipe(livereload());
});
gulp.task('copyFonts', () => {
return gulp.src(
path.join(paths.src.fonts, '**', '*.*'), { base: paths.src.root }
)
.pipe(cache('copyFonts'))
.pipe(print())
.pipe(gulp.dest(paths.dest.root))
.pipe(livereload());
});
gulp.task('copyImages', () => {
return gulp.src(
path.join(paths.src.images, '**', '*.*'), { base: paths.src.root }
)
.pipe(cache('copyImages'))
.pipe(print())
.pipe(gulp.dest(paths.dest.root))
.pipe(livereload());
});

View File

@@ -0,0 +1,5 @@
require('./build.js');
require('./clean.js');
require('./copy.js');
require('./watch.js');
require('./webpack.js');

View File

@@ -0,0 +1,6 @@
const colors = require('ansi-colors');
module.exports = function errorHandler(error) {
console.log(colors.red(`Error (${error.plugin}): ${error.message}`));
this.emit('end');
};

View File

@@ -0,0 +1,23 @@
const root = './frontend/src';
const paths = {
src: {
root,
html: `${root}/*.html`,
scripts: `${root}/**/*.js`,
content: `${root}/Content/`,
fonts: `${root}/Content/Fonts/`,
images: `${root}/Content/Images/`,
exclude: {
libs: `!${root}/JsLibraries/**`
}
},
dest: {
root: './_output/UI/',
content: './_output/UI/Content/',
fonts: './_output/UI/Content/Fonts/',
images: './_output/UI/Content/Images/'
}
};
module.exports = paths;

18
frontend/gulp/watch.js Normal file
View File

@@ -0,0 +1,18 @@
const gulp = require('gulp');
const livereload = require('gulp-livereload');
const gulpWatch = require('gulp-watch');
const paths = require('./helpers/paths.js');
require('./copy.js');
require('./webpack.js');
function watch() {
livereload.listen({ start: true });
gulp.task('webpackWatch')();
gulpWatch(paths.src.html, gulp.series('copyHtml'));
gulpWatch(`${paths.src.fonts}**/*.*`, gulp.series('copyFonts'));
gulpWatch(`${paths.src.images}**/*.*`, gulp.series('copyImages'));
}
gulp.task('watch', gulp.series('build', watch));

268
frontend/gulp/webpack.js Normal file
View File

@@ -0,0 +1,268 @@
const gulp = require('gulp');
const webpackStream = require('webpack-stream');
const livereload = require('gulp-livereload');
const path = require('path');
const webpack = require('webpack');
const errorHandler = require('./helpers/errorHandler');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const uiFolder = 'UI';
const frontendFolder = path.join(__dirname, '..');
const srcFolder = path.join(frontendFolder, 'src');
const isProduction = process.argv.indexOf('--production') > -1;
const isProfiling = isProduction && process.argv.indexOf('--profile') > -1;
const inlineWebWorkers = true;
const distFolder = path.resolve(frontendFolder, '..', '_output', uiFolder);
console.log('Source Folder:', srcFolder);
console.log('Output Folder:', distFolder);
console.log('isProduction:', isProduction);
console.log('isProfiling:', isProfiling);
const cssVarsFiles = [
'../src/Styles/Variables/colors',
'../src/Styles/Variables/dimensions',
'../src/Styles/Variables/fonts',
'../src/Styles/Variables/animations',
'../src/Styles/Variables/zIndexes'
].map(require.resolve);
// Override the way HtmlWebpackPlugin injects the scripts
HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function(html, assets, assetTags) {
const head = assetTags.head.map((v) => {
v.attributes = { rel: 'stylesheet', type: 'text/css', href: `/${v.attributes.href.replace('\\', '/')}` };
return this.createHtmlTag(v);
});
const body = assetTags.body.map((v) => {
v.attributes = { src: `/${v.attributes.src}` };
return this.createHtmlTag(v);
});
return html
.replace('<!-- webpack bundles head -->', head.join('\r\n '))
.replace('<!-- webpack bundles body -->', body.join('\r\n '));
};
const plugins = [
new webpack.DefinePlugin({
__DEV__: !isProduction,
'process.env.NODE_ENV': isProduction ? JSON.stringify('production') : JSON.stringify('development')
}),
new MiniCssExtractPlugin({
filename: path.join('Content', 'styles.css')
}),
new HtmlWebpackPlugin({
template: 'frontend/src/index.html',
filename: 'index.html'
})
];
const config = {
mode: isProduction ? 'production' : 'development',
devtool: '#source-map',
stats: {
children: false
},
watchOptions: {
ignored: /node_modules/
},
entry: {
index: 'index.js'
},
resolve: {
modules: [
srcFolder,
path.join(srcFolder, 'Shims'),
'node_modules'
],
alias: {
jquery: 'jquery/src/jquery'
}
},
output: {
path: distFolder,
filename: '[name].js',
sourceMapFilename: '[file].map'
},
optimization: {
chunkIds: 'named',
splitChunks: {
chunks: 'initial'
}
},
performance: {
hints: false
},
plugins,
resolveLoader: {
modules: [
'node_modules',
'frontend/gulp/webpack/'
]
},
module: {
rules: [
{
test: /\.worker\.js$/,
issuer: {
// monaco-editor includes the editor.worker.js in other language workers,
// don't use worker-loader in that case
exclude: /monaco-editor/
},
use: {
loader: 'worker-loader',
options: {
name: '[name].js',
inline: inlineWebWorkers,
fallback: !inlineWebWorkers
}
}
},
{
test: /\.js?$/,
exclude: /(node_modules|JsLibraries)/,
use: [
{
loader: 'babel-loader',
options: {
configFile: `${frontendFolder}/babel.config.js`,
envName: isProduction ? 'production' : 'development',
presets: [
[
'@babel/preset-env',
{
modules: false,
loose: true,
debug: false,
useBuiltIns: 'entry',
corejs: 3
}
]
]
}
}
]
},
// CSS Modules
{
test: /\.css$/,
exclude: /(node_modules|globals.css)/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: {
localIdentName: '[name]/[local]/[hash:base64:5]'
}
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
config: {
ctx: {
cssVarsFiles
},
path: 'frontend/postcss.config.js'
}
}
}
]
},
// Global styles
{
test: /\.css$/,
include: /(node_modules|globals.css)/,
use: [
'style-loader',
{
loader: 'css-loader'
}
]
},
// Fonts
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10240,
mimetype: 'application/font-woff',
emitFile: false,
name: 'Content/Fonts/[name].[ext]'
}
}
]
},
{
test: /\.(ttf|eot|eot?#iefix|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'file-loader',
options: {
emitFile: false,
name: 'Content/Fonts/[name].[ext]'
}
}
]
}
]
}
};
if (isProfiling) {
config.resolve.alias['react-dom$'] = 'react-dom/profiling';
config.resolve.alias['scheduler/tracing'] = 'scheduler/tracing-profiling';
config.optimization.minimizer = [
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true, // Must be set to true if using source-maps in production
terserOptions: {
mangle: false,
keep_classnames: true,
keep_fnames: true
}
})
];
}
gulp.task('webpack', () => {
return webpackStream(config)
.pipe(gulp.dest('_output/UI'));
});
gulp.task('webpackWatch', () => {
config.watch = true;
return webpackStream(config)
.on('error', errorHandler)
.pipe(gulp.dest('_output/UI'))
.on('error', errorHandler)
.pipe(livereload())
.on('error', errorHandler);
});

View File

@@ -0,0 +1,11 @@
const loaderUtils = require('loader-utils');
module.exports = function cssVariablesLoader(source) {
const options = loaderUtils.getOptions(this);
options.cssVarsFiles.forEach((cssVarsFile) => {
this.addDependency(cssVarsFile);
});
return source;
};

20
frontend/jsconfig.json Normal file
View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es6",
"checkJs": false,
"baseUrl": "src",
"jsx": "react",
"module": "commonjs",
"moduleResolution": "node",
"paths": {
"*": [
"*"
]
}
},
"include": [
"./src/**/*"
],
"exclude": [
]
}

View File

@@ -0,0 +1,23 @@
const reload = require('require-nocache')(module);
module.exports = (ctx, configPath, options) => {
const config = {
plugins: {
'postcss-mixins': {
mixinsDir: [
'frontend/src/Styles/Mixins'
]
},
'postcss-simple-vars': {
variables: () =>
ctx.options.cssVarsFiles.reduce((acc, vars) => {
return Object.assign(acc, reload(vars));
}, {})
},
'postcss-color-function': {},
'postcss-nested': {}
}
};
return config;
};

4
frontend/src/.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.insertFinalNewline": true
}

View File

@@ -0,0 +1,123 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { align, icons } from 'Helpers/Props';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
import TablePager from 'Components/Table/TablePager';
import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody';
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
import BlacklistRowConnector from './BlacklistRowConnector';
class Blacklist extends Component {
//
// Render
render() {
const {
isFetching,
isPopulated,
error,
items,
columns,
totalRecords,
isClearingBlacklistExecuting,
onClearBlacklistPress,
...otherProps
} = this.props;
return (
<PageContent title="Blacklist">
<PageToolbar>
<PageToolbarSection>
<PageToolbarButton
label="Clear"
iconName={icons.CLEAR}
isSpinning={isClearingBlacklistExecuting}
onPress={onClearBlacklistPress}
/>
</PageToolbarSection>
<PageToolbarSection alignContent={align.RIGHT}>
<TableOptionsModalWrapper
{...otherProps}
columns={columns}
>
<PageToolbarButton
label="Options"
iconName={icons.TABLE}
/>
</TableOptionsModalWrapper>
</PageToolbarSection>
</PageToolbar>
<PageContentBody>
{
isFetching && !isPopulated &&
<LoadingIndicator />
}
{
!isFetching && !!error &&
<div>Unable to load blacklist</div>
}
{
isPopulated && !error && !items.length &&
<div>
No history blacklist
</div>
}
{
isPopulated && !error && !!items.length &&
<div>
<Table
columns={columns}
{...otherProps}
>
<TableBody>
{
items.map((item) => {
return (
<BlacklistRowConnector
key={item.id}
columns={columns}
{...item}
/>
);
})
}
</TableBody>
</Table>
<TablePager
totalRecords={totalRecords}
isFetching={isFetching}
{...otherProps}
/>
</div>
}
</PageContentBody>
</PageContent>
);
}
}
Blacklist.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
totalRecords: PropTypes.number,
isClearingBlacklistExecuting: PropTypes.bool.isRequired,
onClearBlacklistPress: PropTypes.func.isRequired
};
export default Blacklist;

View File

@@ -0,0 +1,154 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import withCurrentPage from 'Components/withCurrentPage';
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
import * as blacklistActions from 'Store/Actions/blacklistActions';
import { executeCommand } from 'Store/Actions/commandActions';
import * as commandNames from 'Commands/commandNames';
import Blacklist from './Blacklist';
function createMapStateToProps() {
return createSelector(
(state) => state.blacklist,
createCommandExecutingSelector(commandNames.CLEAR_BLACKLIST),
(blacklist, isClearingBlacklistExecuting) => {
return {
isClearingBlacklistExecuting,
...blacklist
};
}
);
}
const mapDispatchToProps = {
...blacklistActions,
executeCommand
};
class BlacklistConnector extends Component {
//
// Lifecycle
componentDidMount() {
const {
useCurrentPage,
fetchBlacklist,
gotoBlacklistFirstPage
} = this.props;
registerPagePopulator(this.repopulate);
if (useCurrentPage) {
fetchBlacklist();
} else {
gotoBlacklistFirstPage();
}
}
componentDidUpdate(prevProps) {
if (prevProps.isClearingBlacklistExecuting && !this.props.isClearingBlacklistExecuting) {
this.props.gotoBlacklistFirstPage();
}
}
componentWillUnmount() {
this.props.clearBlacklist();
unregisterPagePopulator(this.repopulate);
}
//
// Control
repopulate = () => {
this.props.fetchBlacklist();
}
//
// Listeners
onFirstPagePress = () => {
this.props.gotoBlacklistFirstPage();
}
onPreviousPagePress = () => {
this.props.gotoBlacklistPreviousPage();
}
onNextPagePress = () => {
this.props.gotoBlacklistNextPage();
}
onLastPagePress = () => {
this.props.gotoBlacklistLastPage();
}
onPageSelect = (page) => {
this.props.gotoBlacklistPage({ page });
}
onSortPress = (sortKey) => {
this.props.setBlacklistSort({ sortKey });
}
onTableOptionChange = (payload) => {
this.props.setBlacklistTableOption(payload);
if (payload.pageSize) {
this.props.gotoBlacklistFirstPage();
}
}
onClearBlacklistPress = () => {
this.props.executeCommand({ name: commandNames.CLEAR_BLACKLIST });
}
onTableOptionChange = (payload) => {
this.props.setBlacklistTableOption(payload);
if (payload.pageSize) {
this.props.gotoBlacklistFirstPage();
}
}
//
// Render
render() {
return (
<Blacklist
onFirstPagePress={this.onFirstPagePress}
onPreviousPagePress={this.onPreviousPagePress}
onNextPagePress={this.onNextPagePress}
onLastPagePress={this.onLastPagePress}
onPageSelect={this.onPageSelect}
onSortPress={this.onSortPress}
onTableOptionChange={this.onTableOptionChange}
onClearBlacklistPress={this.onClearBlacklistPress}
{...this.props}
/>
);
}
}
BlacklistConnector.propTypes = {
useCurrentPage: PropTypes.bool.isRequired,
isClearingBlacklistExecuting: PropTypes.bool.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
fetchBlacklist: PropTypes.func.isRequired,
gotoBlacklistFirstPage: PropTypes.func.isRequired,
gotoBlacklistPreviousPage: PropTypes.func.isRequired,
gotoBlacklistNextPage: PropTypes.func.isRequired,
gotoBlacklistLastPage: PropTypes.func.isRequired,
gotoBlacklistPage: PropTypes.func.isRequired,
setBlacklistSort: PropTypes.func.isRequired,
setBlacklistTableOption: PropTypes.func.isRequired,
clearBlacklist: PropTypes.func.isRequired,
executeCommand: PropTypes.func.isRequired
};
export default withCurrentPage(
connect(createMapStateToProps, mapDispatchToProps)(BlacklistConnector)
);

View File

@@ -0,0 +1,89 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Button from 'Components/Link/Button';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import Modal from 'Components/Modal/Modal';
import ModalContent from 'Components/Modal/ModalContent';
import ModalHeader from 'Components/Modal/ModalHeader';
import ModalBody from 'Components/Modal/ModalBody';
import ModalFooter from 'Components/Modal/ModalFooter';
class BlacklistDetailsModal extends Component {
//
// Render
render() {
const {
isOpen,
sourceTitle,
protocol,
indexer,
message,
onModalClose
} = this.props;
return (
<Modal
isOpen={isOpen}
onModalClose={onModalClose}
>
<ModalContent
onModalClose={onModalClose}
>
<ModalHeader>
Details
</ModalHeader>
<ModalBody>
<DescriptionList>
<DescriptionListItem
title="Name"
data={sourceTitle}
/>
<DescriptionListItem
title="Protocol"
data={protocol}
/>
{
!!message &&
<DescriptionListItem
title="Indexer"
data={indexer}
/>
}
{
!!message &&
<DescriptionListItem
title="Message"
data={message}
/>
}
</DescriptionList>
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
}
}
BlacklistDetailsModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
sourceTitle: PropTypes.string.isRequired,
protocol: PropTypes.string.isRequired,
indexer: PropTypes.string,
message: PropTypes.string,
onModalClose: PropTypes.func.isRequired
};
export default BlacklistDetailsModal;

View File

@@ -0,0 +1,18 @@
.language,
.quality {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 100px;
}
.indexer {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 80px;
}
.actions {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 70px;
}

View File

@@ -0,0 +1,186 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { icons, kinds } from 'Helpers/Props';
import IconButton from 'Components/Link/IconButton';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
import TableRow from 'Components/Table/TableRow';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import EpisodeLanguage from 'Episode/EpisodeLanguage';
import EpisodeQuality from 'Episode/EpisodeQuality';
import SeriesTitleLink from 'Series/SeriesTitleLink';
import BlacklistDetailsModal from './BlacklistDetailsModal';
import styles from './BlacklistRow.css';
class BlacklistRow extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
isDetailsModalOpen: false
};
}
//
// Listeners
onDetailsPress = () => {
this.setState({ isDetailsModalOpen: true });
}
onDetailsModalClose = () => {
this.setState({ isDetailsModalOpen: false });
}
//
// Render
render() {
const {
series,
sourceTitle,
language,
quality,
date,
protocol,
indexer,
message,
columns,
onRemovePress
} = this.props;
return (
<TableRow>
{
columns.map((column) => {
const {
name,
isVisible
} = column;
if (!isVisible) {
return null;
}
if (name === 'series.sortTitle') {
return (
<TableRowCell key={name}>
<SeriesTitleLink
titleSlug={series.titleSlug}
title={series.title}
/>
</TableRowCell>
);
}
if (name === 'sourceTitle') {
return (
<TableRowCell key={name}>
{sourceTitle}
</TableRowCell>
);
}
if (name === 'language') {
return (
<TableRowCell
key={name}
className={styles.language}
>
<EpisodeLanguage
language={language}
/>
</TableRowCell>
);
}
if (name === 'quality') {
return (
<TableRowCell
key={name}
className={styles.quality}
>
<EpisodeQuality
quality={quality}
/>
</TableRowCell>
);
}
if (name === 'date') {
return (
<RelativeDateCellConnector
key={name}
date={date}
/>
);
}
if (name === 'indexer') {
return (
<TableRowCell
key={name}
className={styles.indexer}
>
{indexer}
</TableRowCell>
);
}
if (name === 'actions') {
return (
<TableRowCell
key={name}
className={styles.actions}
>
<IconButton
name={icons.INFO}
onPress={this.onDetailsPress}
/>
<IconButton
title="Remove from blacklist"
name={icons.REMOVE}
kind={kinds.DANGER}
onPress={onRemovePress}
/>
</TableRowCell>
);
}
return null;
})
}
<BlacklistDetailsModal
isOpen={this.state.isDetailsModalOpen}
sourceTitle={sourceTitle}
protocol={protocol}
indexer={indexer}
message={message}
onModalClose={this.onDetailsModalClose}
/>
</TableRow>
);
}
}
BlacklistRow.propTypes = {
id: PropTypes.number.isRequired,
series: PropTypes.object.isRequired,
sourceTitle: PropTypes.string.isRequired,
language: PropTypes.object.isRequired,
quality: PropTypes.object.isRequired,
date: PropTypes.string.isRequired,
protocol: PropTypes.string.isRequired,
indexer: PropTypes.string,
message: PropTypes.string,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
onRemovePress: PropTypes.func.isRequired
};
export default BlacklistRow;

View File

@@ -0,0 +1,26 @@
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { removeFromBlacklist } from 'Store/Actions/blacklistActions';
import createSeriesSelector from 'Store/Selectors/createSeriesSelector';
import BlacklistRow from './BlacklistRow';
function createMapStateToProps() {
return createSelector(
createSeriesSelector(),
(series) => {
return {
series
};
}
);
}
function createMapDispatchToProps(dispatch, props) {
return {
onRemovePress() {
dispatch(removeFromBlacklist({ id: props.id }));
}
};
}
export default connect(createMapStateToProps, createMapDispatchToProps)(BlacklistRow);

View File

@@ -0,0 +1,5 @@
.description {
composes: description from '~Components/DescriptionList/DescriptionListItemDescription.css';
overflow-wrap: break-word;
}

View File

@@ -0,0 +1,278 @@
import PropTypes from 'prop-types';
import React from 'react';
import formatDateTime from 'Utilities/Date/formatDateTime';
import formatAge from 'Utilities/Number/formatAge';
import Link from 'Components/Link/Link';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle';
import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription';
import styles from './HistoryDetails.css';
function HistoryDetails(props) {
const {
eventType,
sourceTitle,
data,
shortDateFormat,
timeFormat
} = props;
if (eventType === 'grabbed') {
const {
indexer,
releaseGroup,
nzbInfoUrl,
downloadClient,
downloadId,
age,
ageHours,
ageMinutes,
publishedDate
} = data;
return (
<DescriptionList>
<DescriptionListItem
descriptionClassName={styles.description}
title="Name"
data={sourceTitle}
/>
{
!!indexer &&
<DescriptionListItem
title="Indexer"
data={indexer}
/>
}
{
!!releaseGroup &&
<DescriptionListItem
descriptionClassName={styles.description}
title="Release Group"
data={releaseGroup}
/>
}
{
!!nzbInfoUrl &&
<span>
<DescriptionListItemTitle>
Info URL
</DescriptionListItemTitle>
<DescriptionListItemDescription>
<Link to={nzbInfoUrl}>{nzbInfoUrl}</Link>
</DescriptionListItemDescription>
</span>
}
{
!!downloadClient &&
<DescriptionListItem
title="Download Client"
data={downloadClient}
/>
}
{
!!downloadId &&
<DescriptionListItem
title="Grab ID"
data={downloadId}
/>
}
{
!!indexer &&
<DescriptionListItem
title="Age (when grabbed)"
data={formatAge(age, ageHours, ageMinutes)}
/>
}
{
!!publishedDate &&
<DescriptionListItem
title="Published Date"
data={formatDateTime(publishedDate, shortDateFormat, timeFormat, { includeSeconds: true })}
/>
}
</DescriptionList>
);
}
if (eventType === 'downloadFailed') {
const {
message
} = data;
return (
<DescriptionList>
<DescriptionListItem
descriptionClassName={styles.description}
title="Name"
data={sourceTitle}
/>
{
!!message &&
<DescriptionListItem
title="Message"
data={message}
/>
}
</DescriptionList>
);
}
if (eventType === 'downloadFolderImported') {
const {
droppedPath,
importedPath
} = data;
return (
<DescriptionList>
<DescriptionListItem
descriptionClassName={styles.description}
title="Name"
data={sourceTitle}
/>
{
!!droppedPath &&
<DescriptionListItem
descriptionClassName={styles.description}
title="Source"
data={droppedPath}
/>
}
{
!!importedPath &&
<DescriptionListItem
descriptionClassName={styles.description}
title="Imported To"
data={importedPath}
/>
}
</DescriptionList>
);
}
if (eventType === 'episodeFileDeleted') {
const {
reason
} = data;
let reasonMessage = '';
switch (reason) {
case 'Manual':
reasonMessage = 'File was deleted by via UI';
break;
case 'MissingFromDisk':
reasonMessage = 'Sonarr was unable to find the file on disk so it was removed';
break;
case 'Upgrade':
reasonMessage = 'File was deleted to import an upgrade';
break;
default:
reasonMessage = '';
}
return (
<DescriptionList>
<DescriptionListItem
title="Name"
data={sourceTitle}
/>
<DescriptionListItem
title="Reason"
data={reasonMessage}
/>
</DescriptionList>
);
}
if (eventType === 'episodeFileRenamed') {
const {
sourcePath,
sourceRelativePath,
path,
relativePath
} = data;
return (
<DescriptionList>
<DescriptionListItem
title="Source Path"
data={sourcePath}
/>
<DescriptionListItem
title="Source Relative Path"
data={sourceRelativePath}
/>
<DescriptionListItem
title="Destination Path"
data={path}
/>
<DescriptionListItem
title="Destination Relative Path"
data={relativePath}
/>
</DescriptionList>
);
}
if (eventType === 'downloadIgnored') {
const {
message
} = data;
return (
<DescriptionList>
<DescriptionListItem
descriptionClassName={styles.description}
title="Name"
data={sourceTitle}
/>
{
!!message &&
<DescriptionListItem
title="Message"
data={message}
/>
}
</DescriptionList>
);
}
return (
<DescriptionList>
<DescriptionListItem
descriptionClassName={styles.description}
title="Name"
data={sourceTitle}
/>
</DescriptionList>
);
}
HistoryDetails.propTypes = {
eventType: PropTypes.string.isRequired,
sourceTitle: PropTypes.string.isRequired,
data: PropTypes.object.isRequired,
shortDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired
};
export default HistoryDetails;

View File

@@ -0,0 +1,19 @@
import _ from 'lodash';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import HistoryDetails from './HistoryDetails';
function createMapStateToProps() {
return createSelector(
createUISettingsSelector(),
(uiSettings) => {
return _.pick(uiSettings, [
'shortDateFormat',
'timeFormat'
]);
}
);
}
export default connect(createMapStateToProps)(HistoryDetails);

View File

@@ -0,0 +1,5 @@
.markAsFailedButton {
composes: button from '~Components/Link/Button.css';
margin-right: auto;
}

View File

@@ -0,0 +1,106 @@
import PropTypes from 'prop-types';
import React from 'react';
import { kinds } from 'Helpers/Props';
import Button from 'Components/Link/Button';
import SpinnerButton from 'Components/Link/SpinnerButton';
import Modal from 'Components/Modal/Modal';
import ModalContent from 'Components/Modal/ModalContent';
import ModalHeader from 'Components/Modal/ModalHeader';
import ModalBody from 'Components/Modal/ModalBody';
import ModalFooter from 'Components/Modal/ModalFooter';
import HistoryDetails from './HistoryDetails';
import styles from './HistoryDetailsModal.css';
function getHeaderTitle(eventType) {
switch (eventType) {
case 'grabbed':
return 'Grabbed';
case 'downloadFailed':
return 'Download Failed';
case 'downloadFolderImported':
return 'Episode Imported';
case 'episodeFileDeleted':
return 'Episode File Deleted';
case 'episodeFileRenamed':
return 'Episode File Renamed';
case 'downloadIgnored':
return 'Download Ignored';
default:
return 'Unknown';
}
}
function HistoryDetailsModal(props) {
const {
isOpen,
eventType,
sourceTitle,
data,
isMarkingAsFailed,
shortDateFormat,
timeFormat,
onMarkAsFailedPress,
onModalClose
} = props;
return (
<Modal
isOpen={isOpen}
onModalClose={onModalClose}
>
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{getHeaderTitle(eventType)}
</ModalHeader>
<ModalBody>
<HistoryDetails
eventType={eventType}
sourceTitle={sourceTitle}
data={data}
shortDateFormat={shortDateFormat}
timeFormat={timeFormat}
/>
</ModalBody>
<ModalFooter>
{
eventType === 'grabbed' &&
<SpinnerButton
className={styles.markAsFailedButton}
kind={kinds.DANGER}
isSpinning={isMarkingAsFailed}
onPress={onMarkAsFailedPress}
>
Mark as Failed
</SpinnerButton>
}
<Button
onPress={onModalClose}
>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
}
HistoryDetailsModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
eventType: PropTypes.string.isRequired,
sourceTitle: PropTypes.string.isRequired,
data: PropTypes.object.isRequired,
isMarkingAsFailed: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired,
onMarkAsFailedPress: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
HistoryDetailsModal.defaultProps = {
isMarkingAsFailed: false
};
export default HistoryDetailsModal;

View File

@@ -0,0 +1,172 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { align, icons } from 'Helpers/Props';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
import TablePager from 'Components/Table/TablePager';
import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody';
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
import FilterMenu from 'Components/Menu/FilterMenu';
import HistoryRowConnector from './HistoryRowConnector';
class History extends Component {
//
// Lifecycle
shouldComponentUpdate(nextProps) {
// Don't update when fetching has completed if items have changed,
// before episodes start fetching or when episodes start fetching.
if (
(
this.props.isFetching &&
nextProps.isPopulated &&
hasDifferentItems(this.props.items, nextProps.items)
) ||
(!this.props.isEpisodesFetching && nextProps.isEpisodesFetching)
) {
return false;
}
return true;
}
//
// Render
render() {
const {
isFetching,
isPopulated,
error,
items,
columns,
selectedFilterKey,
filters,
totalRecords,
isEpisodesFetching,
isEpisodesPopulated,
episodesError,
onFilterSelect,
onFirstPagePress,
...otherProps
} = this.props;
const isFetchingAny = isFetching || isEpisodesFetching;
const isAllPopulated = isPopulated && (isEpisodesPopulated || !items.length);
const hasError = error || episodesError;
return (
<PageContent title="History">
<PageToolbar>
<PageToolbarSection>
<PageToolbarButton
label="Refresh"
iconName={icons.REFRESH}
isSpinning={isFetching}
onPress={onFirstPagePress}
/>
</PageToolbarSection>
<PageToolbarSection alignContent={align.RIGHT}>
<TableOptionsModalWrapper
{...otherProps}
columns={columns}
>
<PageToolbarButton
label="Options"
iconName={icons.TABLE}
/>
</TableOptionsModalWrapper>
<FilterMenu
alignMenu={align.RIGHT}
selectedFilterKey={selectedFilterKey}
filters={filters}
customFilters={[]}
onFilterSelect={onFilterSelect}
/>
</PageToolbarSection>
</PageToolbar>
<PageContentBody>
{
isFetchingAny && !isAllPopulated &&
<LoadingIndicator />
}
{
!isFetchingAny && hasError &&
<div>Unable to load history</div>
}
{
// If history isPopulated and it's empty show no history found and don't
// wait for the episodes to populate because they are never coming.
isPopulated && !hasError && !items.length &&
<div>
No history found
</div>
}
{
isAllPopulated && !hasError && !!items.length &&
<div>
<Table
columns={columns}
{...otherProps}
>
<TableBody>
{
items.map((item) => {
return (
<HistoryRowConnector
key={item.id}
columns={columns}
{...item}
/>
);
})
}
</TableBody>
</Table>
<TablePager
totalRecords={totalRecords}
isFetching={isFetchingAny}
onFirstPagePress={onFirstPagePress}
{...otherProps}
/>
</div>
}
</PageContentBody>
</PageContent>
);
}
}
History.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
selectedFilterKey: PropTypes.string.isRequired,
filters: PropTypes.arrayOf(PropTypes.object).isRequired,
totalRecords: PropTypes.number,
isEpisodesFetching: PropTypes.bool.isRequired,
isEpisodesPopulated: PropTypes.bool.isRequired,
episodesError: PropTypes.object,
onFilterSelect: PropTypes.func.isRequired,
onFirstPagePress: PropTypes.func.isRequired
};
export default History;

View File

@@ -0,0 +1,162 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import withCurrentPage from 'Components/withCurrentPage';
import * as historyActions from 'Store/Actions/historyActions';
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
import { clearEpisodeFiles } from 'Store/Actions/episodeFileActions';
import History from './History';
function createMapStateToProps() {
return createSelector(
(state) => state.history,
(state) => state.episodes,
(history, episodes) => {
return {
isEpisodesFetching: episodes.isFetching,
isEpisodesPopulated: episodes.isPopulated,
episodesError: episodes.error,
...history
};
}
);
}
const mapDispatchToProps = {
...historyActions,
fetchEpisodes,
clearEpisodes,
clearEpisodeFiles
};
class HistoryConnector extends Component {
//
// Lifecycle
componentDidMount() {
const {
useCurrentPage,
fetchHistory,
gotoHistoryFirstPage
} = this.props;
registerPagePopulator(this.repopulate);
if (useCurrentPage) {
fetchHistory();
} else {
gotoHistoryFirstPage();
}
}
componentDidUpdate(prevProps) {
if (hasDifferentItems(prevProps.items, this.props.items)) {
const episodeIds = selectUniqueIds(this.props.items, 'episodeId');
if (episodeIds.length) {
this.props.fetchEpisodes({ episodeIds });
} else {
this.props.clearEpisodes();
}
}
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearHistory();
this.props.clearEpisodes();
this.props.clearEpisodeFiles();
}
//
// Control
repopulate = () => {
this.props.fetchHistory();
}
//
// Listeners
onFirstPagePress = () => {
this.props.gotoHistoryFirstPage();
}
onPreviousPagePress = () => {
this.props.gotoHistoryPreviousPage();
}
onNextPagePress = () => {
this.props.gotoHistoryNextPage();
}
onLastPagePress = () => {
this.props.gotoHistoryLastPage();
}
onPageSelect = (page) => {
this.props.gotoHistoryPage({ page });
}
onSortPress = (sortKey) => {
this.props.setHistorySort({ sortKey });
}
onFilterSelect = (selectedFilterKey) => {
this.props.setHistoryFilter({ selectedFilterKey });
}
onTableOptionChange = (payload) => {
this.props.setHistoryTableOption(payload);
if (payload.pageSize) {
this.props.gotoHistoryFirstPage();
}
}
//
// Render
render() {
return (
<History
onFirstPagePress={this.onFirstPagePress}
onPreviousPagePress={this.onPreviousPagePress}
onNextPagePress={this.onNextPagePress}
onLastPagePress={this.onLastPagePress}
onPageSelect={this.onPageSelect}
onSortPress={this.onSortPress}
onFilterSelect={this.onFilterSelect}
onTableOptionChange={this.onTableOptionChange}
{...this.props}
/>
);
}
}
HistoryConnector.propTypes = {
useCurrentPage: PropTypes.bool.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
fetchHistory: PropTypes.func.isRequired,
gotoHistoryFirstPage: PropTypes.func.isRequired,
gotoHistoryPreviousPage: PropTypes.func.isRequired,
gotoHistoryNextPage: PropTypes.func.isRequired,
gotoHistoryLastPage: PropTypes.func.isRequired,
gotoHistoryPage: PropTypes.func.isRequired,
setHistorySort: PropTypes.func.isRequired,
setHistoryFilter: PropTypes.func.isRequired,
setHistoryTableOption: PropTypes.func.isRequired,
clearHistory: PropTypes.func.isRequired,
fetchEpisodes: PropTypes.func.isRequired,
clearEpisodes: PropTypes.func.isRequired,
clearEpisodeFiles: PropTypes.func.isRequired
};
export default withCurrentPage(
connect(createMapStateToProps, mapDispatchToProps)(HistoryConnector)
);

View File

@@ -0,0 +1,6 @@
.cell {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 35px;
text-align: center;
}

View File

@@ -0,0 +1,86 @@
import PropTypes from 'prop-types';
import React from 'react';
import { icons, kinds } from 'Helpers/Props';
import Icon from 'Components/Icon';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import styles from './HistoryEventTypeCell.css';
function getIconName(eventType) {
switch (eventType) {
case 'grabbed':
return icons.DOWNLOADING;
case 'seriesFolderImported':
return icons.DRIVE;
case 'downloadFolderImported':
return icons.DOWNLOADED;
case 'downloadFailed':
return icons.DOWNLOADING;
case 'episodeFileDeleted':
return icons.DELETE;
case 'episodeFileRenamed':
return icons.ORGANIZE;
case 'downloadIgnored':
return icons.IGNORE;
default:
return icons.UNKNOWN;
}
}
function getIconKind(eventType) {
switch (eventType) {
case 'downloadFailed':
return kinds.DANGER;
default:
return kinds.DEFAULT;
}
}
function getTooltip(eventType, data) {
switch (eventType) {
case 'grabbed':
return `Episode grabbed from ${data.indexer} and sent to ${data.downloadClient}`;
case 'seriesFolderImported':
return 'Episode imported from series folder';
case 'downloadFolderImported':
return 'Episode downloaded successfully and picked up from download client';
case 'downloadFailed':
return 'Episode download failed';
case 'episodeFileDeleted':
return 'Episode file deleted';
case 'episodeFileRenamed':
return 'Episode file renamed';
case 'downloadIgnored':
return 'Episode Download Ignored';
default:
return 'Unknown event';
}
}
function HistoryEventTypeCell({ eventType, data }) {
const iconName = getIconName(eventType);
const iconKind = getIconKind(eventType);
const tooltip = getTooltip(eventType, data);
return (
<TableRowCell
className={styles.cell}
title={tooltip}
>
<Icon
name={iconName}
kind={iconKind}
/>
</TableRowCell>
);
}
HistoryEventTypeCell.propTypes = {
eventType: PropTypes.string.isRequired,
data: PropTypes.object
};
HistoryEventTypeCell.defaultProps = {
data: {}
};
export default HistoryEventTypeCell;

View File

@@ -0,0 +1,23 @@
.downloadClient {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 120px;
}
.indexer {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 80px;
}
.releaseGroup {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 110px;
}
.details {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 30px;
}

View File

@@ -0,0 +1,263 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { icons } from 'Helpers/Props';
import IconButton from 'Components/Link/IconButton';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
import TableRow from 'Components/Table/TableRow';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import episodeEntities from 'Episode/episodeEntities';
import SeasonEpisodeNumber from 'Episode/SeasonEpisodeNumber';
import EpisodeTitleLink from 'Episode/EpisodeTitleLink';
import EpisodeLanguage from 'Episode/EpisodeLanguage';
import EpisodeQuality from 'Episode/EpisodeQuality';
import SeriesTitleLink from 'Series/SeriesTitleLink';
import HistoryEventTypeCell from './HistoryEventTypeCell';
import HistoryDetailsModal from './Details/HistoryDetailsModal';
import styles from './HistoryRow.css';
class HistoryRow extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
isDetailsModalOpen: false
};
}
componentDidUpdate(prevProps) {
if (
prevProps.isMarkingAsFailed &&
!this.props.isMarkingAsFailed &&
!this.props.markAsFailedError
) {
this.setState({ isDetailsModalOpen: false });
}
}
//
// Listeners
onDetailsPress = () => {
this.setState({ isDetailsModalOpen: true });
}
onDetailsModalClose = () => {
this.setState({ isDetailsModalOpen: false });
}
//
// Render
render() {
const {
episodeId,
series,
episode,
language,
languageCutoffNotMet,
quality,
qualityCutoffNotMet,
eventType,
sourceTitle,
date,
data,
isMarkingAsFailed,
columns,
shortDateFormat,
timeFormat,
onMarkAsFailedPress
} = this.props;
if (!episode) {
return null;
}
return (
<TableRow>
{
columns.map((column) => {
const {
name,
isVisible
} = column;
if (!isVisible) {
return null;
}
if (name === 'eventType') {
return (
<HistoryEventTypeCell
key={name}
eventType={eventType}
data={data}
/>
);
}
if (name === 'series.sortTitle') {
return (
<TableRowCell key={name}>
<SeriesTitleLink
titleSlug={series.titleSlug}
title={series.title}
/>
</TableRowCell>
);
}
if (name === 'episode') {
return (
<TableRowCell key={name}>
<SeasonEpisodeNumber
seasonNumber={episode.seasonNumber}
episodeNumber={episode.episodeNumber}
absoluteEpisodeNumber={episode.absoluteEpisodeNumber}
seriesType={series.seriesType}
alternateTitles={series.alternateTitles}
sceneSeasonNumber={episode.sceneSeasonNumber}
sceneEpisodeNumber={episode.sceneEpisodeNumber}
sceneAbsoluteEpisodeNumber={episode.sceneAbsoluteEpisodeNumber}
/>
</TableRowCell>
);
}
if (name === 'episodeTitle') {
return (
<TableRowCell key={name}>
<EpisodeTitleLink
episodeId={episodeId}
episodeEntity={episodeEntities.EPISODES}
seriesId={series.id}
episodeTitle={episode.title}
showOpenSeriesButton={true}
/>
</TableRowCell>
);
}
if (name === 'language') {
return (
<TableRowCell key={name}>
<EpisodeLanguage
language={language}
isCutoffMet={languageCutoffNotMet}
/>
</TableRowCell>
);
}
if (name === 'quality') {
return (
<TableRowCell key={name}>
<EpisodeQuality
quality={quality}
isCutoffMet={qualityCutoffNotMet}
/>
</TableRowCell>
);
}
if (name === 'date') {
return (
<RelativeDateCellConnector
key={name}
date={date}
/>
);
}
if (name === 'downloadClient') {
return (
<TableRowCell
key={name}
className={styles.downloadClient}
>
{data.downloadClient}
</TableRowCell>
);
}
if (name === 'indexer') {
return (
<TableRowCell
key={name}
className={styles.indexer}
>
{data.indexer}
</TableRowCell>
);
}
if (name === 'releaseGroup') {
return (
<TableRowCell
key={name}
className={styles.releaseGroup}
>
{data.releaseGroup}
</TableRowCell>
);
}
if (name === 'details') {
return (
<TableRowCell
key={name}
className={styles.details}
>
<IconButton
name={icons.INFO}
onPress={this.onDetailsPress}
/>
</TableRowCell>
);
}
return null;
})
}
<HistoryDetailsModal
isOpen={this.state.isDetailsModalOpen}
eventType={eventType}
sourceTitle={sourceTitle}
data={data}
isMarkingAsFailed={isMarkingAsFailed}
shortDateFormat={shortDateFormat}
timeFormat={timeFormat}
onMarkAsFailedPress={onMarkAsFailedPress}
onModalClose={this.onDetailsModalClose}
/>
</TableRow>
);
}
}
HistoryRow.propTypes = {
episodeId: PropTypes.number,
series: PropTypes.object.isRequired,
episode: PropTypes.object,
language: PropTypes.object.isRequired,
languageCutoffNotMet: PropTypes.bool.isRequired,
quality: PropTypes.object.isRequired,
qualityCutoffNotMet: PropTypes.bool.isRequired,
eventType: PropTypes.string.isRequired,
sourceTitle: PropTypes.string.isRequired,
date: PropTypes.string.isRequired,
data: PropTypes.object.isRequired,
isMarkingAsFailed: PropTypes.bool,
markAsFailedError: PropTypes.object,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
shortDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired,
onMarkAsFailedPress: PropTypes.func.isRequired
};
export default HistoryRow;

View File

@@ -0,0 +1,76 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions';
import createSeriesSelector from 'Store/Selectors/createSeriesSelector';
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import HistoryRow from './HistoryRow';
function createMapStateToProps() {
return createSelector(
createSeriesSelector(),
createEpisodeSelector(),
createUISettingsSelector(),
(series, episode, uiSettings) => {
return {
series,
episode,
shortDateFormat: uiSettings.shortDateFormat,
timeFormat: uiSettings.timeFormat
};
}
);
}
const mapDispatchToProps = {
fetchHistory,
markAsFailed
};
class HistoryRowConnector extends Component {
//
// Lifecycle
componentDidUpdate(prevProps) {
if (
prevProps.isMarkingAsFailed &&
!this.props.isMarkingAsFailed &&
!this.props.markAsFailedError
) {
this.props.fetchHistory();
}
}
//
// Listeners
onMarkAsFailedPress = () => {
this.props.markAsFailed({ id: this.props.id });
}
//
// Render
render() {
return (
<HistoryRow
{...this.props}
onMarkAsFailedPress={this.onMarkAsFailedPress}
/>
);
}
}
HistoryRowConnector.propTypes = {
id: PropTypes.number.isRequired,
isMarkingAsFailed: PropTypes.bool,
markAsFailedError: PropTypes.object,
fetchHistory: PropTypes.func.isRequired,
markAsFailed: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(HistoryRowConnector);

View File

@@ -0,0 +1,13 @@
.torrent {
composes: label from '~Components/Label.css';
border-color: $torrentColor;
background-color: $torrentColor;
}
.usenet {
composes: label from '~Components/Label.css';
border-color: $usenetColor;
background-color: $usenetColor;
}

View File

@@ -0,0 +1,20 @@
import PropTypes from 'prop-types';
import React from 'react';
import Label from 'Components/Label';
import styles from './ProtocolLabel.css';
function ProtocolLabel({ protocol }) {
const protocolName = protocol === 'usenet' ? 'nzb' : protocol;
return (
<Label className={styles[protocol]}>
{protocolName}
</Label>
);
}
ProtocolLabel.propTypes = {
protocol: PropTypes.string.isRequired
};
export default ProtocolLabel;

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