Compare commits

..

522 Commits

Author SHA1 Message Date
Bogdan 5d1f79f3a3 Bump FluentMigrator to official 6.2.0
(cherry picked from commit de722539d098ba67a605cc369e55209667760692)
2025-10-30 09:42:29 -05:00
Bogdan 0ef9f4c869 Fix newznab redirect database migration
(cherry picked from commit f67bc52f85fa0677f4cda5b7b7dcb30dfe31468a)
2025-10-30 09:42:03 -05:00
bakerboy448 e4fb36e08f Bump to 2.3.0 2025-10-30 05:51:48 -05:00
Mark McDowall ff22fdf7d3 Set known networks to RFC 1918 ranges during startup
(cherry picked from commit d10107739b9ed6a50165e5dd1dfae15c7e8aea56)
2025-10-29 23:42:00 +00:00
Polgonite b3d46465ae Fixed: qBittorrent /login API success check 2025-10-29 17:59:58 -05:00
bakerboy448 eb57d20545 Bump to 2.2.0 2025-10-25 14:42:07 -05:00
bakerboy448 775b716c0f Fixed:(RuTracker) fix for Anime S01nd Episode N of N or N+N of N+N
Based on Jackett 5b712189fc55470dc94b56ea0d764e123e2dc432
2025-10-20 18:19:42 -05:00
bakerboy448 f7f3648dac Bump to 2.1.5 2025-10-13 19:42:22 -05:00
Bogdan c669048767 Bump System.Data.SQLite, MailKit, Microsoft.Data.SqlClient, Newtonsoft.Json and Polly
(cherry picked from commit 86282d621b3edcbf3582d6321de8be4172d37ed2)
2025-10-05 12:18:14 -05:00
Bogdan c282e4bef8 Pin System.Private.Uri to 4.3.2
(cherry picked from commit e0180e397d90db01e8cee0ee38419eb0b6bce989)
2025-10-05 12:18:14 -05:00
bakerboy448 574721bfb5 Bump to 2.1.4 2025-10-05 12:18:07 -05:00
bakerboy448 3c7575b58e fixup! Pin System.Drawing.Common to 8.0 (#2514) 2025-10-02 10:36:03 -05:00
Bogdan 93d8f81750 Fix code coverage on CI 2025-10-02 10:31:48 -05:00
Bogdan 364c7c9c7e Avoid rewriting file names in builds
Signed-off-by: bakerboy448 <55419169+bakerboy448@users.noreply.github.com>
2025-10-02 10:31:48 -05:00
Bogdan 54af7fd3d0 Bump coverlet.collector to official 6.0.4
Bump NUnit3TestAdapter to 5.1.0
Bump NunitXml.TestLogger to 3.1.20
2025-10-02 10:31:48 -05:00
bakerboy448 e6bc7fa062 Pin System.Drawing.Common to 8.0 (#2514) 2025-10-02 09:36:12 -05:00
bakerboy448 98608e75a6 Fixup theme selector App name 2025-10-01 10:21:22 -05:00
Bogdan 160320f3a2 Switch HttpProxySettingsProviderFixture to test cases
(cherry picked from commit 4e8fe6e81b1ac3f53135ad2e2b95d7aae811b87e)
2025-09-30 21:48:50 -05:00
Collin Heist c9baaf634e Fixed: Prevent modals from overflowing screen width
(cherry picked from commit 6c581b7e3c5c74db350d7ba2aad04f2df77c7671)
2025-09-30 21:46:34 -05:00
Stevie Robinson 8bf2f68abe New: Switch theme automatically on system change
(cherry picked from commit 4904e85887b8455483e509b83abaa2c6517d45a0)
2025-09-30 21:46:32 -05:00
Bogdan 9434091912 New: Retry SQLite writes for database is locked errors
(cherry picked from commit 2e1289b9248a70ce50bde52a66d3a589f3dcb8f5)
2025-09-30 21:46:28 -05:00
Zac Bowling 2f7d821d45 Fixed: (RevolutionTT) New Domain (#2511)
* RevolutionTT switched domains

* fixup!

Co-authored-by: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com>

---------

Co-authored-by: bakerboy448 <55419169+bakerboy448@users.noreply.github.com>
Co-authored-by: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com>
2025-09-30 20:39:28 -05:00
Bogdan 471c9910a0 Bump System.Data.SQLite to official 2.0.1 2025-09-30 13:24:39 -05:00
Bogdan 98ff2f5cb6 Bump STJson, MailKit and Polly 2025-09-30 13:24:39 -05:00
bakerboy448 4d9982872a New: (PTP) Improve Error Handling 2025-09-30 11:43:56 -05:00
bakerboy448 ae9326480e fixup! New: Move CGPeers to Cardigann 2025-09-30 11:41:57 -05:00
Ryan S 624cbd548f Fixed: (Indexer) Shazbat added new site url
Moved old url to LegacyUrls
2025-09-30 11:28:09 -05:00
bakerboy448 f5f98e4f53 New: Move CGPeers to Cardigann 2025-09-25 09:36:56 -05:00
Weblate 8585dd447e Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Pazuzu6666 <fukscam978@gmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_TW/
Translation: Servarr/Prowlarr
2025-09-25 09:29:25 -05:00
bakerboy448 dfffb3aa4e Bump to 2.1.3 2025-09-21 14:53:25 -05:00
bakerboy448 7eb2d956cf Bump to 2.1.2 2025-09-14 22:29:17 -05:00
thisaccountwillmakeprs 8da493dbaf Fixed: (BroadcasTheNet) Improve daily episode searching (#2500) 2025-09-13 10:37:29 -05:00
bakerboy448 f17cf6144f docs: Update bug report template for clarity
[skip ci]
2025-09-07 12:23:51 -05:00
bakerboy448 1b3adc4529 docs: Fix typos in bug report template labels and descriptions
[skip ci]
2025-09-07 12:08:30 -05:00
bakerboy448 389f049a8b docs: Update bug report template for clarity and accuracy
[skip ci]
2025-09-07 12:06:05 -05:00
bakerboy448 99b0fcd750 Bump to 2.1.1 2025-09-07 00:27:28 -05:00
bakerboy448 516b09ca91 Fixed: Rename (Newznab) nzb.su to nzb.life
rename ApiKeyWhiteList to ApiKeyAllowList

Co-authored-by: Stevie<stevie.robinson@gmail.com>
2025-09-06 21:15:04 -05:00
bakerboy448 770fd64013 Revert Various
Revert "Fixed: (HttpClient) Increase cookie limit per domain to 100"

This reverts commit f67c672ec7.

Revert "Add exclusive only"

This reverts commit 80425f5ea4.

Revert "GGn Snatched + Pagination"This reverts commit 758cae3f40.

Revert "Fixed: (PassThePopcorn) Generate titles for full discs"

This reverts commit fbf4ff6777.
2025-09-06 10:57:17 -05:00
Bogdan f67c672ec7 Fixed: (HttpClient) Increase cookie limit per domain to 100 2025-09-06 07:15:05 -05:00
Bogdan 80425f5ea4 Add exclusive only 2025-09-06 07:14:55 -05:00
Bogdan 758cae3f40 GGn Snatched + Pagination 2025-09-06 07:14:43 -05:00
Bogdan fbf4ff6777 Fixed: (PassThePopcorn) Generate titles for full discs 2025-09-06 07:14:32 -05:00
Bogdan 98ee9c1703 Fixed: Responsive add indexer modal layout filters 2025-09-06 07:14:20 -05:00
bakerboy448 c537e94f0f New: INTERNAL flag support for Cardigann Indexers based on Description 2025-09-05 16:12:03 -05:00
bakerboy448 9e5dd2a2e6 Fixed: (Newznab) nzb.su to nzb.life
Change url for built in defintion
2025-09-03 10:56:22 -05:00
bakerboy448 f601ff98a2 New: (FileList) Add Cat 31 and refresh urls 2025-09-01 14:27:33 -05:00
Weblate 540fafdebf Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Jeremi Florczyk <j.m.florczyk@gmail.com>
Co-authored-by: NanderTGA <nander.roobaert@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Xoores <servarr-35466@xoores.cz>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translation: Servarr/Prowlarr
2025-09-01 14:27:20 -05:00
bakerboy448 532bffe772 Bump to 2.1.0 2025-08-23 15:47:28 -05:00
bakerboy448 bf80f7916c Improve UX of indexer urls error logging 2025-08-21 14:48:05 -05:00
bakerboy448 2f6a9dfffb New: Improve Indexer Connection Failure Messaging (#2473) 2025-08-20 11:25:27 -05:00
Weblate 94477e9cf9 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Jeremi Florczyk <j.m.florczyk@gmail.com>
Co-authored-by: Marcin <ml.cichy@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translation: Servarr/Prowlarr
2025-08-20 11:25:05 -05:00
ilike2burnthing 52e21b3dfc Fixed:(toloka) improve episode regex & trim (#2471)
toloka: improve episode regex & trim
2025-08-18 20:38:22 -05:00
Eugene Shatilo cb4cc81ad0 Fixed:(RuTracker) corrected regexp for director’s name in the title to cover cases for Russian directors (#2470)
Corrected regexp for rutracker director's name in the title to cover cases for russian directors
2025-08-17 21:51:57 -05:00
bakerboy448 7ada036480 Fixed: Mobile add indexer modal layout (#2464)
* New: Add Indexer Filters are Collapsible

fixes #2431

* Fixed: Rename onToggleFilters to handleToggleFilters

* fix css lint
2025-08-17 21:46:59 -05:00
bakerboy448 f1c9ba40c4 Bump to 2.0.5 2025-08-17 14:43:48 -04:00
Mark McDowall 8664fc095d New: Move auth success logging to debug
Closes #7978
2025-08-11 22:38:25 -05:00
Mark McDowall 23b9973ef7 Don't log debug messages for API key validation
(cherry picked from commit 78ca30d1f81361a2dabaddd0036b764859b858af)
2025-08-11 18:34:24 -05:00
Weblate d9f1d96e00 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Tim81 <tvdham@hotmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translation: Servarr/Prowlarr
2025-08-11 18:26:34 -05:00
bakerboy448 d9d045a548 Bump version to 2.0.4 2025-08-10 23:24:55 -05:00
Robin Dadswell c417c41133 Fixed: Saving Newznab indexer when redirect was true 2025-08-05 13:30:21 +01:00
Weblate d5853735ac Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: ArLab1 <arnaud.laberge@hotmail.com>
Co-authored-by: Oleksii Ilienko <assada.ua@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translation: Servarr/Prowlarr
2025-08-05 06:12:08 -05:00
Robin Dadswell dbc159f536 New: Force all usenet indexers to use Redirection 2025-08-04 10:39:45 +01:00
Robin Dadswell 231cc91f97 New: Updated all newznab indexers to be redirect 2025-08-04 10:39:45 +01:00
Mike Miller 1a075f201c Fixed: (Xpseeds) Update categories (#2458)
Sync with Jackett
2025-08-03 13:12:59 -05:00
bakerboy448 de7f42cf30 Bump version to 2.0.3 2025-07-23 08:50:43 -05:00
bakerboy448 fab74b58fa New: (Avistaz Sites) Use created_at_iso for release create date (#2437)
* New: (Avistaz Sites) Use created_at_iso for release create date

no longer have timezone headaches
all Staz sites except animetorrents support this new field.

* fix tests

* Remove AvistaZ TimezoneOffset
2025-07-19 07:43:26 -04:00
bakerboy448 2b332a00d7 Bump version to 2.0.2 2025-07-08 18:36:38 -05:00
Weblate a0b0c1555c Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: averyv86 <averyv86@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translation: Servarr/Prowlarr
2025-07-08 17:31:08 -05:00
bakerboy448 86b81948af Sync UiAuthorizationPolicyProvider with upstream
* Revert "Fixed: Fallback to Forms for removed Basic auth method"

This reverts commit fe198352a3.

* AuthPolicy Var fixes
2025-07-02 10:10:40 -05:00
Mark McDowall 54918e0c30 Change authentication to Forms if set to Basic
(cherry picked from commit 8e08b0cc3df904d39da5be38bc345cc701412a9d)
2025-06-28 09:29:52 -05:00
Bogdan 01dd793c0a Bump version to 2.0.1 2025-06-15 09:25:06 +03:00
Bogdan 950949e4bc Bump Polly to 8.6.0 2025-06-12 09:56:52 +03:00
Bogdan fe198352a3 Fixed: Fallback to Forms for removed Basic auth method 2025-06-11 20:13:03 +03:00
Bogdan 88502cd020 Fixed: (AnimeTosho) Mapping of Subcategory as Parent 2025-06-11 10:32:21 +03:00
Bogdan 4924b45b56 Fix various typos 2025-06-10 18:36:14 +03:00
Bogdan aea8b7cd7e Fixed: Redirect loop for removed basic auth method 2025-06-10 12:33:52 +03:00
Bogdan aafadb6111 Fix fullscreen automation screenshots 2025-06-09 22:08:00 +03:00
Mark McDowall c82f904d49 New: Add exception to SSL Certificate validation message
(cherry picked from commit d84c4500949a530fac92d73f7f2f8e8462b37244)
2025-06-08 16:37:52 +03:00
Servarr 60740fa259 Automated API Docs update 2025-06-08 10:33:02 +03:00
Mark McDowall d36b32f414 New: Remove Basic Auth
(cherry picked from commit 0f9e063e2146812f6e963363eee70a524612f354)
2025-06-07 19:23:03 +03:00
Bogdan 14ccd6d2a5 Fixed: Validation for tags label 2025-06-07 19:23:03 +03:00
Bogdan bdc3b63df2 Upgrade StyleCop.Analyzers to Unstable 1.2.0.556 2025-06-07 19:23:03 +03:00
Bogdan 8eec321a0e Bump Swashbuckle to 8.1.4 2025-06-07 19:23:03 +03:00
Bogdan 06de2313ab Bump version to 2.0.0 2025-06-07 19:23:03 +03:00
Bogdan a3f713bad8 New: Support removed for linux-x86 2025-06-07 19:23:03 +03:00
Bogdan 7a1fca5e23 New: Migrate appdata folder for .NET 8 on OSX 2025-06-07 19:23:03 +03:00
Bogdan 21c408a7da New: Bump to .NET 8 2025-06-07 19:23:03 +03:00
Weblate 0e92108970 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ilbebino <tommasobellandi08@gmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2025-06-06 14:41:02 +03:00
Bogdan 7d813ef97a Bump version to 1.38.0 2025-06-04 14:05:21 +03:00
Bogdan c87995250a Fixed: Sync indexers with basic search to Radarr and Sonarr
Fixes #2404
2025-06-03 14:26:09 +03:00
Bogdan a9f7a376c7 Bump version to 1.37.0 2025-05-25 17:00:17 +03:00
Bogdan c3ee3f2320 Fix jump to character for Search page 2025-05-25 14:04:33 +03:00
Weblate e8c26d0fea Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: thelooter <evekolb2204@gmail.com>
Co-authored-by: warkurre86 <tom.novo.86@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translation: Servarr/Prowlarr
2025-05-25 12:05:56 +03:00
Bogdan 9c936121e8 Fixed: Sync indexers with basic search to Lidarr and Readarr
Fixes #2402
2025-05-22 13:30:41 +03:00
Bogdan 40d2e40d94 Fail build on missing test results
Ignore missing test results failure on FreeBSD
2025-05-18 18:01:13 +03:00
Weblate 837f50c91c Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Hugoren Martinako <aumpfbahn@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2025-05-18 14:10:34 +03:00
Bogdan f0a0202e5c Bump version to 1.36.3 2025-05-18 14:10:14 +03:00
Bogdan 708c94bc56 Fixed PTP test 2025-05-15 00:47:46 +03:00
Bogdan 5ed82eaf09 Fixed: (PTP) Download torrent files with API credentials 2025-05-14 22:44:26 +03:00
Bogdan 7d77ad68fd Bump caniuse db 2025-05-14 21:25:20 +03:00
Bogdan 6725358db5 Bump babel, fontawesome icons, react-use-measure, react-virtualized and react-window 2025-05-14 21:25:20 +03:00
Bogdan c410e23460 Bump core-js to 3.42 2025-05-14 21:25:20 +03:00
Bogdan 903b86b9a2 Bump version to 1.36.2 2025-05-11 14:48:48 +03:00
Weblate 52a49e6a34 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Discover999 <13189912235@163.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: ZijiYu <ziji.yu@stonybrook.edu>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_Hans/
Translation: Servarr/Prowlarr
2025-05-11 00:07:11 +03:00
Bogdan a7d99f351c Fixed: Parsing user agents without a version
Fixes #2392
2025-05-11 00:05:29 +03:00
Bogdan b0212dd780 Add hourly limits as defaults for PTP 2025-05-10 11:55:11 +03:00
Bogdan c8f5099423 Use the thrown exception in http timeout handling 2025-05-09 15:58:02 +03:00
Bogdan 5cc4c3f302 Bump version to 1.36.1 2025-05-04 21:06:28 +03:00
Bogdan c0d2cb42e9 Fixed: (PTP) Sorting releases by time added 2025-05-01 17:06:17 +03:00
Bogdan 8081f13052 Clean logging messages in AppriseProxy 2025-05-01 12:12:47 +03:00
Bogdan 84b672e617 Fixed: Sync indexers to apps only if search is available 2025-05-01 01:34:09 +03:00
Bogdan ed586c2d72 Update fixture file for PTP 2025-05-01 00:30:55 +03:00
Bogdan 233176e321 Improve error message when BHD's API responds with HTML 2025-04-30 22:12:30 +03:00
Bogdan d1e3390bae Fixed: (PTP) Category mapping for search results 2025-04-30 22:12:30 +03:00
Bogdan 1cd60c7a40 Bump version to 1.36.0 2025-04-30 14:03:05 +03:00
Bogdan c61cfcd312 Avoid logging the whole response in the exception when not finding JSON selectors in Cardigann 2025-04-30 12:36:34 +03:00
Weblate 5eb4d112ca Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translation: Servarr/Prowlarr
2025-04-29 11:05:21 +03:00
Mark McDowall 70f2361d69 Improve messaging when NZB contains invalid XML
(cherry picked from commit 728df146ada115a367bf1ce808482a4625e6098d)
2025-04-29 10:58:31 +03:00
Bogdan 1d6babaa15 Bump caniuse db 2025-04-29 10:23:51 +03:00
Bogdan 0427add8d0 Bump core-js to 3.41 2025-04-29 10:23:15 +03:00
Bogdan 010c2b836d Clean up formatted strings in log messages 2025-04-29 10:16:59 +03:00
Bogdan 22c4c1fc9a Pass messages with arguments to NLog in LoggerExtensions
(cherry picked from commit 9683b0af35220bb0af801779a06d73feaeba809a)
2025-04-29 10:14:32 +03:00
Bogdan d5f6cc94b8 Fixed: (PTP) TV search capabilities removed 2025-04-29 10:04:40 +03:00
Bogdan 411e96ef2a New: Redirect enabled by default when adding new usenet indexers 2025-04-28 21:52:09 +03:00
Bogdan 2b0e52ebca Update default log level message 2025-04-27 21:22:37 +03:00
Bogdan c6fa26ca7b Bump version to 1.35.1 2025-04-27 11:48:50 +03:00
blu3 c85f170d41 Bump license year 2025-04-23 11:34:19 +03:00
Bogdan 48a658571b Improve error messaging for not finding JSON selectors in Cardigann 2025-04-21 14:39:22 +03:00
Weblate 0b3a5c9bc4 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Hugoren Martinako <aumpfbahn@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translation: Servarr/Prowlarr
2025-04-20 22:30:45 +03:00
Bogdan 356d07ef34 Bump version to 1.35.0 2025-04-20 22:30:15 +03:00
Bogdan 0322d70d63 Fixed: Handle 307 and 308 redirects for indexer download requests 2025-04-20 11:09:08 +03:00
Bogdan 362f3fe223 Bump version to 1.34.1 2025-04-13 09:48:04 +03:00
Bogdan 075fd24f96 Downgrade Microsoft.AspNetCore.WebUtilities 2025-04-12 17:23:45 +03:00
Bogdan 4ba72ea7f3 Bump Swashbuckle to 7.3.2 2025-04-12 14:54:56 +03:00
Bogdan 46f73c51bb Bump IPAddressRange, Npgsql, System.Text.Json 2025-04-12 14:54:01 +03:00
Bogdan 3287d45661 Update timezone offset for AvistaZ trackers 2025-04-12 14:42:25 +03:00
Bogdan 71937fa44c Update timezone offset for FL 2025-04-12 14:33:30 +03:00
Bogdan 6aefd46cd4 Fixed: (SecretCinema) Edition not being decoded 2025-04-12 14:31:29 +03:00
Bogdan c8370c9e00 Bump version to 1.34.0 2025-04-09 20:59:15 +03:00
Servarr 6be4203b41 Automated API Docs update 2025-04-09 10:29:44 +03:00
Bogdan 1339373e43 Bump Selenium.WebDriver.ChromeDriver 2025-04-08 13:30:56 +03:00
Bogdan fc9dfb0cf7 Fixed: Disallow tags creation with empty label 2025-04-08 13:30:03 +03:00
Mark McDowall 48301055ea Fixed: Set output encoding to UTF-8 when running external processes
(cherry picked from commit f8e57b09856278a6d0c65f18704e96a33459687d)
2025-04-08 13:29:32 +03:00
Mark McDowall 8a9518c9c1 Update WikiUrl type in API docs
(cherry picked from commit 9bd619ccfe074abe396bbf043a36a5be18a7ba4b)
2025-04-08 13:29:09 +03:00
Bogdan de099c6770 Log delete statements only once 2025-04-08 13:28:52 +03:00
Bogdan 07711da4e0 Bump version to 1.33.3 2025-04-06 15:44:25 +03:00
MrE12345 7cb70716d0 Fixed: (NorBits) Change encoding to UTF8 (#2367) 2025-04-06 12:43:24 +03:00
Weblate 548dedad5c Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ste <stefanucciu@gmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translation: Servarr/Prowlarr
2025-04-06 12:23:27 +03:00
Bogdan 7008626358 Fixed: (PassThePopcorn) Parse volume factors for neutral leech releases 2025-04-04 21:34:10 +03:00
Bogdan f6f2a3b00d Bump linux agent to ubuntu-22.04 2025-04-02 00:10:40 +03:00
Weblate 2b16d93095 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Alex Mills <alex@alexmills.uk>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fa/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translation: Servarr/Prowlarr
2025-03-30 10:30:41 +03:00
Bogdan e63ee13d23 Bump version to 1.33.2 2025-03-30 10:30:03 +03:00
Bogdan 5c5a163151 Fixed: (AnimeBytes) Allow season searching for ONA 2025-03-28 13:39:19 +02:00
Bogdan 023eec0ec0 Update timezone offset for PrivateHD and CinemaZ 2025-03-25 13:04:07 +02:00
Bogdan 5bc5f0e6b8 New: Categories, genres, indexer flags and publish dates for webhook releases 2025-03-25 13:00:53 +02:00
Bogdan 5cbacc01eb Fixed: Publish dates timezone in history details for grabbed releases 2025-03-25 13:00:53 +02:00
Bogdan f4f1b38324 New: On Grab notifications for CustomScript 2025-03-25 13:00:53 +02:00
Bogdan 758dddd4ad Bump version to 1.33.1 2025-03-23 09:45:33 +02:00
Bogdan 73ee695633 New: (BeyondHD) Parsing audio and subtitles languages 2025-03-22 21:01:22 +02:00
Bogdan 27fbd7ef7e Fixed: (RuTracker.org) Improve subtitles removal 2025-03-22 12:45:10 +02:00
Bogdan 5125f256fb Fixed: Priority validation for indexers and download clients 2025-03-20 20:38:13 +02:00
Mark McDowall b99e8d0d65 Improve logging when login fails due to CryptographicException
(cherry picked from commit 1449941471cbb8885e9298317b9a30f2576d7941)
2025-03-16 13:10:09 +02:00
Bogdan d20b2cc9c0 Bump NLog and Polly 2025-03-16 12:06:32 +02:00
Bogdan 8a1787bdb6 Bump version to 1.33.0 2025-03-16 11:42:07 +02:00
Mark McDowall a19b8ea997 New: Truncate button text
Fixes #2352

(cherry picked from commit 093ee5b88db0470426f6132e66a5893e5cf89bab)
2025-03-10 20:07:15 +02:00
Mark McDowall 10ea6cd753 Improve wrapping of text in sidebar
(cherry picked from commit f58dfc5605738ebccdd6adc6f1ca2a7843c086b2)
2025-03-10 20:07:15 +02:00
Bogdan 2c1b464715 New: Recommend against using uTorrent
(cherry picked from commit 6d8c3f15b343a24fc31a212463af8ed2b5792508)
2025-03-10 20:07:15 +02:00
Bogdan 3263454041 Bump version to 1.32.2 2025-03-09 11:50:31 +02:00
Servarr 015db4a916 Translations update from Servarr Weblate (#2351)
Multiple Translations updated by Weblate

ignore-downstream







Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_Hans/
Translation: Servarr/Prowlarr

Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: wangdj1314 <wangdj@risenenergy.com>
Co-authored-by: 葛磊磊 <geleilei198117@163.com>
2025-03-07 10:38:29 +02:00
Bogdan 49268f3b8d Fix timezone offset tests for AvistaZ trackers 2025-03-04 13:15:44 +02:00
Bogdan f02a6f3e2c Update timezone offset for AvistaZ trackers 2025-03-03 17:17:29 +02:00
Bogdan 46b6124b97 Bump version to 1.32.1 2025-03-02 12:17:40 +02:00
Bogdan 53bc97b3be Fixed: (BeyondHd) Search daily episodes using year-month-day format 2025-03-01 17:34:58 +02:00
Bogdan b09d4927cc Check instance name must contain application name with culture-insensitive 2025-03-01 13:38:34 +02:00
Bogdan 328f3c0423 Bump version to 1.32.0 2025-02-22 12:55:30 +02:00
Mark McDowall 635e76526a Cleanse console log messages
(cherry picked from commit 609e964794e17343f63e1ecff3fef323e3d284ff)
2025-02-19 15:59:34 +02:00
Stevie Robinson 790feed5ab Fixed: Fallback to Instance Name for Discord notifications
(cherry picked from commit b99e06acc0a3ecae2857d9225b35424c82c67a2b)
2025-02-19 15:55:42 +02:00
Mark McDowall 59b5d2fc78 Fixed: Drop downs flickering in some cases
(cherry picked from commit 3b024443c5447b7638a69a99809bf44b2419261f)
2025-02-18 17:09:56 +02:00
Bogdan d5b12cf51a Fixed release guid for SpeedApp 2025-02-18 04:00:24 +02:00
Bogdan 2d584f7eb6 New: Support for exclusive indexer flag
Co-authored-by: zakkarry <zak@ary.dev>
2025-02-18 02:11:57 +02:00
Bogdan 0f1d647cd7 Fixed: (FileList) Download links when passkey contains spaces 2025-02-16 12:22:44 +02:00
zodihax d6e8d89be4 Fixed: (NorBits) Update release category parsing (#2342)
Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com>
2025-02-12 19:27:09 +02:00
Bogdan 8672129d5a Fixed: (AnimeTorrents) Switched to cookies login 2025-02-12 15:52:22 +02:00
Bogdan 44bdff8b8f Minor cleanup for AnimeTorrents 2025-02-12 15:52:22 +02:00
Bogdan 4df8fc02f1 Bump version to 1.31.2 2025-02-09 17:51:35 +02:00
Weblate e101129cff Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Marius Nechifor <flm.marius@gmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fa/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2025-02-07 19:14:29 -06:00
Bogdan 147e732c9c Building docs on ARM
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2025-02-06 00:36:13 +02:00
Bogdan a12381fb1d Cleanse "rsskey" from logs 2025-02-05 20:06:51 +02:00
Bogdan 3a4de9cca1 Fixed: (MAM) Continue downloading if attempting to buy personal FL for VIP release 2025-02-05 19:59:48 +02:00
Bogdan 43c988d951 Fixed: (MAM) Use the latest cookies on release download 2025-02-05 19:51:20 +02:00
Bogdan a036e0fc37 Fixed: (MAM) Updated property name for user class 2025-02-05 19:42:32 +02:00
Bogdan 56b9da16cf Fix release category selector on all themes for NorBits
Co-authored-by: Garfield69 <garfield69@outlook.com>
2025-02-05 19:24:36 +02:00
zodihax 887c262589 Update release category selector for NorBits (#2338) 2025-02-05 12:55:53 +02:00
zodihax 12ff612775 Fixed: (NorBits) Added main categories to avoid invalid releases (#2337)
NorBits also has these main categories in addition to the already configured sub-categories. This PR adds these main categories.

Prowlarr often return 0 query results even when there are query results, this is probably caused by all the results only having a main category (for instance "TV") and no sub-categories.

`|Warn|NorBits|Invalid Release: '<redacted>' from indexer: NorBits. No categories provided.`
2025-02-03 18:03:40 +02:00
Bogdan 0d3d27e46f Fixed: (HDB) Use release name for full discs and XXX content 2025-02-02 18:51:12 +02:00
Bogdan d1846fde61 New: (Myanonamouse) Prevent downloads without FL tokens
Co-authored-by: Kalon Shannon-Innes <mav@hotmail.com.au>
2025-02-02 17:46:28 +02:00
Bogdan e6901506a0 Fixed: (IPTorrents) Cleanup languages between brackets when possible 2025-02-02 17:44:31 +02:00
Weblate 08b4eddbc5 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Mailme Dashite <mailmedashite@protonmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: marapavelka <mara.pavelka@gmail.com>
Co-authored-by: 宿命 <331874545@qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2025-02-02 16:13:56 +02:00
Bogdan 979db70e68 Bump version to 1.31.1 2025-02-02 12:47:52 +02:00
Bogdan 22834a852a Fixed: TV search with tmdbid for Newznab and Torznab 2025-01-29 18:39:22 +02:00
Bogdan f0540a5f8b Bump version to 1.31.0 2025-01-24 17:33:38 +02:00
Weblate 1f7ac7d7d6 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: HanaO00 <lwin24452@gmail.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translation: Servarr/Prowlarr
2025-01-24 13:19:05 +02:00
Bogdan 8ac68240ad Revert "Improve error message on non-JSON responses for Nebulance"
This reverts commit 2c3621d25e.
2025-01-23 16:42:41 +02:00
Bogdan b463a3f54b Update categories for RuTracker
Co-authored-by: Garfield69 <garfield69@outlook.com>
2025-01-23 15:27:45 +02:00
Bogdan e15e57329e Update categories for XSpeeds
Co-authored-by: Garfield69 <garfield69@outlook.com>
2025-01-23 15:27:45 +02:00
Bogdan d8354408a4 Update categories for AnimeTorrents
Co-authored-by: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com>
2025-01-23 15:27:45 +02:00
bakerboy448 6d2d49f7bd Fixed: (PTP) Filtering non-freeleech releases when using Freeleech Only
Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com>
2025-01-23 02:36:03 +02:00
Bogdan 37610eec40 Fixed: (TorrentDay) Improved error message for expired cookies 2025-01-22 19:44:49 +02:00
Steel City Phantom ed51208116 Auto-detect building on macOS ARM
(cherry picked from commit 64122b4cfb3bf53bdbf5c924baee5e1b0814501a)
2025-01-21 01:04:44 +02:00
Bogdan 26e4dcad65 Bump version to 1.30.2 2025-01-19 17:14:44 +02:00
Bogdan 6eb21a02a1 Bump NLog, Polly, System.Memory and AngleSharp 2025-01-15 23:23:30 +02:00
Bogdan 8c2d5a404d Fixed BR-DISK detection for AnimeBytes 2025-01-15 01:56:48 +02:00
Bogdan 3b83a00eaf Fixed: (AnimeBytes) Improve M2TS and ISO titles for BR-DISK detection 2025-01-12 19:01:14 +02:00
Weblate a5a86a6f86 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translation: Servarr/Prowlarr
2025-01-12 15:15:03 +02:00
Bogdan e7ed09a43d Bump version to 1.30.1 2025-01-12 15:14:09 +02:00
Bogdan 547bc2e58c New: (MyAnonamouse) Search by languages option
Fixes #2326
2025-01-10 22:36:11 +02:00
Weblate 8eb674c8d7 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Altair <villagermd@outlook.com>
Co-authored-by: Ano10 <Ano10@users.noreply.translate.servarr.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Matti Meikäläinen <diefor-93@hotmail.com>
Co-authored-by: Mickaël O <mickael.ouillon@ac-bordeaux.fr>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: marapavelka <mara.pavelka@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translation: Servarr/Prowlarr
2025-01-08 13:07:07 +02:00
Bogdan 2c3621d25e Improve error message on non-JSON responses for Nebulance 2025-01-07 04:07:54 +02:00
Bogdan 2648f2c639 Fixed: (BTN) Improve M2TS and ISO titles for BR-DISK detection 2025-01-06 13:30:01 +02:00
Bogdan f4d621063b Bump version to 1.30.0 2025-01-05 15:40:12 +02:00
Stevie Robinson 73494c462c Fixed: Listening on all IPv4 Addresses
(cherry picked from commit 035c474f10c257331a5f47e863d24af82537e335)
2025-01-05 14:27:33 +02:00
Bogdan 36f6896f30 Fixed: (PassThePopcorn) Increase rate limit 2025-01-02 23:20:39 +02:00
Bogdan e01741a69e New: (AnimeBytes) Use error message from response 2024-12-31 16:33:19 +02:00
Bogdan 1dbff1235e Match single digits only in season number regex for AnimeBytes 2024-12-31 16:26:05 +02:00
Bogdan 1a9ad6b363 Suggest adding IP to RPC whitelist for on failed Transmission auth
(cherry picked from commit f05e552e8e6dc02cd26444073ab9a678dcb36492)
2024-12-31 12:23:32 +02:00
Bogdan c88249300c Check if backup folder is writable on backup
(cherry picked from commit 8aad79fd3e14eb885724a5e5790803c289be2f25)
2024-12-31 12:23:09 +02:00
Qstick 7b8e352d87 Bump SonarCloud azure extension to 3.X 2024-12-30 22:49:24 -06:00
Bogdan 81f7a6cbab Word boundary in season number regex for AnimeBytes 2024-12-31 02:11:14 +02:00
Bogdan 523e46af2a Fixed: (AnimeBytes) Include year in release title for series with year in filenames 2024-12-31 01:55:55 +02:00
Bogdan 2b4a6def2a Fixed privacy level for Nebulance's API key 2024-12-30 00:59:48 +02:00
Bogdan 9097c0ef6d Bump version to 1.29.2 2024-12-30 00:59:35 +02:00
Bogdan 4321c1d40c Catch search engine related error messages for MyAnonaMouse 2024-12-28 23:42:14 +02:00
Mark McDowall bb2548a08d Don't send session information to Sentry
(cherry picked from commit fae24e98fb9230c2f3701caef457332952c6723f)
2024-12-28 15:22:41 +02:00
Weblate 3a9b841fad Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Tommy Au <smarttommyau@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: marapavelka <mara.pavelka@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_TW/
Translation: Servarr/Prowlarr
2024-12-27 22:55:30 +02:00
Bogdan 31203d1370 Add more links for info FlareSolverr and category 8000 2024-12-27 22:53:53 +02:00
Bogdan c8a910eaf4 Fixed: (RuTracker) Update categories
Co-authored-by: garfield69 <garfield69@outlook.com>
2024-12-27 22:53:53 +02:00
Bogdan 9ab3c3e6c7 Update how to get cookies info for Cardigann
Co-authored-by: garfield69 <garfield69@outlook.com>
2024-12-27 22:53:53 +02:00
Bogdan 4659cb706a Fixed: (Knaben) Update base url
Co-authored-by: garfield69 <garfield69@outlook.com>
2024-12-27 22:53:53 +02:00
Bogdan 500759bf1f Bump version to 1.29.1 2024-12-22 13:24:47 +02:00
Bogdan 43c7c43257 Bump Microsoft.Data.SqlClient to 2.1.7 2024-12-18 12:56:44 +02:00
Bogdan 9c2fced391 Bump System.Text.Json to 6.0.10 2024-12-18 02:34:29 +02:00
Bogdan 52ec5b6ff6 Bump MailKit to 4.8.0 2024-12-18 02:34:29 +02:00
zodihax b46e657976 Fixed: (NorBits) Searching UTF-8 characters with full search disabled (#2305)
Co-authored-by: zodihaxx <parity.umpires-0m@icloud.com>
2024-12-17 23:04:05 +02:00
Bogdan 51fd30ba10 Use message from error response for Gazelle indexers 2024-12-17 15:30:25 +02:00
Mark McDowall 5fbb347108 Upgrade typescript-eslint packages to 8.181.1
(cherry picked from commit ed10b63fa0c161cac7e0a2084e53785ab1798208)
2024-12-17 14:09:24 +02:00
Mark McDowall 54d3d44620 Upgrade Font Awesome to 6.7.1
(cherry picked from commit 016b5718386593c030f14fcac307c93ee1ceeca6)
2024-12-17 14:04:46 +02:00
Mark McDowall 5ca18683ca Upgrade babel to 7.26.0
(cherry picked from commit bfcd017012730c97eb587ae2d2e91f72ee7a1de3)
2024-12-17 13:59:56 +02:00
Bogdan 6bdf5f5d69 Use error message from Redacted response 2024-12-16 22:25:55 +02:00
Bogdan 7cba7152f1 Bump version to 1.29.0 2024-12-16 22:11:18 +02:00
Bogdan cf012eb001 Use minor version for core-js in babel/preset-env 2024-12-16 13:26:25 +02:00
Weblate 6b8a7993ff Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translation: Servarr/Prowlarr
2024-12-15 18:40:20 +02:00
Mark McDowall c6440bb21b Upgrade TypeScript and core-js
(cherry picked from commit 148480909917f69ff3b2ca547ccb4716dd56606e)
2024-12-15 15:37:10 +02:00
Mark McDowall b95eac98b9 Fixed: Error getting processes in some cases
(cherry picked from commit b552d4e9f7ca7388404aa0d52566010a54cb0244)
2024-12-15 15:37:10 +02:00
Bogdan 0eb19ce834 Bump version to 1.28.2 2024-12-15 10:05:45 +02:00
Weblate 4b8016d95d Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translation: Servarr/Prowlarr
2024-12-14 02:34:32 +02:00
Bogdan 31d8d2419a Fixed: Refresh backup list on deletion
Fixes #2300
2024-12-11 14:36:59 +02:00
Weblate d29ccd7749 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ardenet <1213193613@qq.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Co-authored-by: Robin Dadswell <robin@robindadswell.tech>
Co-authored-by: Rodion <rodyon009@gmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: farebyting <farelbyting@gmail.com>
Co-authored-by: hhjuhl <hans@kopula.dk>
Co-authored-by: keysuck <joshkkim@gmail.com>
Co-authored-by: mryx007 <mryx@mail.de>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_HANS/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_Hans/
Translation: Servarr/Prowlarr
2024-12-10 14:12:15 +02:00
Mark McDowall e789f4ec54 Sync TimeSpanConverter with upstream
(cherry picked from commit 1374240321f08d1400faf95e84217e4b7a2d116b)
2024-12-09 14:09:23 +02:00
Bogdan 58d495d618 Bump version to 1.28.1 2024-12-08 12:25:51 +02:00
Bogdan f3328863e1 Fixed: (M-Team) IMDb removed from releases response 2024-12-07 14:08:48 +02:00
Bogdan a23d792781 Fixed: Syncing Newznab indexers with expired VIP expiration dates to apps 2024-12-07 12:10:45 +02:00
Bogdan f066cf399d Fixed: Link to TMDb shows in search history
Fixes #2294
2024-12-07 10:37:29 +02:00
Servarr 61e863cb31 Automated API Docs update 2024-12-03 00:26:48 -06:00
soup b2afbc6872 New: Add config file setting for CGNAT authentication bypass
(cherry picked from commit 4c41a4f368046f73f82306bbd73bec992392938b)
2024-12-03 00:07:27 -06:00
Elias Benbourenane aace65f88e Allow GetFileSize to follow symlinks
(cherry picked from commit ca0bb14027f3409014e7cf9ffa8e04e577001d77)

Don't fail if symlink target can't be resolved

(cherry picked from commit 8cb58a63d8ec1b290bc57ad2cf1e90809ceebce9)
2024-12-02 03:18:30 +02:00
Bogdan 9ab2d8b444 Bump IPAddressRange, Npgsql and Polly 2024-12-02 03:14:36 +02:00
Mark McDowall bc314061ef Fixed: Prevent lack of internet from stopping all health checks from running
(cherry picked from commit dba3a8243988d3e9870b841696303191e1703a0d)
2024-12-02 03:10:32 +02:00
Mark McDowall 87b3dcd780 Support Postgres with non-standard version string
(cherry picked from commit 40f4ef27b22113c1dae0d0cbdee8205132bed68a)
2024-12-02 03:06:47 +02:00
Gylesie f3b99f68f6 Remove unnecessary heap allocations in local IP check
(cherry picked from commit ed536a85ad5f2062bf6f01f80efddb19fa935f63)
2024-12-02 03:05:29 +02:00
Mark McDowall c4a90e8ba4 Webpack web target
(cherry picked from commit a90866a73e6cff9a286c23e60c74672f4c0d317a)
2024-11-27 12:26:23 +02:00
Bogdan 41320ca2dc Bump version to 1.28.0 2024-11-26 19:27:15 +02:00
Bogdan b8b32f8708 Fixed: (ImmortalSeed) Update relogin check 2024-11-24 11:45:55 +02:00
Weblate 30c4bb24e8 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Mizuyoru_TW <mizuyoru.tw@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_TW/
Translation: Servarr/Prowlarr
2024-11-24 07:44:46 +02:00
Alexander Bruun b447db5d08 Fixed: (RED) Update indexer url (#2285)
* Updated RED CNAME record
* Added LegacyUrls
2024-11-23 22:41:21 -06:00
Weblate 299001a513 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: 4kwins <hanszimmerme@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-11-19 20:37:31 -06:00
Bogdan 2871f1f2a2 Bump version to 1.27.0 2024-11-19 03:11:37 +02:00
Bogdan a9b93df0c9 Pin ReportGenerator in Azure Pipelines for .NET 6
(cherry picked from commit 50ce480abf043140e209d2d2959fbea8dd5dd2ab)
2024-11-15 15:43:29 -06:00
Weblate 2726787ee9 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: My name is Svetoslav Kolev <slubchev@yahoo.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-11-14 20:56:24 -06:00
bakerboy448 b917932f19 Improve No Results Messaging 2024-11-14 19:30:12 -06:00
bakerboy448 06ae85e6d1 Fixed: Updates Page Translations 2024-11-12 21:14:38 -06:00
Weblate b1c7e98664 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Lars <lars.erik.heloe@gmail.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mytelegrambot <lacsonluxur@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translation: Servarr/Prowlarr
2024-11-08 13:45:13 +02:00
Bogdan 62479737a7 Fixed: (Torrent RSS) Clear old cookies on edit
Fixes #2275
2024-11-04 14:23:29 +02:00
Bogdan 8e69415d64 Check for disabled till value in filtering blocked providers 2024-11-03 18:16:39 +02:00
Bogdan 222dfb1821 Bump version to 1.26.1 2024-11-03 11:43:41 +02:00
Weblate 94f439e238 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Ardenet <1213193613@qq.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: HUi <huynguyeexn@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Kuzmich <kuzmich55@gmail.com>
Co-authored-by: Moon55 <dylan.gurdak@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-11-02 21:13:55 +02:00
Bogdan 903a88c121 Update timezone offset for FL 2024-11-01 17:56:47 +02:00
Bogdan 9690ab6883 Fixed: (IPTorrents) Search IMDb ID in descriptions 2024-11-01 17:19:28 +02:00
Bogdan 1e1a2b3b4a Fixed: (BeyondHD) Enforce length for API and RSS keys 2024-11-01 12:59:11 +02:00
bakerboy448 9dc2d3669c Fixed: NzbIndex removed, API not supported 2024-10-31 09:31:25 +02:00
Bogdan 511c76e219 Update JetBrains logos 2024-10-29 10:06:00 +02:00
Bogdan 78329b7b92 Improve exception message for invalid torrent files 2024-10-28 17:35:17 +02:00
Bogdan 4240048853 Add Knaben as native indexer 2024-10-28 08:23:42 +02:00
Bogdan 432af42ffd Fixed indexer names for no definitions check 2024-10-27 16:04:17 +02:00
Weblate 0d6c03f8d4 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ardenet <1213193613@qq.com>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-10-27 16:02:41 +02:00
Bogdan 96830f975e Cleaning paths for top level root folders
(cherry picked from commit a00121695715feb2cf8f04da246dc18262ab3237)
2024-10-27 15:12:00 +02:00
Mark McDowall 13c538ff58 Ignore extra spaces in path when not running on Windows
(cherry picked from commit 6d0f10b877912edef21232c64339cc6548d9690e)
2024-10-27 15:10:34 +02:00
Mark McDowall 14250e9634 Fixed getting parents from different OS paths
(cherry picked from commit e791f4b743d9660b0ad1decc4c5ed0e864f3b243)
2024-10-27 15:08:13 +02:00
Hadrien Patte e2f7890d76 Use OperatingSystem class to get OS information
(cherry picked from commit 135b5c2ddd8f0a274b0d59eb07f75aaf1446b9da)
2024-10-27 09:06:21 +02:00
Bogdan 257d38de66 Inherit trigger from pushed command models
(cherry picked from commit 0bc4903954b955fce0c368ef7fd2a6f3761d6a93)
2024-10-27 09:05:38 +02:00
Bogdan fd2a14e01b Fix settings fetching failure for updates 2024-10-27 09:01:07 +02:00
Bogdan b4d76c7138 Fixed: Initial state for qBittorrent v5.0
(cherry picked from commit ff724b7f4099284b8062f1625cf07b7822782edf)
2024-10-27 08:57:54 +02:00
Bogdan 9655f37fa8 Trim directory separators in GetRelativePath
(cherry picked from commit 240a0339bee7d407e564df6b6575a2ade6ac03cd)
2024-10-27 08:56:57 +02:00
Bogdan 246fb9b855 Update check returns error if build older than 180 days 2024-10-24 08:14:07 +03:00
Bogdan 25afadc9b2 Bump version to 1.26.0 2024-10-22 05:51:30 +03:00
Bogdan 3f547f0856 Cleanse exceptions in event logs 2024-10-20 13:39:43 +03:00
Bogdan 11e322b6d7 Bump version to 1.25.4 2024-10-20 08:05:32 +03:00
Weblate 02ff133a62 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Kuzmich55 <kuzmich55@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_TW/
Translation: Servarr/Prowlarr
2024-10-20 04:42:29 +03:00
Bogdan 47268aac87 Fix stable branch label in updates 2024-10-20 04:36:52 +03:00
Bogdan 8aad1ac554 New: Allow major version updates to be installed (#2260)
* New: Allow major version updates to be installed

(cherry picked from commit 0e95ba2021b23cc65bce0a0620dd48e355250dab)

* fixup! New: Allow major version updates to be installed

---------

Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2024-10-19 09:01:23 +03:00
Bogdan 9037cde439 Rename ApplicationCheckUpdate to ApplicationUpdateCheck 2024-10-19 07:13:31 +03:00
Mark McDowall 2afafd79e4 Fixed: Don't block updates under docker unless configured in package_info
(cherry picked from commit 5a7e34e291c2715aa67161e5c455d25e80f498df)
2024-10-19 07:13:31 +03:00
Bogdan f4fa2517d2 Sort indexers by name when syncing to applications 2024-10-18 23:12:57 +03:00
Stevie Robinson 37bc46c1cd Translate System pages
(cherry picked from commit 93e8ff0ac7610fa8739f2e577ece98c2c06c8881)
2024-10-18 11:44:20 +03:00
Weblate 3e3a7ed4f0 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: JoseFilipeFerreira <jose.filipe.matos.ferreira@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translation: Servarr/Prowlarr
2024-10-16 04:09:51 +03:00
Bogdan 04fa7d366d Fixed: (Cardigann) Redirect warnings with "Refresh" header 2024-10-13 20:08:54 +03:00
Bogdan ed9a3214a2 Fix redirect url in HttpClient development warning message 2024-10-13 19:56:32 +03:00
Bogdan 66a9e1a653 Bump dotnet to 6.0.35 2024-10-13 19:32:37 +03:00
Bogdan 8cb59c35fb New: Sync UI updates for providers 2024-10-13 07:23:10 +03:00
Bogdan 94e9c05d60 Natural sorting for tags list in the UI 2024-10-13 07:21:27 +03:00
Bogdan 8d2c4e1246 Bump version to 1.25.3 2024-10-13 07:20:52 +03:00
Bogdan c05be39346 Treat unauthorized newbie accounts in AvistaZ parser 2024-10-12 22:21:05 +03:00
Bogdan 951d42a591 Fix indexer url info 2024-10-12 05:30:03 +03:00
Bogdan dd046d8a68 Fixed: (Cardigann) Validate definition file and setting fields existence
Towards #2245
2024-10-11 19:23:30 +03:00
Bogdan efa54a4d51 Remove unused gulp packages 2024-10-10 19:19:59 +03:00
Bogdan 3f07c50cc5 Fixed: Copy to clipboard in non-secure contexts
(cherry picked from commit 3828e475cc8860e74cdfd8a70b4f886de7f9c5c3)
2024-10-10 19:19:59 +03:00
Treycos 94cf07ddb4 Convert ClipboardButton to TypeScript
(cherry picked from commit 99fc52039f44264c83d939e5f096d8e16d2f3355)
2024-10-10 19:19:59 +03:00
Bogdan 24063e06ab Convert FormInputButton to TypeScript
(cherry picked from commit 32fa63d24d08d8d8877386a8d2e7065ab5d0ad39)
2024-10-10 19:19:59 +03:00
Treycos e8ebb87189 Convert Label to TypeScript
(cherry picked from commit 3eca63a67c898256b711d37607f07cbabb9ed323)
2024-10-10 19:19:59 +03:00
Treycos 896e196767 Convert Button to TypeScript
(cherry picked from commit 63b4998c8e51d0d2b8b51133cbb1fd928394a7e6)
2024-10-10 19:19:59 +03:00
Bogdan 9f5be75e6d Link polymorphic static typing
(cherry picked from commit a2e06e9e650642518b926a61f624a2c7a49c0988)
(cherry picked from commit cfa2f4d4c6e35d7b9ddd2e1da2e59f7287859516)
2024-10-10 19:19:59 +03:00
Bogdan 9cc9e720bb Bump frontend packages 2024-10-10 19:19:59 +03:00
Bogdan a9c2cca66d Bump dotnet packages 2024-10-09 23:56:11 +03:00
Bogdan 9cc3646be5 Fixed: (Cardigann) Using variables in login paths 2024-10-09 00:50:40 +03:00
Bogdan d6bca449da Cleanse sharewood passkey 2024-10-09 00:26:08 +03:00
Bogdan cb5764c654 Log exceptions when getting indexer definitions
Closes #2245
2024-10-08 01:44:36 +03:00
Weblate 19a9b56fa4 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Ardenet <1213193613@qq.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Kuzmich55 <kuzmich55@gmail.com>
Co-authored-by: Mathias <mathias@rodilbach.dk>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: angelsky11 <angelsky11@gmail.com>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: jsain <josip.sain@gmail.com>
Co-authored-by: liuwqq <843384478@qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-10-06 18:19:32 +03:00
Tiago Santos a2b0f199f1 Fixed: (BeyondHD) Filter freeleech or limited releases when configured 2024-10-06 17:56:21 +03:00
Mark McDowall 59bfad7614 New: Use 307 redirect for requests missing URL Base 2024-10-06 17:48:02 +03:00
Bogdan aee3f2d12b Fixed: Handle 307 redirects from applications 2024-10-06 17:47:48 +03:00
Bogdan 11d58b4460 Bump macOS runner version to 13 2024-10-06 16:22:06 +03:00
Bogdan ee4de6c6ca Bump version to 1.25.2 2024-10-06 12:04:50 +03:00
Bogdan 8d16b88185 Return bad request for unprotect download link failures 2024-10-05 17:20:17 +03:00
Bogdan 121ef8e80d Add new category for FL 2024-09-30 17:26:31 +03:00
Bogdan d53fec7e75 Add newbie warning for AvistaZ's API use 2024-09-30 11:21:36 +03:00
Bogdan c017a3cd7e New: (PTP) Filter by Golden Popcorn only releases 2024-09-29 12:12:26 +03:00
Bogdan 27ea93090f Use proxied requests for fetching user class for MAM 2024-09-29 10:40:16 +03:00
Bogdan d79845144e Bump version to 1.25.1 2024-09-29 08:17:56 +03:00
Servarr 3f77900dd0 Automated API Docs update 2024-09-27 15:59:16 +03:00
Bogdan 4e8b9e81cf New: Option to prefer magnet URLs over torrent file links
Co-authored-by: Deathspike <meister.deathspike@outlook.com>

New: Bulk edit Prefer Magnet Url for indexers
2024-09-27 06:42:06 +03:00
Bogdan a32ab3acfd Fixed: (AnimeBytes) Avoid specials for non-zero season searches 2024-09-27 06:24:04 +03:00
Bogdan 942da3a5c0 Bump version to 1.25.0 2024-09-27 06:23:48 +03:00
Qstick 17e1a72baf Bump webpack to 5.94.0 and regenerate yarn.lock 2024-09-22 22:34:45 -05:00
Bogdan b454ded00a Bump version to 1.24.3 2024-09-22 07:48:53 +03:00
Servarr d4512393e2 Automated API Docs update 2024-09-21 22:05:08 +03:00
Bogdan 97d1384726 Guard against using invalid sort keys 2024-09-21 21:35:23 +03:00
Bogdan ba002a7a4a Add packages needed for RemoveDiacritics 2024-09-21 21:30:34 +03:00
momo 349efab7a8 Fix description for API key as query parameter
(cherry picked from commit 30c36fdc3baa686102ff124833c7963fc786f251)
2024-09-21 21:21:26 +03:00
Mark McDowall af9a6f42db Fixed: Unable to login when instance name contained brackets 2024-09-21 00:27:15 +03:00
Mark McDowall 6b20fa8abd New: Use instance name in forms authentication cookie name
Closes #2224
2024-09-16 16:47:22 +03:00
Bogdan 029ad3903f Bump version to 1.24.2 2024-09-15 15:56:33 +03:00
Weblate a23d66930b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: FloatStream <1213193613@qq.com>
Co-authored-by: Kuzmich55 <kuzmich55@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: shixiaotongy <shixiaotong2280@sina.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-09-14 17:14:52 +03:00
Bogdan 710ab7ae09 New: (Gazelle/OPS/RED) Prevent downloads without FL tokens 2024-09-08 15:19:25 +03:00
jaype87 434b07ae64 New: Sync seeding limits for LazyLibrarian (#2215)
* add support for seeders, seed_ratio and seed_duration for LazyLibrarian
2024-09-08 11:34:26 +03:00
Bogdan eee8c95ca6 Fix weblate widget 2024-09-08 11:24:36 +03:00
Bogdan 1f5c514011 Bump version to 1.24.1 2024-09-08 11:10:36 +03:00
Weblate 66d722e097 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Dream <seth.gecko.rr@gmail.com>
Co-authored-by: FloatStream <1213193613@qq.com>
Co-authored-by: Gabriel Markowski <gmarkowski62@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: Kerk en IT <info@kerkenit.nl>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Nota Inutilis <hugo@notainutilis.fr>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-09-07 13:43:28 -05:00
Bogdan 39befe5aa4 Use error message from Nebulance response
Fixes #2212
2024-09-06 10:41:26 +03:00
Bogdan ab043e87dc Display grabs, failures and queries stats with values 2024-09-04 16:28:06 +03:00
Bogdan 58ae9c0a13 Fixed: (MyAnonamouse) Avoid using FL wedges for freeleech torrents 2024-09-02 10:37:11 +03:00
Bogdan 44c446943c Fixed: (Gazelle) Allow freeleech torrents with Use Freeleech Tokens 2024-09-02 10:31:56 +03:00
Weblate 8301b669fe Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Dream <seth.gecko.rr@gmail.com>
Co-authored-by: Gabriel Markowski <gmarkowski62@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: Kerk en IT <info@kerkenit.nl>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translation: Servarr/Prowlarr
2024-09-01 21:21:40 -05:00
Bogdan 6fa0b79c67 Bump version to 1.24.0 2024-09-01 06:43:21 +03:00
Bogdan 32d23d6636 Simplify cookie clearing for MAM 2024-08-28 03:28:49 +03:00
Bogdan b31b695887 Fixed: Mapping of Cardigann indexers on bulk edit 2024-08-27 07:15:49 +03:00
Bogdan 33de32b138 Simplify app profile validation on indexers 2024-08-27 06:51:45 +03:00
Bogdan 753b53a529 Use UTC for filtering out AB releases 2024-08-27 06:09:35 +03:00
Bogdan 123535b9a5 Fixed: Use renewed mam_id from response to avoid invalid credentials after original one expires 2024-08-27 06:02:58 +03:00
Bogdan 7a5fa452f0 Don't persist value for SslCertHash when checking for existence 2024-08-27 00:27:34 +03:00
Bogdan 281e712542 Fixed: Hide reboot and shutdown UI buttons on docker
(cherry picked from commit 50d7e8fed4f9a43b501551f84471656f8bb19458)
2024-08-26 03:29:31 +03:00
Bogdan c2c34ecf53 New: Bypass IP addresses ranges in proxies
(cherry picked from commit 402db9128c214d4c5af6583643cb49d3aa7a28b5)

Closes #2203
2024-08-26 03:26:56 +03:00
bakerboy448 615193617c Fixed: Trim spaces and empty values in Proxy Bypass List
(cherry picked from commit 846333ddf0d9da775c80d004fdb9b41e700ef359)
2024-08-26 03:26:27 +03:00
Bogdan 1b58d50b6d Bump version to 1.23.1 2024-08-25 10:13:49 +03:00
Bogdan 99f9a0b4e6 Improve sorting indexer by status 2024-08-23 02:52:59 +03:00
Bogdan 696001a8bb Remove AroLol
Site has shutdown
2024-08-22 20:09:51 +03:00
Bogdan 31f057c097 Hiding "enable" property in API docs for applications 2024-08-20 17:28:11 +03:00
Bogdan 0391537a60 Don't display validation errors as HTML
Display the link to application only if it's enabled

Thanks to higa on discord for pointing this to us.
2024-08-20 17:10:24 +03:00
Servarr 521c1f760c Automated API Docs update 2024-08-20 05:26:16 +03:00
Bogdan 3bf9b4f90f Dedupe titles to avoid similar release names for AB 2024-08-20 05:16:35 +03:00
martylukyy af86a6d34e New: Configure log file size limit in UI
(cherry picked from commit 35baebaf7280749d5dfe5440e28b425e45a22d21)
2024-08-19 15:54:55 +03:00
Bogdan 3ecf5c6166 Fixed: (AnimeBytes) Improve filtering of old releases 2024-08-19 15:30:45 +03:00
Bogdan 4da3e7b2b3 Fixed: (MyAnonamouse) Sanitise search query and stop search if term is empty 2024-08-19 01:08:15 +03:00
Bogdan 66f38f1566 Bump version to 1.23.0 2024-08-18 15:52:58 +03:00
Weblate 04b513ad14 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-08-18 04:59:35 +03:00
Bogdan 1ce7fda8bb Fixed: Removing invalid statuses on provider deletion 2024-08-17 18:11:43 +03:00
Bogdan 6d09fad675 Bump babel packages 2024-08-16 18:38:54 +03:00
Bogdan ad061e7ece Fix select background appearance on iOS
And make use of autoprefixer
2024-08-16 18:38:53 +03:00
Bogdan 3155343bcc Fixed: (Uniotaku) Updated categories
Co-authored-by: Garfield69 <garfield69@outlook.com>
2024-08-16 15:03:24 +03:00
Bogdan f5e91f7bfd Fixed: (RuTracker) Updated categories
Co-authored-by: Garfield69 <garfield69@outlook.com>
2024-08-16 15:01:55 +03:00
Bogdan 1d69f2ed3f Fixed: (GazelleGames) Fixed release titles 2024-08-16 14:41:45 +03:00
Mark McDowall 1d233dbcab New: Configurable log file size limit
(cherry picked from commit 813965e6a20edef2772d68eaa7646af33028425a)
2024-08-15 04:02:33 +03:00
Mark McDowall 1aafb0b201 New: Add Compact Log Event Format option for console logging
(cherry picked from commit 0d914f4c53876540ed2df83ad3d71615c013856f)
2024-08-15 04:00:23 +03:00
Bogdan d7d5a2dd42 Upgrade nlog to 5.3.3 2024-08-15 03:57:21 +03:00
Bogdan 8060a65ef6 Fixed: Duplicated changelog lines 2024-08-15 03:51:36 +03:00
Bogdan 379071f838 Convert formatBytes to TypeScript 2024-08-15 03:49:37 +03:00
Mark McDowall 5cbbd060a4 Update React Lint rules for TSX
(cherry picked from commit 1299a97579bec52ee3d16ab8d05c9e22edd80330)
2024-08-15 03:31:29 +03:00
Mark McDowall ef19673a76 Convert System to TypeScript
(cherry picked from commit 72db8099e0f4abc3176e397f8dda3b2b69026daf)
2024-08-15 03:31:29 +03:00
The Dark c3cf8a6ebb Convert App to TypeScript
(cherry picked from commit d6d90a64a39d3b9d3a95fb6b265517693a70fdd7)
(cherry picked from commit 428569106499b5e3a463f1990ae2996d1ae4ab49)
(cherry picked from commit d0e9504af0d88391a74e04b90638e4b2d99fb476)
(cherry picked from commit ee80564dd427ca1dc14c192955efaa61f386ad44)
(cherry picked from commit 76650af9fdc7ef06d13ce252986d21574903d293)
2024-08-15 03:31:29 +03:00
Bogdan c22b27525a Include available version in update health check
(cherry picked from commit 15e3c3efb18242caf28b9bfc77a72a78296018bf)
2024-08-15 03:31:29 +03:00
Mark McDowall eec3b01f5b Don't hash files in development builds
(cherry picked from commit bc7799139e52b92956eb595fb87f44d7dda9a320)
2024-08-15 03:31:29 +03:00
Mark McDowall e67a127a02 Fixed: Allow leading/trailing spaces on non-Windows
(cherry picked from commit 9127a91dfc460f442498a00faed98737047098cd)
2024-08-15 03:31:29 +03:00
Mark McDowall a074ebc951 New: Default file log level changed to debug
(cherry picked from commit 9b528eb82914a05cfc3b67d4d6146ce51e86f68d)
2024-08-15 03:31:29 +03:00
Weblate d1cd814663 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ano10 <arnaudthommeray+github@ik.me>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: iMohmmedSA <i.mohmmed.i+1@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translation: Servarr/Prowlarr
2024-08-15 03:30:44 +03:00
Bogdan ac76646a20 Fixed: Fallback to saved capabilities when syncing failed indexers 2024-08-15 03:29:45 +03:00
Bogdan 6549f799f6 Fix parsing imdb ids for native indexers 2024-08-15 03:29:18 +03:00
Bogdan cca55fd66c Bump version to 1.22.0 2024-07-27 00:57:57 +03:00
Weblate 2f67d2813a Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: seidnerj <jonathan.seidner@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_TW/
Translation: Servarr/Prowlarr
2024-07-27 00:19:19 +03:00
Bogdan 9a7a5fdc38 Remove PropTypes 2024-07-26 06:40:34 +03:00
Bogdan f1fdec6822 Convert Add Indexer Modal to Typescript 2024-07-26 06:25:37 +03:00
Bogdan 5464b23329 Sort indexer queries stats by a sum of all 3 types 2024-07-26 01:09:04 +03:00
Bogdan 4c99971882 Improve messaging on no results with applied filter 2024-07-25 08:08:48 +03:00
Weblate cc7769b601 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Dream <seth.gecko.rr@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-07-24 19:42:16 +03:00
Bogdan cb2ed7daf9 Fixed: Improve elapsed time collecting for grabs 2024-07-22 19:52:12 +03:00
Bogdan 78508094c8 Bump some frontend libraries 2024-07-22 01:02:25 +03:00
Bogdan b0f755a30c Fixed: (Nebulance) Searching for daily episodes using ids 2024-07-22 00:38:13 +03:00
Bogdan 9d1384792a Bump version to 1.21.2 2024-07-21 18:06:41 +03:00
Bogdan ea17116998 Fixed: (Nebulance) Avoid requests for release calls that are 2 characters or fewer 2024-07-21 02:39:02 +03:00
Servarr 2c23681fc5 Automated API Docs update 2024-07-21 01:53:11 +03:00
Bogdan 17aa2832ea New: Split average response time statistics for queries and grabs 2024-07-21 01:01:03 +03:00
Bogdan 5f3a329ef2 Don't show null for non-cached indexer queries 2024-07-20 20:36:01 +03:00
Bogdan 96f49da79e New: Improve history details for release grabs 2024-07-20 19:50:20 +03:00
Bogdan c7dfde0ce9 Improve messaging for invalid request for M-Team-TP 2024-07-19 19:49:17 +03:00
Bogdan 8cf32020f7 New: Bump dotnet to 6.0.32 2024-07-19 19:39:06 +03:00
Weblate a5ed5a0e60 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Dream <seth.gecko.rr@gmail.com>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Rauniik <raunerjakub@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_TW/
Translation: Servarr/Prowlarr
2024-07-19 00:05:13 +03:00
Bogdan 3279936fc9 New: Litestream compatibility for SQLite (#2179) 2024-07-18 23:33:55 +03:00
Bogdan 8abccc709e Use natural sorting for remaining lists of items in the UI 2024-07-18 22:49:43 +03:00
Mark McDowall 76f30e7682 New: Use natural sorting for lists of items in the UI
(cherry picked from commit 1a1c8e6c08a6db5fcd2b5d17e65fa1f943d2e746)
2024-07-18 21:35:06 +03:00
Mark McDowall ab289b3e42 New: Show update settings on all platforms
(cherry picked from commit c023fc700896c7f0751c4ac63c4e1a89d6e1a9bb)
2024-07-18 21:22:01 +03:00
Bogdan ef7e04065c Fixed: (BeyondHD) Don't die on invalid TMDb ids 2024-07-17 02:36:58 +03:00
Bogdan d1084039b3 Bump version to 1.21.1 2024-07-14 12:29:09 +03:00
Bogdan 7bada440d2 Log invalid torrent files contents as debug
Fixes #2169
2024-07-12 13:00:23 +03:00
Bogdan 803c4752db Fixed: Sending health restored notifications with Gotify
Fixed #2176
2024-07-11 13:35:02 +03:00
Bogdan c0777474c0 Bump Polly 2024-07-09 23:47:23 +03:00
Weblate 66dcea5604 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Serhii Matrunchyk <serhii@digitalidea.studio>
Co-authored-by: Taylan Tatlı <taylantatli90@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: quek76 <quek@libertysurf.fr>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_TW/
Translation: Servarr/Prowlarr
2024-07-09 11:06:17 +03:00
Qstick a2a12d2450 Update SonarCloud pipeline versions (#2171)
* Update SonarCloud pipeline versions

* Update reportgenerator to remove PublishCodeCoverage dep warnings
2024-07-07 17:55:24 +03:00
Bogdan 39593bd5a8 Bump version to 1.21.0 2024-07-07 10:44:00 +03:00
Bogdan 45d8a8a4e6 Minor fixes and cover link for SubsPlease 2024-07-06 22:12:36 +03:00
Bogdan a4546c77ce Avoid invalid requests for Nebulance 2024-07-06 11:33:21 +03:00
Bogdan d69bf6360a Fixed: (Nebulance) Improve searching by release names 2024-07-06 09:21:55 +03:00
Bogdan da9ce5b5c3 New: Enable "Sync Anime Standard Format Search" by default for new Sonarr apps 2024-07-05 22:26:34 +03:00
Bogdan e092098101 Minor improvements to season parsing from titles for AnimeBytes 2024-07-05 16:39:04 +03:00
Bogdan 1a89a79b74 Avoid NullRef for missing filelist and tags fields 2024-07-05 16:13:32 +03:00
Bogdan cb6bf49922 New: (Nebulance) Improvements for season and episode searching 2024-07-05 12:42:51 +03:00
Bogdan 4bcaba0be0 Fixed: Trimming disabled logs database
(cherry picked from commit d5dff8e8d6301b661a713702e1c476705423fc4f)
2024-07-01 05:41:37 +03:00
Bogdan 220ef723c7 Bump version to 1.20.1 2024-06-30 07:22:49 +03:00
Bogdan 9c599a6be4 New: (UI) Indexer privacy label
Fixes #2132
2024-06-28 05:43:09 +03:00
Bogdan 715ce1fc6c Refresh indexers list and status on page change 2024-06-28 04:57:24 +03:00
Bogdan 8c3a192dd0 Fixed: Ignore auth events from queries and grab stats 2024-06-28 04:56:18 +03:00
Bogdan d22bf93dfd Fixed: Searches with season/episodes should not be treated as ID searches 2024-06-27 08:06:26 +03:00
Bogdan 886054fdf8 Bump indexers definition version to 11 2024-06-27 04:35:27 +03:00
Bogdan 4188510586 New: (Cardigann) Add info_category_8000 2024-06-27 04:35:27 +03:00
Bogdan fedebca5e1 New: (Cardigann) Optional login selectorinputs and getselectorinputs 2024-06-27 04:35:27 +03:00
Bogdan e2ce6437e9 Bump mac image to 12 2024-06-26 23:52:41 +03:00
Mark McDowall bdae60bac9 Improvements to EnhancedSelectInput
(cherry picked from commit 4c622fd41289cd293a68a6a9f6b8da2a086edecb)
2024-06-26 04:47:25 +03:00
Bogdan 2d6c818aec Fixed: Exclude invalid releases from Newznab and Torznab parsers 2024-06-26 03:47:08 +03:00
Bogdan a1d19852dc Switch TorrentsCSV to STJson 2024-06-21 02:25:21 +03:00
Bogdan 104c95f28f Bump version to 1.20.0 2024-06-20 19:03:57 +03:00
Bogdan 55fa1ec637 Small improvements to IndexerNoDefinitionCheck 2024-06-20 17:40:54 +03:00
Weblate b27a3d8272 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ano10 <arnaudthommeray+github@ik.me>
Co-authored-by: Mariot Tsitoara <mariot@tsitoara.fr>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translation: Servarr/Prowlarr
2024-06-20 17:39:11 +03:00
Bogdan 089d450b46 Fixed: (M-Team-TP) New API path
Co-authored-by: Garfield69 <garfield69@outlook.com>
2024-06-20 16:57:54 +03:00
dependabot[bot] 358ac7434d Bump ws from 7.5.9 to 7.5.10
Bumps [ws](https://github.com/websockets/ws) from 7.5.9 to 7.5.10.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.5.9...7.5.10)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-19 20:47:47 +03:00
dependabot[bot] 9cd505fd8a Bump braces from 3.0.2 to 3.0.3
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-18 22:56:14 +03:00
Bogdan 20ac2687df New: Ignore inaccessible folders when getting folders
(cherry picked from commit a30e9da7672a202cb9e9188cf106afc34a5d0361)
2024-06-18 22:45:12 +03:00
Weblate 9f075c09a2 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Felix <edivad94@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-06-16 16:24:03 +03:00
Bogdan 3793538ba4 Use tooltip component for detailed error message 2024-06-15 23:27:04 +03:00
Bogdan 4c4b16d234 Fixed: (FileList) Parsing poorly padded IMDb Ids 2024-06-14 22:10:09 +03:00
Bogdan f5790bec2e HD-Space switched to Cardigann YML 2024-06-13 12:26:52 +03:00
Bogdan 6c0d08de56 Fixed: Ignore case for name validation in providers
(cherry picked from commit 0edc5ba99a15c5f80305b387a053f35fc3f6e51b)
2024-06-11 07:49:17 +03:00
Mark McDowall ba344756b1 Fixed: Improve error messaging if config file isn't formatted correctly
(cherry picked from commit 52b72925f9d42c896144dde3099dc19c397327b0)
2024-06-11 07:48:15 +03:00
Servarr dfda86aca3 Automated API Docs update 2024-06-10 17:54:04 +03:00
Bogdan df6f83ed69 Increase timeout for docs 2024-06-10 17:40:27 +03:00
Bogdan 218d92a1ac docs: use application specific to platform 2024-06-10 17:21:57 +03:00
Bogdan df2b529d01 Bump Swashbuckle to 6.6.2 2024-06-10 17:00:46 +03:00
Bogdan 0ef42dbb4d Display downtime message for Nebulance 2024-06-09 14:27:27 +03:00
Weblate 1a428197b2 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dani Talens <databio@gmail.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Yi Cao <caoyi06@qq.com>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: r0bertreh <Robert.reh@live.de>
Co-authored-by: topnew <sznetim@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-06-03 09:14:00 +03:00
Bogdan 09d7983845 Bump version to 1.19.0 2024-06-02 05:33:28 +03:00
Bogdan 6e01f3187a New: (UI) Detailed error message for inner exception in indexers validation 2024-06-01 13:47:23 +03:00
Bogdan 468436b9f7 Fixed: Remove extraneous rate limiting for grabs
Co-authored-by: Michael Goodnow <mmgoodnow@gmail.com>

Closes #2140
2024-06-01 10:37:30 +03:00
Bogdan 76c288a6e4 Fixed: Authentication issues with Cardigann definitions having captcha
This mostly reverts 68b895d2ad where the cache key was changed to something more specific to avoid another issue with shared settings, but sadly this resulted in a new instance of CardigannRequestGenerator with null `landingResultDocument` failing the login.

Fixes #2139
2024-06-01 08:07:47 +03:00
Bogdan f95f67a7ca New: (Cardigann) Bump minimum version to v10 2024-05-27 21:05:14 +03:00
Bogdan 11864247eb Bump Microsoft.NET.Test.Sdk and Polly 2024-05-25 02:31:44 +03:00
Bogdan 74509ea7c9 Fixed: (MyAnonamouse) Don't die when no results on paginated queries 2024-05-19 01:24:10 +03:00
Bogdan 948fe0a6dc Fixed: Trimming slashes from UrlBase when using environment variable 2024-05-18 19:12:37 +03:00
Bogdan a4257cbcde Bump Npgsql to 7.0.7 2024-05-13 15:33:46 +03:00
Bogdan 2929c3c898 Bump version to 1.18.0 2024-05-12 16:23:24 +03:00
Weblate 2c5f2187c8 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dani Talens <databio@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Michael5564445 <michaelvelosk@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translation: Servarr/Prowlarr
2024-05-10 14:05:29 +03:00
Bogdan 401ef88971 Refactor PasswordInput to use type password 2024-05-10 13:59:52 +03:00
Bogdan 4fb3754048 Fixed: Text color for inputs on login page 2024-05-09 23:40:50 +03:00
Mark McDowall 596efe8fb0 New: Dark theme for login screen
(cherry picked from commit cae134ec7b331d1c906343716472f3d043614b2c)
2024-05-09 23:40:49 +03:00
Bogdan 076a4f2574 Fix class name for AppIndexerMapRepository 2024-05-09 23:15:05 +03:00
Servarr 9561371a47 Automated API Docs update 2024-05-08 03:20:28 +03:00
Mark McDowall 16254cf5f9 New: Option to select download client when multiple of the same type are configured
(cherry picked from commit 07f0fbf9a51d54e44681fd0f74df4e048bff561a)
2024-05-08 03:14:17 +03:00
Jared 649a03e5a0 New: Config file setting to disable log database (#2123)
Co-authored-by: sillock1 <jprest97@gmail.com>
2024-05-07 19:52:02 +03:00
Bogdan dd21d9b521 Fixed: Allow decimals for Seed Ratio 2024-05-07 00:11:20 +03:00
Bogdan 68b895d2ad Fixed: Don't share settings for same cached definition in CardigannRequestGenerator 2024-05-06 18:22:54 +03:00
Weblate 634016ae1b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Michael5564445 <michaelvelosk@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translation: Servarr/Prowlarr
2024-05-05 13:12:04 +03:00
Mark McDowall 83c6751847 Forward X-Forwarded-Host header
(cherry picked from commit 3fbe4361386e9fb8dafdf82ad9f00f02bec746cc)
2024-05-05 12:29:22 +03:00
Jared 04bb0c51b1 New: Optionally use Environment Variables for settings in config.xml
(cherry picked from commit d051dac12c8b797761a0d1f3b4aa84cff47ed13d)
2024-05-05 11:39:55 +03:00
Bogdan d2e9621de9 Bump version to 1.17.2 2024-05-05 11:38:40 +03:00
Bogdan cb673ddc42 New: Host column in history and more info 2024-05-02 22:35:20 +03:00
Bogdan 440618f2b6 Fixed: Initialize databases after app folder migrations
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2024-05-02 00:21:01 +03:00
Bruno Garcia ae79d45664 Update Sentry SDK add features
Co-authored-by: Stefan Jandl <reg@bitfox.at>
(cherry picked from commit 6377c688fc7b35749d608bf62796446bb5bcb11b)
2024-05-02 00:07:58 +03:00
Bogdan 1877ccb513 Update Pull Request Labeler config for v5 2024-04-29 14:35:43 +03:00
Bogdan b3098f2e4c Use newer Node.js task for in pipelines 2024-04-29 14:32:46 +03:00
Bogdan 3e0af062c1 Parameter binding for API requests 2024-04-29 01:24:57 +03:00
Bogdan 858f85c50d Fix translations for proxy validation 2024-04-28 23:49:59 +03:00
Uruk 938848be65 (ci): update action version 2024-04-28 11:42:07 -05:00
Bogdan 615f5899cc Fixed: (TorrentDay) Update base urls and MST
Co-authored-by: garfield69 <garfield69@outlook.com>
2024-04-28 14:57:30 +03:00
Mark McDowall 5a6b1313e8 Validate that folders in paths don't start or end with a space
(cherry picked from commit 316b5cbf75b45ef9a25f96ce1f2fbed25ad94296)
2024-04-28 13:16:08 +03:00
Mark McDowall ab7debb34b Improve paths longer than 256 on Windows failing to hardlink
(cherry picked from commit a97fbcc40a6247bf59678425cf460588fd4dbecd)
2024-04-28 13:07:52 +03:00
Bogdan eee21de795 Fixed: Handle download redirects to magnet links 2024-04-28 13:05:13 +03:00
Bogdan 15fabbe7d0 Bump version to 1.17.1 2024-04-28 12:50:04 +03:00
Weblate 6aef48c6e7 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: maodun96 <435795439@qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2024-04-27 21:15:01 +03:00
663 changed files with 17801 additions and 10769 deletions
+2 -2
View File
@@ -2,11 +2,11 @@
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet // README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{ {
"name": "Prowlarr", "name": "Prowlarr",
"image": "mcr.microsoft.com/devcontainers/dotnet:1-6.0", "image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0",
"features": { "features": {
"ghcr.io/devcontainers/features/node:1": { "ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true, "nodeGypDependencies": true,
"version": "16", "version": "20",
"nvmVersion": "latest" "nvmVersion": "latest"
} }
}, },
+10 -3
View File
@@ -4,11 +4,18 @@ labels: ['Type: Bug', 'Status: Needs Triage']
body: body:
- type: checkboxes - type: checkboxes
attributes: attributes:
label: Is there an existing issue for this? label: I attest that there is not an existing issue for this?
description: Please search to see if an open or closed issue already exists for the bug you encountered. If a bug exists and is closed note that it may only be fixed in an unstable branch. description: Please search to see if an open or closed issue already exists for the bug you encountered. If a bug exists and is closed note that it may only be fixed in an unstable branch.
options: options:
- label: I have searched the existing open and closed issues - label: I have searched the existing open and closed issues
required: true required: true
- type: checkboxes
attributes:
label: I attest this is not related to a Cardigann YML Indexer.
description: Please search to see if this is for a tracker [that is yml-based (Cardigann)](https://github.com/Prowlarr/indexers) these are synced to Prowlarr/Indexers from Jackett/Jackett.
options:
- label: I confirm this is not related to a Cardigann YML Indexer
required: true
- type: textarea - type: textarea
attributes: attributes:
label: Current Behavior label: Current Behavior
@@ -73,8 +80,8 @@ body:
required: true required: true
- type: checkboxes - type: checkboxes
attributes: attributes:
label: Trace Logs have been provided as applicable. Reports may be closed if the required logs are not provided. label: I attest that Trace Logs have been provided as applicable. Reports will be closed if the required logs are not provided.
description: Trace logs are generally required for all bug reports and contain `trace`. Info logs are invalid for bug reports and do not contain `debug` nor `trace` description: Trace logs are generally required for all bug reports and contain `trace`. Info logs are invalid for bug reports and do not contain `debug` nor `trace`
options: options:
- label: I have read and followed the steps in the wiki link above and provided the required trace logs - the logs contain `trace` - that are relevant and show this issue. - label: I attest that I have read and followed the steps in the wiki link above and provided the required trace logs - the logs contain `trace` - that are relevant and show this issue.
required: true required: true
+20 -8
View File
@@ -1,19 +1,31 @@
'Area: API': 'Area: API':
- src/Prowlarr.Api.V1/**/* - changed-files:
- any-glob-to-any-file:
- src/Prowlarr.Api.V1/**/*
'Area: Db-migration': 'Area: Db-migration':
- src/NzbDrone.Core/Datastore/Migration/* - changed-files:
- any-glob-to-any-file:
- src/NzbDrone.Core/Datastore/Migration/*
'Area: Download Clients': 'Area: Download Clients':
- src/NzbDrone.Core/Download/Clients/**/* - changed-files:
- any-glob-to-any-file:
- src/NzbDrone.Core/Download/Clients/**/*
'Area: Indexer': 'Area: Indexer':
- src/NzbDrone.Core/Indexers/**/* - changed-files:
- any-glob-to-any-file:
- src/NzbDrone.Core/Indexers/**/*
'Area: Notifications': 'Area: Notifications':
- src/NzbDrone.Core/Notifications/**/* - changed-files:
- any-glob-to-any-file:
- src/NzbDrone.Core/Notifications/**/*
'Area: UI': 'Area: UI':
- frontend/**/* - changed-files:
- package.json - any-glob-to-any-file:
- yarn.lock - frontend/**/*
- package.json
- yarn.lock
+1 -1
View File
@@ -9,4 +9,4 @@ jobs:
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/labeler@v4 - uses: actions/labeler@v5
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
lock: lock:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: dessant/lock-threads@v4 - uses: dessant/lock-threads@v5
with: with:
github-token: ${{ github.token }} github-token: ${{ github.token }}
issue-inactive-days: '90' issue-inactive-days: '90'
+1 -1
View File
@@ -10,7 +10,7 @@
"request": "launch", "request": "launch",
"preLaunchTask": "build dotnet", "preLaunchTask": "build dotnet",
// If you have changed target frameworks, make sure to update the program path. // If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/_output/net6.0/Prowlarr", "program": "${workspaceFolder}/_output/net8.0/Prowlarr",
"args": [], "args": [],
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
-33
View File
@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="70px" height="70px" viewBox="0 0 70 70" style="enable-background:new 0 0 70 70;" xml:space="preserve">
<g>
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-1.3318" y1="43.7371" x2="67.0419" y2="26.0967">
<stop offset="0.1237" style="stop-color:#7866FF"/>
<stop offset="0.5376" style="stop-color:#FE2EB6"/>
<stop offset="0.8548" style="stop-color:#FD0486"/>
</linearGradient>
<polygon style="fill:url(#SVGID_1_);" points="67.3,16 43.7,0 0,31.1 11.1,70 58.9,60.3 "/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="45.9148" y1="38.9098" x2="67.6577" y2="9.0989">
<stop offset="0.1237" style="stop-color:#FF0080"/>
<stop offset="0.2587" style="stop-color:#FE0385"/>
<stop offset="0.4109" style="stop-color:#FA0C92"/>
<stop offset="0.5713" style="stop-color:#F41BA9"/>
<stop offset="0.7363" style="stop-color:#EB2FC8"/>
<stop offset="0.8656" style="stop-color:#E343E6"/>
</linearGradient>
<polygon style="fill:url(#SVGID_2_);" points="67.3,16 43.7,0 38,15.7 38,47.8 70,47.8 "/>
</g>
<g>
<rect x="13.4" y="13.4" style="fill:#000000;" width="43.2" height="43.2"/>
<rect x="17.4" y="48.5" style="fill:#FFFFFF;" width="16.2" height="2.7"/>
<g>
<path style="fill:#FFFFFF;" d="M17.4,19.1h6.9c5.6,0,9.5,3.8,9.5,8.9V28c0,5-3.9,8.9-9.5,8.9h-6.9V19.1z M21.4,22.7v10.7h3
c3.2,0,5.4-2.2,5.4-5.3V28c0-3.2-2.2-5.4-5.4-5.4H21.4z"/>
<polygon style="fill:#FFFFFF;" points="40.3,22.7 34.9,22.7 34.9,19.1 49.6,19.1 49.6,22.7 44.2,22.7 44.2,37 40.3,37 "/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

-66
View File
@@ -1,66 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="120.1px" height="130.2px" viewBox="0 0 120.1 130.2" style="enable-background:new 0 0 120.1 130.2;" xml:space="preserve"
>
<g>
<linearGradient id="XMLID_2_" gradientUnits="userSpaceOnUse" x1="31.8412" y1="120.5578" x2="110.2402" y2="73.24">
<stop offset="0" style="stop-color:#FCEE39"/>
<stop offset="1" style="stop-color:#F37B3D"/>
</linearGradient>
<path id="XMLID_3041_" style="fill:url(#XMLID_2_);" d="M118.6,71.8c0.9-0.8,1.4-1.9,1.5-3.2c0.1-2.6-1.8-4.7-4.4-4.9
c-1.2-0.1-2.4,0.4-3.3,1.1l0,0l-83.8,45.9c-1.9,0.8-3.6,2.2-4.7,4.1c-2.9,4.8-1.3,11,3.6,13.9c3.4,2,7.5,1.8,10.7-0.2l0,0l0,0
c0.2-0.2,0.5-0.3,0.7-0.5l78-54.8C117.3,72.9,118.4,72.1,118.6,71.8L118.6,71.8L118.6,71.8z"/>
<linearGradient id="XMLID_3_" gradientUnits="userSpaceOnUse" x1="48.3607" y1="6.9083" x2="119.9179" y2="69.5546">
<stop offset="0" style="stop-color:#EF5A6B"/>
<stop offset="0.57" style="stop-color:#F26F4E"/>
<stop offset="1" style="stop-color:#F37B3D"/>
</linearGradient>
<path id="XMLID_3049_" style="fill:url(#XMLID_3_);" d="M118.8,65.1L118.8,65.1L55,2.5C53.6,1,51.6,0,49.3,0
c-4.3,0-7.7,3.5-7.7,7.7v0c0,2.1,0.8,3.9,2.1,5.3l0,0l0,0c0.4,0.4,0.8,0.7,1.2,1l67.4,57.7l0,0c0.8,0.7,1.8,1.2,3,1.3
c2.6,0.1,4.7-1.8,4.9-4.4C120.2,67.3,119.7,66,118.8,65.1z"/>
<linearGradient id="XMLID_4_" gradientUnits="userSpaceOnUse" x1="52.9467" y1="63.6407" x2="10.5379" y2="37.1562">
<stop offset="0" style="stop-color:#7C59A4"/>
<stop offset="0.3852" style="stop-color:#AF4C92"/>
<stop offset="0.7654" style="stop-color:#DC4183"/>
<stop offset="0.957" style="stop-color:#ED3D7D"/>
</linearGradient>
<path id="XMLID_3042_" style="fill:url(#XMLID_4_);" d="M57.1,59.5C57,59.5,17.7,28.5,16.9,28l0,0l0,0c-0.6-0.3-1.2-0.6-1.8-0.9
c-5.8-2.2-12.2,0.8-14.4,6.6c-1.9,5.1,0.2,10.7,4.6,13.4l0,0l0,0C6,47.5,6.6,47.8,7.3,48c0.4,0.2,45.4,18.8,45.4,18.8l0,0
c1.8,0.8,3.9,0.3,5.1-1.2C59.3,63.7,59,61,57.1,59.5z"/>
<linearGradient id="XMLID_5_" gradientUnits="userSpaceOnUse" x1="52.1736" y1="3.7019" x2="10.7706" y2="37.8971">
<stop offset="0" style="stop-color:#EF5A6B"/>
<stop offset="0.364" style="stop-color:#EE4E72"/>
<stop offset="1" style="stop-color:#ED3D7D"/>
</linearGradient>
<path id="XMLID_3057_" style="fill:url(#XMLID_5_);" d="M49.3,0c-1.7,0-3.3,0.6-4.6,1.5L4.9,28.3c-0.1,0.1-0.2,0.1-0.2,0.2l-0.1,0
l0,0c-1.7,1.2-3.1,3-3.9,5.1C-1.5,39.4,1.5,45.9,7.3,48c3.6,1.4,7.5,0.7,10.4-1.4l0,0l0,0c0.7-0.5,1.3-1,1.8-1.6l34.6-31.2l0,0
c1.8-1.4,3-3.6,3-6.1v0C57.1,3.5,53.6,0,49.3,0z"/>
<g id="XMLID_3008_">
<rect id="XMLID_3033_" x="34.6" y="37.4" style="fill:#000000;" width="51" height="51"/>
<rect id="XMLID_3032_" x="39" y="78.8" style="fill:#FFFFFF;" width="19.1" height="3.2"/>
<g id="XMLID_3009_">
<path id="XMLID_3030_" style="fill:#FFFFFF;" d="M38.8,50.8l1.5-1.4c0.4,0.5,0.8,0.8,1.3,0.8c0.6,0,0.9-0.4,0.9-1.2l0-5.3l2.3,0
l0,5.3c0,1-0.3,1.8-0.8,2.3c-0.5,0.5-1.3,0.8-2.3,0.8C40.2,52.2,39.4,51.6,38.8,50.8z"/>
<path id="XMLID_3028_" style="fill:#FFFFFF;" d="M45.3,43.8l6.7,0v1.9l-4.4,0V47l4,0l0,1.8l-4,0l0,1.3l4.5,0l0,2l-6.7,0
L45.3,43.8z"/>
<path id="XMLID_3026_" style="fill:#FFFFFF;" d="M55,45.8l-2.5,0l0-2l7.3,0l0,2l-2.5,0l0,6.3l-2.3,0L55,45.8z"/>
<path id="XMLID_3022_" style="fill:#FFFFFF;" d="M39,54l4.3,0c1,0,1.8,0.3,2.3,0.7c0.3,0.3,0.5,0.8,0.5,1.4v0
c0,1-0.5,1.5-1.3,1.9c1,0.3,1.6,0.9,1.6,2v0c0,1.4-1.2,2.3-3.1,2.3l-4.3,0L39,54z M43.8,56.6c0-0.5-0.4-0.7-1-0.7l-1.5,0l0,1.5
l1.4,0C43.4,57.3,43.8,57.1,43.8,56.6L43.8,56.6z M43,59l-1.8,0l0,1.5H43c0.7,0,1.1-0.3,1.1-0.8v0C44.1,59.2,43.7,59,43,59z"/>
<path id="XMLID_3019_" style="fill:#FFFFFF;" d="M46.8,54l3.9,0c1.3,0,2.1,0.3,2.7,0.9c0.5,0.5,0.7,1.1,0.7,1.9v0
c0,1.3-0.7,2.1-1.7,2.6l2,2.9l-2.6,0l-1.7-2.5h-1l0,2.5l-2.3,0L46.8,54z M50.6,58c0.8,0,1.2-0.4,1.2-1v0c0-0.7-0.5-1-1.2-1
l-1.5,0v2H50.6z"/>
<path id="XMLID_3016_" style="fill:#FFFFFF;" d="M56.8,54l2.2,0l3.5,8.4l-2.5,0l-0.6-1.5l-3.2,0l-0.6,1.5l-2.4,0L56.8,54z
M58.8,59l-0.9-2.3L57,59L58.8,59z"/>
<path id="XMLID_3014_" style="fill:#FFFFFF;" d="M62.8,54l2.3,0l0,8.3l-2.3,0L62.8,54z"/>
<path id="XMLID_3012_" style="fill:#FFFFFF;" d="M65.7,54l2.1,0l3.4,4.4l0-4.4l2.3,0l0,8.3l-2,0L68,57.8l0,4.6l-2.3,0L65.7,54z"
/>
<path id="XMLID_3010_" style="fill:#FFFFFF;" d="M73.7,61.1l1.3-1.5c0.8,0.7,1.7,1,2.7,1c0.6,0,1-0.2,1-0.6v0
c0-0.4-0.3-0.5-1.4-0.8c-1.8-0.4-3.1-0.9-3.1-2.6v0c0-1.5,1.2-2.7,3.2-2.7c1.4,0,2.5,0.4,3.4,1.1l-1.2,1.6
c-0.8-0.5-1.6-0.8-2.3-0.8c-0.6,0-0.8,0.2-0.8,0.5v0c0,0.4,0.3,0.5,1.4,0.8c1.9,0.4,3.1,1,3.1,2.6v0c0,1.7-1.3,2.7-3.4,2.7
C76.1,62.5,74.7,62,73.7,61.1z"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

-50
View File
@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="70px" height="70px" viewBox="0 0 70 70" style="enable-background:new 0 0 70 70;" xml:space="preserve">
<g>
<g>
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="22.9451" y1="75.7869" x2="74.7868" y2="20.6415">
<stop offset="1.612903e-002" style="stop-color:#B35BA3"/>
<stop offset="0.4044" style="stop-color:#C41E57"/>
<stop offset="0.4677" style="stop-color:#C41E57"/>
<stop offset="0.6505" style="stop-color:#EB8523"/>
<stop offset="0.9516" style="stop-color:#FEBD11"/>
</linearGradient>
<polygon style="fill:url(#SVGID_1_);" points="49.8,15.2 36,36.7 58.4,70 70,23.1 "/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="17.7187" y1="73.2922" x2="69.5556" y2="18.1519">
<stop offset="1.612903e-002" style="stop-color:#B35BA3"/>
<stop offset="0.4044" style="stop-color:#C41E57"/>
<stop offset="0.4677" style="stop-color:#C41E57"/>
<stop offset="0.7043" style="stop-color:#EB8523"/>
</linearGradient>
<polygon style="fill:url(#SVGID_2_);" points="51.1,15.7 49,0 18.8,33.6 27.6,42.3 20.8,70 58.4,70 "/>
</g>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="1.8281" y1="53.4275" x2="48.8245" y2="9.2255">
<stop offset="1.612903e-002" style="stop-color:#B35BA3"/>
<stop offset="0.6613" style="stop-color:#C41E57"/>
</linearGradient>
<polygon style="fill:url(#SVGID_3_);" points="49,0 11.6,0 0,47.1 55.6,47.1 "/>
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="49.8935" y1="-11.5569" x2="48.8588" y2="24.0352">
<stop offset="0.5" style="stop-color:#C41E57"/>
<stop offset="0.6668" style="stop-color:#D13F48"/>
<stop offset="0.7952" style="stop-color:#D94F39"/>
<stop offset="0.8656" style="stop-color:#DD5433"/>
</linearGradient>
<polygon style="fill:url(#SVGID_4_);" points="55.3,47.1 51.1,15.7 49,0 41.7,23 "/>
</g>
<g>
<rect x="13.4" y="13.5" transform="matrix(-1 2.577289e-003 -2.577289e-003 -1 70.0288 70.081)" style="fill:#000000;" width="43.2" height="43.2"/>
<rect x="17.6" y="48.6" transform="matrix(1 -2.577289e-003 2.577289e-003 1 -0.1287 6.634109e-002)" style="fill:#FFFFFF;" width="16.2" height="2.7"/>
<path style="fill:#FFFFFF;" d="M17.4,19.1l8.2,0c2.3,0,4,0.6,5.2,1.8c1,1,1.5,2.4,1.5,4.1l0,0.1c0,1.5-0.3,2.6-1.1,3.5
c-0.7,0.9-1.6,1.6-2.8,2l4.4,6.4l-4.6,0l-3.7-5.5l-3.3,0l0,5.5l-3.9,0L17.4,19.1z M25.3,27.8c1,0,1.7-0.2,2.2-0.7
c0.5-0.5,0.8-1.1,0.8-1.8l0-0.1c0-0.9-0.3-1.5-0.8-1.9c-0.5-0.4-1.3-0.6-2.3-0.6l-3.9,0l0,5.1L25.3,27.8z"/>
<path style="fill:#FFFFFF;" d="M36,33.2l-1.9,0l0-3.3l2.5,0l0.6-3.8l-2.3,0l0-3.3l2.8,0l0.6-3.7l3.4,0l-0.6,3.7l3.7,0l0.6-3.7
l3.4,0l-0.6,3.7l1.9,0l0,3.3l-2.5,0L47,29.9l2.3,0l0,3.3l-2.8,0L45.8,37l-3.4,0l0.7-3.8l-3.7,0L38.7,37l-3.4,0L36,33.2z
M43.7,29.9l0.6-3.8l-3.7,0L40,29.9L43.7,29.9z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

-42
View File
@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="70px" height="70px" viewBox="0 0 70 70" style="enable-background:new 0 0 70 70;" xml:space="preserve">
<defs>
<linearGradient id="linear-gradient" x1="70.22612" y1="27.79912" x2="-5.13024" y2="63.12242" gradientTransform="matrix(1, 0, 0, -1, 0, 71.27997)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#c90f5e"/>
<stop offset="0.22111" stop-color="#c90f5e"/>
<stop offset="0.2356" stop-color="#c90f5e"/>
<stop offset="0.35559" stop-color="#ca135c"/>
<stop offset="0.46633" stop-color="#ce1e57"/>
<stop offset="0.5735" stop-color="#d4314e"/>
<stop offset="0.67844" stop-color="#dc4b41"/>
<stop offset="0.78179" stop-color="#e66d31"/>
<stop offset="0.88253" stop-color="#f3961d"/>
<stop offset="0.94241" stop-color="#fcb20f"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="24.65904" y1="61.99608" x2="46.04762" y2="2.93445" gradientTransform="matrix(1, 0, 0, -1, 0, 71.27997)" gradientUnits="userSpaceOnUse">
<stop offset="0.04188" stop-color="#077cfb"/>
<stop offset="0.44503" stop-color="#c90f5e"/>
<stop offset="0.95812" stop-color="#077cfb"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="17.39552" y1="63.34592" x2="33.19389" y2="7.20092" gradientTransform="matrix(1, 0, 0, -1, 0, 71.27997)" gradientUnits="userSpaceOnUse">
<stop offset="0.27749" stop-color="#c90f5e"/>
<stop offset="0.97382" stop-color="#fcb20f"/>
</linearGradient>
</defs>
<title>rider</title>
<g>
<polygon points="70 27.237 63.391 23.75 20.926 0 3.827 17.921 21.619 41.068 60.537 44.397 70 27.237" fill="url(#linear-gradient)"/>
<polygon points="50.423 16.132 44.271 1.107 27.643 17.471 11.768 50.194 49.411 70 70 57.98 50.423 16.132" fill="url(#linear-gradient-2)"/>
<polygon points="20.926 0 0 14.095 7.779 62.172 27.848 69.889 53.78 48.823 20.926 0" fill="url(#linear-gradient-3)"/>
</g>
<g>
<rect x="13.30219" y="13.19311" width="43.61371" height="43.61371"/>
<g>
<path d="M17.22741,18.86293h8.39564a7.38416,7.38416,0,0,1,5.34268,1.85358,5.86989,5.86989,0,0,1,1.52648,4.1433h0A5.74339,5.74339,0,0,1,28.567,30.5296l4.47041,6.54206H28.34891L24.42368,31.1838h-3.162v5.88785H17.22741V18.86293h0ZM25.296,27.69471c1.96262,0,3.053-1.09034,3.053-2.61682h0c0-1.74455-1.19938-2.61682-3.162-2.61682H21.15265v5.23365H25.296Z" fill="#fff"/>
<path d="M36.09034,18.86293H43.2866c5.77882,0,9.70405,3.92523,9.70405,9.15888h0c0,5.12461-3.92523,9.15888-9.70405,9.15888H36.09034V18.86293Zm4.03427,3.59813V33.47352h3.162a5.23727,5.23727,0,0,0,5.56075-5.45171h0a5.26493,5.26493,0,0,0-5.56075-5.56075h-3.162Z" fill="#fff"/>
</g>
<rect x="17.22741" y="48.62925" width="16.35514" height="2.72586" fill="#fff"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

-36
View File
@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="70px" height="70px" viewBox="0 0 70 70" style="enable-background:new 0 0 70 70;" xml:space="preserve">
<g>
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="25.0676" y1="1.4599" x2="43.1829" y2="66.675">
<stop offset="0.2849" style="stop-color:#00CDD7"/>
<stop offset="0.9409" style="stop-color:#2086D7"/>
</linearGradient>
<polygon style="fill:url(#SVGID_1_);" points="9.4,63.3 0,7.3 17.5,0.1 28.6,6.7 38.8,1.2 60.1,9.4 48.1,70 "/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="30.7199" y1="9.7343" x2="61.365" y2="54.6713">
<stop offset="0.1398" style="stop-color:#FFF045"/>
<stop offset="0.3656" style="stop-color:#00CDD7"/>
</linearGradient>
<polygon style="fill:url(#SVGID_2_);" points="70,23.7 61,1.4 44.6,0 19.3,24.3 26.1,55.6 38.8,64.6 70,46 62.3,31.7 "/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="61.0819" y1="15.2899" x2="65.1065" y2="29.5436">
<stop offset="0.2849" style="stop-color:#00CDD7"/>
<stop offset="0.9409" style="stop-color:#2086D7"/>
</linearGradient>
<polygon style="fill:url(#SVGID_3_);" points="56,20.4 62.3,31.7 70,23.7 64.4,9.8 "/>
</g>
<g>
<g>
<rect x="13.4" y="13.4" style="fill:#000000;" width="43.2" height="43.2"/>
<rect x="17.5" y="48.5" style="fill:#FFFFFF;" width="16.2" height="2.7"/>
<path style="fill:#FFFFFF;" d="M38.7,34.3l2.3-2.8c1.6,1.3,3.3,2.2,5.3,2.2c1.6,0,2.5-0.6,2.5-1.7v-0.1c0-1-0.6-1.5-3.6-2.3
c-3.6-0.9-5.8-1.9-5.8-5.5v-0.1c0-3.3,2.6-5.4,6.2-5.4c2.6,0,4.8,0.8,6.6,2.3l-2,3c-1.6-1.1-3.1-1.8-4.6-1.8
c-1.5,0-2.3,0.7-2.3,1.6v0.1c0,1.2,0.8,1.6,3.8,2.4c3.6,1,5.6,2.3,5.6,5.4v0.1c0,3.6-2.7,5.6-6.5,5.6
C43.5,37.2,40.8,36.2,38.7,34.3"/>
</g>
<polygon style="fill:#FFFFFF;" points="35.2,19 32.5,29.4 29.5,19 26.5,19 23.4,29.4 20.7,19 16.6,19 21.7,36.9 25,36.9 28,26.5
30.9,36.9 34.3,36.9 39.4,19 "/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

+7 -7
View File
@@ -1,7 +1,7 @@
# Prowlarr # Prowlarr
[![Build Status](https://dev.azure.com/Prowlarr/Prowlarr/_apis/build/status/Prowlarr.Prowlarr?branchName=develop)](https://dev.azure.com/Prowlarr/Prowlarr/_build/latest?definitionId=1&branchName=develop) [![Build Status](https://dev.azure.com/Prowlarr/Prowlarr/_apis/build/status/Prowlarr.Prowlarr?branchName=develop)](https://dev.azure.com/Prowlarr/Prowlarr/_build/latest?definitionId=1&branchName=develop)
[![Translated](https://translate.servarr.com/widgets/servarr/-/prowlarr/svg-badge.svg)](https://translate.servarr.com/engage/prowlarr/?utm_source=widget) [![Translation status](https://translate.servarr.com/widget/servarr/prowlarr/svg-badge.svg)](https://translate.servarr.com/engage/servarr/?utm_source=widget)
[![Docker Pulls](https://img.shields.io/docker/pulls/hotio/prowlarr.svg)](https://wiki.servarr.com/prowlarr/installation/docker) [![Docker Pulls](https://img.shields.io/docker/pulls/hotio/prowlarr.svg)](https://wiki.servarr.com/prowlarr/installation/docker)
![Github Downloads](https://img.shields.io/github/downloads/Prowlarr/Prowlarr/total.svg) ![Github Downloads](https://img.shields.io/github/downloads/Prowlarr/Prowlarr/total.svg)
[![Backers on Open Collective](https://opencollective.com/Prowlarr/backers/badge.svg)](#backers) [![Backers on Open Collective](https://opencollective.com/Prowlarr/backers/badge.svg)](#backers)
@@ -68,16 +68,16 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
## JetBrains ## JetBrains
Thank you to [<img src="/Logo/jetbrains.svg" alt="JetBrains" width="32"> JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools. Thank you to [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.png" alt="JetBrains" width="96">](http://www.jetbrains.com/) for providing us with free licenses to their great tools.
- [<img src="/Logo/resharper.svg" alt="ReSharper" width="32"> ReSharper](http://www.jetbrains.com/resharper/) * [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/ReSharper_icon.png" alt="ReSharper" width="32"> ReSharper](http://www.jetbrains.com/resharper/)
- [<img src="/Logo/webstorm.svg" alt="WebStorm" width="32"> WebStorm](http://www.jetbrains.com/webstorm/) * [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/WebStorm_icon.png" alt="WebStorm" width="32"> WebStorm](http://www.jetbrains.com/webstorm/)
- [<img src="/Logo/rider.svg" alt="Rider" width="32"> Rider](http://www.jetbrains.com/rider/) * [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/Rider_icon.png" alt="Rider" width="32"> Rider](http://www.jetbrains.com/rider/)
- [<img src="/Logo/dottrace.svg" alt="dotTrace" width="32"> dotTrace](http://www.jetbrains.com/dottrace/) * [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/dotTrace_icon.png" alt="dotTrace" width="32"> dotTrace](http://www.jetbrains.com/dottrace/)
### License ### License
- [GNU GPL v3](http://www.gnu.org/licenses/gpl.html) - [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
- Copyright 2010-2022 - Copyright 2010-2025
Icon Credit - [Box vector created by freepik - www.freepik.com](https://www.freepik.com/vectors/box) Icon Credit - [Box vector created by freepik - www.freepik.com](https://www.freepik.com/vectors/box)
+65 -93
View File
@@ -9,18 +9,18 @@ variables:
testsFolder: './_tests' testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '1.17.0' majorVersion: '2.3.0'
minorVersion: $[counter('minorVersion', 1)] minorVersion: $[counter('minorVersion', 1)]
prowlarrVersion: '$(majorVersion).$(minorVersion)' prowlarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)'
sentryOrg: 'servarr' sentryOrg: 'servarr'
sentryUrl: 'https://sentry.servarr.com' sentryUrl: 'https://sentry.servarr.com'
dotnetVersion: '6.0.421' dotnetVersion: '8.0.405'
nodeVersion: '20.X' nodeVersion: '20.X'
innoVersion: '6.2.2' innoVersion: '6.2.2'
windowsImage: 'windows-2022' windowsImage: 'windows-2022'
linuxImage: 'ubuntu-20.04' linuxImage: 'ubuntu-22.04'
macImage: 'macOS-11' macImage: 'macOS-13'
trigger: trigger:
branches: branches:
@@ -106,7 +106,7 @@ stages:
echo "Extra platforms already enabled" echo "Extra platforms already enabled"
else else
echo "Enabling extra platform support" echo "Enabling extra platform support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64/' "$BUNDLEDVERSIONS"
fi fi
displayName: Enable Extra Platform Support displayName: Enable Extra Platform Support
- bash: ./build.sh --backend --enable-extra-platforms - bash: ./build.sh --backend --enable-extra-platforms
@@ -122,27 +122,23 @@ stages:
artifact: '$(osName)Backend' artifact: '$(osName)Backend'
displayName: Publish Backend displayName: Publish Backend
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/win-x64/publish' - publish: '$(testsFolder)/net8.0/win-x64/publish'
artifact: win-x64-tests artifact: win-x64-tests
displayName: Publish win-x64 Test Package displayName: Publish win-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-x64/publish' - publish: '$(testsFolder)/net8.0/linux-x64/publish'
artifact: linux-x64-tests artifact: linux-x64-tests
displayName: Publish linux-x64 Test Package displayName: Publish linux-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-x86/publish' - publish: '$(testsFolder)/net8.0/linux-musl-x64/publish'
artifact: linux-x86-tests
displayName: Publish linux-x86 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-musl-x64/publish'
artifact: linux-musl-x64-tests artifact: linux-musl-x64-tests
displayName: Publish linux-musl-x64 Test Package displayName: Publish linux-musl-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/freebsd-x64/publish' - publish: '$(testsFolder)/net8.0/freebsd-x64/publish'
artifact: freebsd-x64-tests artifact: freebsd-x64-tests
displayName: Publish freebsd-x64 Test Package displayName: Publish freebsd-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/osx-x64/publish' - publish: '$(testsFolder)/net8.0/osx-x64/publish'
artifact: osx-x64-tests artifact: osx-x64-tests
displayName: Publish osx-x64 Test Package displayName: Publish osx-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
@@ -166,10 +162,10 @@ stages:
pool: pool:
vmImage: $(imageName) vmImage: $(imageName)
steps: steps:
- task: NodeTool@0 - task: UseNode@1
displayName: Set Node.js version displayName: Set Node.js version
inputs: inputs:
versionSpec: $(nodeVersion) version: $(nodeVersion)
- checkout: self - checkout: self
submodules: true submodules: true
fetchDepth: 1 fetchDepth: 1
@@ -189,7 +185,7 @@ stages:
artifact: '$(osName)Frontend' artifact: '$(osName)Frontend'
displayName: Publish Frontend displayName: Publish Frontend
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- stage: Installer - stage: Installer
dependsOn: dependsOn:
- Build_Backend - Build_Backend
@@ -259,21 +255,21 @@ stages:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x64.zip' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x64.zip'
archiveType: 'zip' archiveType: 'zip'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/win-x64/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create win-x86 zip displayName: Create win-x86 zip
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x86.zip' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x86.zip'
archiveType: 'zip' archiveType: 'zip'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x86/net6.0 rootFolderOrFile: $(artifactsFolder)/win-x86/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create osx-x64 app displayName: Create osx-x64 app
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-x64.zip' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-x64.zip'
archiveType: 'zip' archiveType: 'zip'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net6.0 rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create osx-x64 tar displayName: Create osx-x64 tar
inputs: inputs:
@@ -281,14 +277,14 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/osx-x64/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create osx-arm64 app displayName: Create osx-arm64 app
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-arm64.zip' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-arm64.zip'
archiveType: 'zip' archiveType: 'zip'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net6.0 rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create osx-arm64 tar displayName: Create osx-arm64 tar
inputs: inputs:
@@ -296,7 +292,7 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net6.0 rootFolderOrFile: $(artifactsFolder)/osx-arm64/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-x64 tar displayName: Create linux-x64 tar
inputs: inputs:
@@ -304,7 +300,7 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-x64/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-musl-x64 tar displayName: Create linux-musl-x64 tar
inputs: inputs:
@@ -312,15 +308,7 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-x86 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-core-x86.tar.gz'
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x86/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-arm tar displayName: Create linux-arm tar
inputs: inputs:
@@ -328,7 +316,7 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-arm/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-musl-arm tar displayName: Create linux-musl-arm tar
inputs: inputs:
@@ -336,7 +324,7 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-arm64 tar displayName: Create linux-arm64 tar
inputs: inputs:
@@ -344,7 +332,7 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-arm64/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-musl-arm64 tar displayName: Create linux-musl-arm64 tar
inputs: inputs:
@@ -352,7 +340,7 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net8.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create freebsd-x64 tar displayName: Create freebsd-x64 tar
inputs: inputs:
@@ -360,7 +348,7 @@ stages:
archiveType: 'tar' archiveType: 'tar'
tarCompression: 'gz' tarCompression: 'gz'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/freebsd-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/freebsd-x64/net8.0
- publish: $(Build.ArtifactStagingDirectory) - publish: $(Build.ArtifactStagingDirectory)
artifact: 'Packages' artifact: 'Packages'
displayName: Publish Packages displayName: Publish Packages
@@ -391,7 +379,7 @@ stages:
SENTRY_AUTH_TOKEN: $(sentryAuthTokenServarr) SENTRY_AUTH_TOKEN: $(sentryAuthTokenServarr)
SENTRY_ORG: $(sentryOrg) SENTRY_ORG: $(sentryOrg)
SENTRY_URL: $(sentryUrl) SENTRY_URL: $(sentryUrl)
- stage: Unit_Test - stage: Unit_Test
displayName: Unit Tests displayName: Unit Tests
dependsOn: Build_Backend dependsOn: Build_Backend
@@ -476,6 +464,7 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Unit Tests' testRunTitle: '$(testName) Unit Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: ne(variables['testName'], 'freebsd-x64')
- job: Unit_Docker - job: Unit_Docker
displayName: Unit Docker displayName: Unit Docker
@@ -487,29 +476,19 @@ stages:
testName: 'Musl Net Core' testName: 'Musl Net Core'
artifactName: linux-musl-x64-tests artifactName: linux-musl-x64-tests
containerImage: ghcr.io/servarr/testimages:alpine containerImage: ghcr.io/servarr/testimages:alpine
linux-x86:
testName: 'linux-x86'
artifactName: linux-x86-tests
containerImage: ghcr.io/servarr/testimages:linux-x86
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: ${{ variables.linuxImage }}
container: $[ variables['containerImage'] ] container: $[ variables['containerImage'] ]
timeoutInMinutes: 10 timeoutInMinutes: 10
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .NET' displayName: 'Install .NET'
inputs: inputs:
version: $(dotnetVersion) version: $(dotnetVersion)
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
- bash: |
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
displayName: 'Install .NET'
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
- checkout: none - checkout: none
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
displayName: Download Test Artifact displayName: Download Test Artifact
@@ -532,7 +511,8 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Unit Tests' testRunTitle: '$(testName) Unit Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
- job: Unit_LinuxCore_Postgres14 - job: Unit_LinuxCore_Postgres14
displayName: Unit Native LinuxCore with Postgres14 Database displayName: Unit Native LinuxCore with Postgres14 Database
dependsOn: Prepare dependsOn: Prepare
@@ -549,7 +529,7 @@ stages:
vmImage: ${{ variables.linuxImage }} vmImage: ${{ variables.linuxImage }}
timeoutInMinutes: 10 timeoutInMinutes: 10
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .net core' displayName: 'Install .net core'
@@ -585,6 +565,7 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: 'LinuxCore Postgres14 Unit Tests' testRunTitle: 'LinuxCore Postgres14 Unit Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
- job: Unit_LinuxCore_Postgres15 - job: Unit_LinuxCore_Postgres15
displayName: Unit Native LinuxCore with Postgres15 Database displayName: Unit Native LinuxCore with Postgres15 Database
@@ -597,12 +578,12 @@ stages:
Prowlarr__Postgres__Port: '5432' Prowlarr__Postgres__Port: '5432'
Prowlarr__Postgres__User: 'prowlarr' Prowlarr__Postgres__User: 'prowlarr'
Prowlarr__Postgres__Password: 'prowlarr' Prowlarr__Postgres__Password: 'prowlarr'
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: ${{ variables.linuxImage }}
timeoutInMinutes: 10 timeoutInMinutes: 10
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .net core' displayName: 'Install .net core'
@@ -638,6 +619,7 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: 'LinuxCore Postgres15 Unit Tests' testRunTitle: 'LinuxCore Postgres15 Unit Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
- stage: Integration - stage: Integration
displayName: Integration displayName: Integration
@@ -681,7 +663,7 @@ stages:
pool: pool:
vmImage: $(imageName) vmImage: $(imageName)
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .net core' displayName: 'Install .net core'
@@ -703,7 +685,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory) targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1 - task: ExtractFiles@1
inputs: inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)' archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin' destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package displayName: Extract Package
- bash: | - bash: |
@@ -720,6 +702,7 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Integration Tests' testRunTitle: '$(testName) Integration Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
displayName: Publish Test Results displayName: Publish Test Results
- job: Integration_LinuxCore_Postgres14 - job: Integration_LinuxCore_Postgres14
@@ -757,7 +740,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory) targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1 - task: ExtractFiles@1
inputs: inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)' archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin' destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package displayName: Extract Package
- bash: | - bash: |
@@ -782,6 +765,7 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: 'Integration LinuxCore Postgres14 Database Integration Tests' testRunTitle: 'Integration LinuxCore Postgres14 Database Integration Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
displayName: Publish Test Results displayName: Publish Test Results
@@ -820,7 +804,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory) targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1 - task: ExtractFiles@1
inputs: inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)' archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin' destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package displayName: Extract Package
- bash: | - bash: |
@@ -845,6 +829,7 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: 'Integration LinuxCore Postgres15 Database Integration Tests' testRunTitle: 'Integration LinuxCore Postgres15 Database Integration Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
displayName: Publish Test Results displayName: Publish Test Results
- job: Integration_FreeBSD - job: Integration_FreeBSD
@@ -891,6 +876,7 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: 'FreeBSD Integration Tests' testRunTitle: 'FreeBSD Integration Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: false
displayName: Publish Test Results displayName: Publish Test Results
- job: Integration_Docker - job: Integration_Docker
@@ -904,29 +890,18 @@ stages:
artifactName: linux-musl-x64-tests artifactName: linux-musl-x64-tests
containerImage: ghcr.io/servarr/testimages:alpine containerImage: ghcr.io/servarr/testimages:alpine
pattern: 'Prowlarr.*.linux-musl-core-x64.tar.gz' pattern: 'Prowlarr.*.linux-musl-core-x64.tar.gz'
linux-x86:
testName: 'linux-x86'
artifactName: linux-x86-tests
containerImage: ghcr.io/servarr/testimages:linux-x86
pattern: 'Prowlarr.*.linux-core-x86.tar.gz'
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: ${{ variables.linuxImage }}
container: $[ variables['containerImage'] ] container: $[ variables['containerImage'] ]
timeoutInMinutes: 15 timeoutInMinutes: 15
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .NET' displayName: 'Install .NET'
inputs: inputs:
version: $(dotnetVersion) version: $(dotnetVersion)
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
- bash: |
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
displayName: 'Install .NET'
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
- checkout: none - checkout: none
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
displayName: Download Test Artifact displayName: Download Test Artifact
@@ -943,7 +918,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory) targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1 - task: ExtractFiles@1
inputs: inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)' archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin' destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package displayName: Extract Package
- bash: | - bash: |
@@ -960,12 +935,13 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Integration Tests' testRunTitle: '$(testName) Integration Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
displayName: Publish Test Results displayName: Publish Test Results
- stage: Automation - stage: Automation
displayName: Automation displayName: Automation
dependsOn: Packages dependsOn: Packages
jobs: jobs:
- job: Automation - job: Automation
strategy: strategy:
@@ -991,7 +967,7 @@ stages:
pool: pool:
vmImage: $(imageName) vmImage: $(imageName)
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .net core' displayName: 'Install .net core'
@@ -1013,7 +989,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory) targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1 - task: ExtractFiles@1
inputs: inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)' archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin' destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package displayName: Extract Package
- bash: | - bash: |
@@ -1041,6 +1017,7 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(osName) Automation Tests' testRunTitle: '$(osName) Automation Tests'
failTaskOnFailedTests: $(failBuild) failTaskOnFailedTests: $(failBuild)
failTaskOnMissingResultsFile: $(failBuild)
displayName: Publish Test Results displayName: Publish Test Results
- stage: Analyze - stage: Analyze
@@ -1075,10 +1052,10 @@ stages:
pool: pool:
vmImage: $(imageName) vmImage: $(imageName)
steps: steps:
- task: NodeTool@0 - task: UseNode@1
displayName: Set Node.js version displayName: Set Node.js version
inputs: inputs:
versionSpec: $(nodeVersion) version: $(nodeVersion)
- checkout: self - checkout: self
submodules: true submodules: true
fetchDepth: 1 fetchDepth: 1
@@ -1116,7 +1093,7 @@ stages:
- checkout: self - checkout: self
submodules: true submodules: true
persistCredentials: true persistCredentials: true
fetchDepth: 1 fetchDepth: 1
- bash: ./docs.sh Windows - bash: ./docs.sh Windows
displayName: Create openapi.json displayName: Create openapi.json
- bash: | - bash: |
@@ -1169,39 +1146,35 @@ stages:
submodules: true submodules: true
- powershell: Set-Service SCardSvr -StartupType Manual - powershell: Set-Service SCardSvr -StartupType Manual
displayName: Enable Windows Test Service displayName: Enable Windows Test Service
- task: SonarCloudPrepare@1 - task: SonarCloudPrepare@3
condition: eq(variables['System.PullRequest.IsFork'], 'False') condition: eq(variables['System.PullRequest.IsFork'], 'False')
inputs: inputs:
SonarCloud: 'SonarCloud' SonarCloud: 'SonarCloud'
organization: 'prowlarr' organization: 'prowlarr'
scannerMode: 'MSBuild' scannerMode: 'dotnet'
projectKey: 'Prowlarr_Prowlarr' projectKey: 'Prowlarr_Prowlarr'
projectName: 'Prowlarr' projectName: 'Prowlarr'
projectVersion: '$(prowlarrVersion)' projectVersion: '$(prowlarrVersion)'
extraProperties: | extraProperties: |
sonar.exclusions=**/obj/**,**/*.dll,**/NzbDrone.Core.Test/Files/**/*,./frontend/**,**/ExternalModules/**,./src/Libraries/** sonar.exclusions=**/obj/**,**/*.dll,**/NzbDrone.Core.Test/Files/**/*,./frontend/**,**/ExternalModules/**,./src/Libraries/**
sonar.coverage.exclusions=**/Prowlarr.Api.V1/**/* sonar.coverage.exclusions=**/Prowlarr.Api.V1/**/*
sonar.cs.opencover.reportsPaths=$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml sonar.cs.cobertura.reportsPaths=$(Build.SourcesDirectory)/CoverageResults/**/coverage.cobertura.xml
sonar.cs.nunit.reportsPaths=$(Build.SourcesDirectory)/TestResult.xml sonar.cs.nunit.reportsPaths=$(Build.SourcesDirectory)/TestResult.xml
- bash: | - bash: |
./build.sh --backend -f net6.0 -r win-x64 ./build.sh --backend -f net8.0 -r win-x64
TEST_DIR=_tests/net6.0/win-x64/publish/ ./test.sh Windows Unit Coverage TEST_DIR=_tests/net8.0/win-x64/publish/ ./test.sh Windows Unit Coverage
displayName: Coverage Unit Tests displayName: Coverage Unit Tests
- task: SonarCloudAnalyze@1 - task: SonarCloudAnalyze@3
condition: eq(variables['System.PullRequest.IsFork'], 'False') condition: eq(variables['System.PullRequest.IsFork'], 'False')
displayName: Publish SonarCloud Results displayName: Publish SonarCloud Results
- task: reportgenerator@4 - task: reportgenerator@5
displayName: Generate Coverage Report displayName: Generate Coverage Report
inputs: inputs:
reports: '$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml' reports: '$(Build.SourcesDirectory)/CoverageResults/**/coverage.cobertura.xml'
targetdir: '$(Build.SourcesDirectory)/CoverageResults/combined' targetdir: '$(Build.SourcesDirectory)/CoverageResults/combined'
reporttypes: 'HtmlInline_AzurePipelines;Cobertura;Badges' reporttypes: 'HtmlInline_AzurePipelines;Cobertura;Badges'
- task: PublishCodeCoverageResults@1 publishCodeCoverageResults: true
displayName: Publish Coverage Report sourcedirs: src
inputs:
codeCoverageTool: 'cobertura'
summaryFileLocation: './CoverageResults/combined/Cobertura.xml'
reportDirectory: './CoverageResults/combined/'
- stage: Report_Out - stage: Report_Out
dependsOn: dependsOn:
@@ -1233,4 +1206,3 @@ stages:
DISCORDCHANNELID: $(discordChannelId) DISCORDCHANNELID: $(discordChannelId)
DISCORDWEBHOOKKEY: $(discordWebhookKey) DISCORDWEBHOOKKEY: $(discordWebhookKey)
DISCORDTHREADID: $(discordThreadId) DISCORDTHREADID: $(discordThreadId)
+25 -27
View File
@@ -33,14 +33,14 @@ EnableExtraPlatformsInSDK()
echo "Extra platforms already enabled" echo "Extra platforms already enabled"
else else
echo "Enabling extra platform support" echo "Enabling extra platform support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64/' "$BUNDLEDVERSIONS"
fi fi
} }
EnableExtraPlatforms() EnableExtraPlatforms()
{ {
if grep -qv freebsd-x64 src/Directory.Build.props; then if grep -qv freebsd-x64 src/Directory.Build.props; then
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64;linux-x86</RuntimeIdentifiers>^g" src/Directory.Build.props sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64</RuntimeIdentifiers>^g" src/Directory.Build.props
fi fi
} }
@@ -79,9 +79,9 @@ Build()
if [[ -z "$RID" || -z "$FRAMEWORK" ]]; if [[ -z "$RID" || -z "$FRAMEWORK" ]];
then then
dotnet msbuild -restore $slnFile -p:Configuration=Release -p:Platform=$platform -t:PublishAllRids dotnet msbuild -restore $slnFile -p:SelfContained=True -p:Configuration=Release -p:Platform=$platform -t:PublishAllRids
else else
dotnet msbuild -restore $slnFile -p:Configuration=Release -p:Platform=$platform -p:RuntimeIdentifiers=$RID -t:PublishAllRids dotnet msbuild -restore $slnFile -p:SelfContained=True -p:Configuration=Release -p:Platform=$platform -p:RuntimeIdentifiers=$RID -t:PublishAllRids
fi fi
ProgressEnd 'Build' ProgressEnd 'Build'
@@ -137,7 +137,7 @@ PackageLinux()
echo "Adding Prowlarr.Mono to UpdatePackage" echo "Adding Prowlarr.Mono to UpdatePackage"
cp $folder/Prowlarr.Mono.* $folder/Prowlarr.Update cp $folder/Prowlarr.Mono.* $folder/Prowlarr.Update
if [ "$framework" = "net6.0" ]; then if [ "$framework" = "net8.0" ]; then
cp $folder/Mono.Posix.NETStandard.* $folder/Prowlarr.Update cp $folder/Mono.Posix.NETStandard.* $folder/Prowlarr.Update
cp $folder/libMonoPosixHelper.* $folder/Prowlarr.Update cp $folder/libMonoPosixHelper.* $folder/Prowlarr.Update
fi fi
@@ -165,7 +165,7 @@ PackageMacOS()
echo "Adding Prowlarr.Mono to UpdatePackage" echo "Adding Prowlarr.Mono to UpdatePackage"
cp $folder/Prowlarr.Mono.* $folder/Prowlarr.Update cp $folder/Prowlarr.Mono.* $folder/Prowlarr.Update
if [ "$framework" = "net6.0" ]; then if [ "$framework" = "net8.0" ]; then
cp $folder/Mono.Posix.NETStandard.* $folder/Prowlarr.Update cp $folder/Mono.Posix.NETStandard.* $folder/Prowlarr.Update
cp $folder/libMonoPosixHelper.* $folder/Prowlarr.Update cp $folder/libMonoPosixHelper.* $folder/Prowlarr.Update
fi fi
@@ -377,15 +377,14 @@ then
Build Build
if [[ -z "$RID" || -z "$FRAMEWORK" ]]; if [[ -z "$RID" || -z "$FRAMEWORK" ]];
then then
PackageTests "net6.0" "win-x64" PackageTests "net8.0" "win-x64"
PackageTests "net6.0" "win-x86" PackageTests "net8.0" "win-x86"
PackageTests "net6.0" "linux-x64" PackageTests "net8.0" "linux-x64"
PackageTests "net6.0" "linux-musl-x64" PackageTests "net8.0" "linux-musl-x64"
PackageTests "net6.0" "osx-x64" PackageTests "net8.0" "osx-x64"
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ]; if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then then
PackageTests "net6.0" "freebsd-x64" PackageTests "net8.0" "freebsd-x64"
PackageTests "net6.0" "linux-x86"
fi fi
else else
PackageTests "$FRAMEWORK" "$RID" PackageTests "$FRAMEWORK" "$RID"
@@ -413,20 +412,19 @@ then
if [[ -z "$RID" || -z "$FRAMEWORK" ]]; if [[ -z "$RID" || -z "$FRAMEWORK" ]];
then then
Package "net6.0" "win-x64" Package "net8.0" "win-x64"
Package "net6.0" "win-x86" Package "net8.0" "win-x86"
Package "net6.0" "linux-x64" Package "net8.0" "linux-x64"
Package "net6.0" "linux-musl-x64" Package "net8.0" "linux-musl-x64"
Package "net6.0" "linux-arm64" Package "net8.0" "linux-arm64"
Package "net6.0" "linux-musl-arm64" Package "net8.0" "linux-musl-arm64"
Package "net6.0" "linux-arm" Package "net8.0" "linux-arm"
Package "net6.0" "linux-musl-arm" Package "net8.0" "linux-musl-arm"
Package "net6.0" "osx-x64" Package "net8.0" "osx-x64"
Package "net6.0" "osx-arm64" Package "net8.0" "osx-arm64"
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ]; if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then then
Package "net6.0" "freebsd-x64" Package "net8.0" "freebsd-x64"
Package "net6.0" "linux-x86"
fi fi
else else
Package "$FRAMEWORK" "$RID" Package "$FRAMEWORK" "$RID"
@@ -436,7 +434,7 @@ fi
if [ "$INSTALLER" = "YES" ]; if [ "$INSTALLER" = "YES" ];
then then
InstallInno InstallInno
BuildInstaller "net6.0" "win-x64" BuildInstaller "net8.0" "win-x64"
BuildInstaller "net6.0" "win-x86" BuildInstaller "net8.0" "win-x86"
RemoveInno RemoveInno
fi fi
Regular → Executable
+18 -7
View File
@@ -1,13 +1,18 @@
#!/bin/bash
set -e
FRAMEWORK="net8.0"
PLATFORM=$1 PLATFORM=$1
ARCHITECTURE="${2:-x64}"
if [ "$PLATFORM" = "Windows" ]; then if [ "$PLATFORM" = "Windows" ]; then
RUNTIME="win-x64" RUNTIME="win-$ARCHITECTURE"
elif [ "$PLATFORM" = "Linux" ]; then elif [ "$PLATFORM" = "Linux" ]; then
RUNTIME="linux-x64" RUNTIME="linux-$ARCHITECTURE"
elif [ "$PLATFORM" = "Mac" ]; then elif [ "$PLATFORM" = "Mac" ]; then
RUNTIME="osx-x64" RUNTIME="osx-$ARCHITECTURE"
else else
echo "Platform must be provided as first arguement: Windows, Linux or Mac" echo "Platform must be provided as first argument: Windows, Linux or Mac"
exit 1 exit 1
fi fi
@@ -21,17 +26,23 @@ slnFile=src/Prowlarr.sln
platform=Posix platform=Posix
if [ "$PLATFORM" = "Windows" ]; then
application=Prowlarr.Console.dll
else
application=Prowlarr.dll
fi
dotnet clean $slnFile -c Debug dotnet clean $slnFile -c Debug
dotnet clean $slnFile -c Release dotnet clean $slnFile -c Release
dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids
dotnet new tool-manifest dotnet new tool-manifest
dotnet tool install --version 6.5.0 Swashbuckle.AspNetCore.Cli dotnet tool install --version 8.1.4 Swashbuckle.AspNetCore.Cli
dotnet tool run swagger tofile --output ./src/Prowlarr.Api.V1/openapi.json "$outputFolder/net6.0/$RUNTIME/prowlarr.console.dll" v1 & dotnet tool run swagger tofile --output ./src/Prowlarr.Api.V1/openapi.json "$outputFolder/$FRAMEWORK/$RUNTIME/$application" v1 &
sleep 30 sleep 45
kill %1 kill %1
+44 -5
View File
@@ -357,11 +357,16 @@ module.exports = {
], ],
rules: Object.assign(typescriptEslintRecommended.rules, { rules: Object.assign(typescriptEslintRecommended.rules, {
'no-shadow': 'off', '@typescript-eslint/no-unused-vars': [
// These should be enabled after cleaning things up 'error',
'@typescript-eslint/no-unused-vars': 'warn', {
args: 'after-used',
argsIgnorePattern: '^_',
ignoreRestSiblings: true
}
],
'@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-function-return-type': 'off',
'react/prop-types': 'off', 'no-shadow': 'off',
'prettier/prettier': 'error', 'prettier/prettier': 'error',
'simple-import-sort/imports': [ 'simple-import-sort/imports': [
'error', 'error',
@@ -374,7 +379,41 @@ module.exports = {
['^@?\\w', `^(${dirs})(/.*|$)`, '^\\.', '^\\..*css$'] ['^@?\\w', `^(${dirs})(/.*|$)`, '^\\.', '^\\..*css$']
] ]
} }
] ],
// React Hooks
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
// React
'react/function-component-definition': 'error',
'react/hook-use-state': 'error',
'react/jsx-boolean-value': ['error', 'always'],
'react/jsx-curly-brace-presence': [
'error',
{ props: 'never', children: 'never' }
],
'react/jsx-fragments': 'error',
'react/jsx-handler-names': [
'error',
{
eventHandlerPrefix: 'on',
eventHandlerPropPrefix: 'on'
}
],
'react/jsx-no-bind': ['error', { ignoreRefs: true }],
'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
'react/jsx-pascal-case': ['error', { allowAllCaps: true }],
'react/jsx-sort-props': [
'error',
{
callbacksLast: true,
noSortAlphabetically: true,
reservedFirst: true
}
],
'react/prop-types': 'off',
'react/self-closing-comp': 'error'
}) })
}, },
{ {
+5 -4
View File
@@ -25,6 +25,7 @@ module.exports = (env) => {
const config = { const config = {
mode: isProduction ? 'production' : 'development', mode: isProduction ? 'production' : 'development',
devtool: isProduction ? 'source-map' : 'eval-source-map', devtool: isProduction ? 'source-map' : 'eval-source-map',
target: 'web',
stats: { stats: {
children: false children: false
@@ -65,7 +66,7 @@ module.exports = (env) => {
output: { output: {
path: distFolder, path: distFolder,
publicPath: '/', publicPath: '/',
filename: '[name]-[contenthash].js', filename: isProduction ? '[name]-[contenthash].js' : '[name].js',
sourceMapFilename: '[file].map' sourceMapFilename: '[file].map'
}, },
@@ -90,7 +91,7 @@ module.exports = (env) => {
new MiniCssExtractPlugin({ new MiniCssExtractPlugin({
filename: 'Content/styles.css', filename: 'Content/styles.css',
chunkFilename: 'Content/[id]-[chunkhash].css' chunkFilename: isProduction ? 'Content/[id]-[chunkhash].css' : 'Content/[id].css'
}), }),
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
@@ -169,7 +170,7 @@ module.exports = (env) => {
loose: true, loose: true,
debug: false, debug: false,
useBuiltIns: 'entry', useBuiltIns: 'entry',
corejs: 3 corejs: '3.42'
} }
] ]
] ]
@@ -190,7 +191,7 @@ module.exports = (env) => {
options: { options: {
importLoaders: 1, importLoaders: 1,
modules: { modules: {
localIdentName: '[name]/[local]/[hash:base64:5]' localIdentName: isProduction ? '[name]/[local]/[hash:base64:5]' : '[name]/[local]'
} }
} }
}, },
+1
View File
@@ -16,6 +16,7 @@ const mixinsFiles = [
module.exports = { module.exports = {
plugins: [ plugins: [
'autoprefixer',
['postcss-mixins', { ['postcss-mixins', {
mixinsFiles mixinsFiles
}], }],
@@ -1,31 +1,30 @@
import { ConnectedRouter } from 'connected-react-router'; import { ConnectedRouter, ConnectedRouterProps } from 'connected-react-router';
import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import DocumentTitle from 'react-document-title'; import DocumentTitle from 'react-document-title';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { Store } from 'redux';
import PageConnector from 'Components/Page/PageConnector'; import PageConnector from 'Components/Page/PageConnector';
import ApplyTheme from './ApplyTheme'; import ApplyTheme from './ApplyTheme';
import AppRoutes from './AppRoutes'; import AppRoutes from './AppRoutes';
function App({ store, history }) { interface AppProps {
store: Store;
history: ConnectedRouterProps['history'];
}
function App({ store, history }: AppProps) {
return ( return (
<DocumentTitle title={window.Prowlarr.instanceName}> <DocumentTitle title={window.Prowlarr.instanceName}>
<Provider store={store}> <Provider store={store}>
<ConnectedRouter history={history}> <ConnectedRouter history={history}>
<ApplyTheme> <ApplyTheme />
<PageConnector> <PageConnector>
<AppRoutes app={App} /> <AppRoutes />
</PageConnector> </PageConnector>
</ApplyTheme>
</ConnectedRouter> </ConnectedRouter>
</Provider> </Provider>
</DocumentTitle> </DocumentTitle>
); );
} }
App.propTypes = {
store: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
};
export default App; export default App;
-184
View File
@@ -1,184 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import NotFound from 'Components/NotFound';
import Switch from 'Components/Router/Switch';
import HistoryConnector from 'History/HistoryConnector';
import IndexerIndex from 'Indexer/Index/IndexerIndex';
import IndexerStats from 'Indexer/Stats/IndexerStats';
import SearchIndexConnector from 'Search/SearchIndexConnector';
import ApplicationSettings from 'Settings/Applications/ApplicationSettings';
import DevelopmentSettingsConnector from 'Settings/Development/DevelopmentSettingsConnector';
import DownloadClientSettingsConnector from 'Settings/DownloadClients/DownloadClientSettingsConnector';
import GeneralSettingsConnector from 'Settings/General/GeneralSettingsConnector';
import IndexerSettings from 'Settings/Indexers/IndexerSettings';
import NotificationSettings from 'Settings/Notifications/NotificationSettings';
import Settings from 'Settings/Settings';
import TagSettings from 'Settings/Tags/TagSettings';
import UISettingsConnector from 'Settings/UI/UISettingsConnector';
import BackupsConnector from 'System/Backup/BackupsConnector';
import LogsTableConnector from 'System/Events/LogsTableConnector';
import Logs from 'System/Logs/Logs';
import Status from 'System/Status/Status';
import Tasks from 'System/Tasks/Tasks';
import UpdatesConnector from 'System/Updates/UpdatesConnector';
import getPathWithUrlBase from 'Utilities/getPathWithUrlBase';
function AppRoutes(props) {
const {
app
} = props;
return (
<Switch>
{/*
Indexers
*/}
<Route
exact={true}
path="/"
component={IndexerIndex}
/>
{
window.Prowlarr.urlBase &&
<Route
exact={true}
path="/"
addUrlBase={false}
render={() => {
return (
<Redirect
to={getPathWithUrlBase('/')}
component={app}
/>
);
}}
/>
}
<Route
path="/indexers/stats"
component={IndexerStats}
/>
{/*
Search
*/}
<Route
path="/search"
component={SearchIndexConnector}
/>
{/*
Activity
*/}
<Route
path="/history"
component={HistoryConnector}
/>
{/*
Settings
*/}
<Route
exact={true}
path="/settings"
component={Settings}
/>
<Route
path="/settings/indexers"
component={IndexerSettings}
/>
<Route
path="/settings/applications"
component={ApplicationSettings}
/>
<Route
path="/settings/downloadclients"
component={DownloadClientSettingsConnector}
/>
<Route
path="/settings/connect"
component={NotificationSettings}
/>
<Route
path="/settings/tags"
component={TagSettings}
/>
<Route
path="/settings/general"
component={GeneralSettingsConnector}
/>
<Route
path="/settings/ui"
component={UISettingsConnector}
/>
<Route
path="/settings/development"
component={DevelopmentSettingsConnector}
/>
{/*
System
*/}
<Route
path="/system/status"
component={Status}
/>
<Route
path="/system/tasks"
component={Tasks}
/>
<Route
path="/system/backup"
component={BackupsConnector}
/>
<Route
path="/system/updates"
component={UpdatesConnector}
/>
<Route
path="/system/events"
component={LogsTableConnector}
/>
<Route
path="/system/logs/files"
component={Logs}
/>
{/*
Not Found
*/}
<Route
path="*"
component={NotFound}
/>
</Switch>
);
}
AppRoutes.propTypes = {
app: PropTypes.func.isRequired
};
export default AppRoutes;
+117
View File
@@ -0,0 +1,117 @@
import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import NotFound from 'Components/NotFound';
import Switch from 'Components/Router/Switch';
import HistoryConnector from 'History/HistoryConnector';
import IndexerIndex from 'Indexer/Index/IndexerIndex';
import IndexerStats from 'Indexer/Stats/IndexerStats';
import SearchIndexConnector from 'Search/SearchIndexConnector';
import ApplicationSettings from 'Settings/Applications/ApplicationSettings';
import DevelopmentSettingsConnector from 'Settings/Development/DevelopmentSettingsConnector';
import DownloadClientSettingsConnector from 'Settings/DownloadClients/DownloadClientSettingsConnector';
import GeneralSettingsConnector from 'Settings/General/GeneralSettingsConnector';
import IndexerSettings from 'Settings/Indexers/IndexerSettings';
import NotificationSettings from 'Settings/Notifications/NotificationSettings';
import Settings from 'Settings/Settings';
import TagSettings from 'Settings/Tags/TagSettings';
import UISettingsConnector from 'Settings/UI/UISettingsConnector';
import BackupsConnector from 'System/Backup/BackupsConnector';
import LogsTableConnector from 'System/Events/LogsTableConnector';
import Logs from 'System/Logs/Logs';
import Status from 'System/Status/Status';
import Tasks from 'System/Tasks/Tasks';
import Updates from 'System/Updates/Updates';
import getPathWithUrlBase from 'Utilities/getPathWithUrlBase';
function RedirectWithUrlBase() {
return <Redirect to={getPathWithUrlBase('/')} />;
}
function AppRoutes() {
return (
<Switch>
{/*
Indexers
*/}
<Route exact={true} path="/" component={IndexerIndex} />
{window.Prowlarr.urlBase && (
<Route
exact={true}
path="/"
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
addUrlBase={false}
render={RedirectWithUrlBase}
/>
)}
<Route path="/indexers/stats" component={IndexerStats} />
{/*
Search
*/}
<Route path="/search" component={SearchIndexConnector} />
{/*
Activity
*/}
<Route path="/history" component={HistoryConnector} />
{/*
Settings
*/}
<Route exact={true} path="/settings" component={Settings} />
<Route path="/settings/indexers" component={IndexerSettings} />
<Route path="/settings/applications" component={ApplicationSettings} />
<Route
path="/settings/downloadclients"
component={DownloadClientSettingsConnector}
/>
<Route path="/settings/connect" component={NotificationSettings} />
<Route path="/settings/tags" component={TagSettings} />
<Route path="/settings/general" component={GeneralSettingsConnector} />
<Route path="/settings/ui" component={UISettingsConnector} />
<Route
path="/settings/development"
component={DevelopmentSettingsConnector}
/>
{/*
System
*/}
<Route path="/system/status" component={Status} />
<Route path="/system/tasks" component={Tasks} />
<Route path="/system/backup" component={BackupsConnector} />
<Route path="/system/updates" component={Updates} />
<Route path="/system/events" component={LogsTableConnector} />
<Route path="/system/logs/files" component={Logs} />
{/*
Not Found
*/}
<Route path="*" component={NotFound} />
</Switch>
);
}
export default AppRoutes;
-30
View File
@@ -1,30 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import AppUpdatedModalContentConnector from './AppUpdatedModalContentConnector';
function AppUpdatedModal(props) {
const {
isOpen,
onModalClose
} = props;
return (
<Modal
isOpen={isOpen}
closeOnBackgroundClick={false}
onModalClose={onModalClose}
>
<AppUpdatedModalContentConnector
onModalClose={onModalClose}
/>
</Modal>
);
}
AppUpdatedModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default AppUpdatedModal;
+28
View File
@@ -0,0 +1,28 @@
import React, { useCallback } from 'react';
import Modal from 'Components/Modal/Modal';
import AppUpdatedModalContent from './AppUpdatedModalContent';
interface AppUpdatedModalProps {
isOpen: boolean;
onModalClose: (...args: unknown[]) => unknown;
}
function AppUpdatedModal(props: AppUpdatedModalProps) {
const { isOpen, onModalClose } = props;
const handleModalClose = useCallback(() => {
location.reload();
}, []);
return (
<Modal
isOpen={isOpen}
closeOnBackgroundClick={false}
onModalClose={onModalClose}
>
<AppUpdatedModalContent onModalClose={handleModalClose} />
</Modal>
);
}
export default AppUpdatedModal;
@@ -1,12 +0,0 @@
import { connect } from 'react-redux';
import AppUpdatedModal from './AppUpdatedModal';
function createMapDispatchToProps(dispatch, props) {
return {
onModalClose() {
location.reload();
}
};
}
export default connect(null, createMapDispatchToProps)(AppUpdatedModal);
-139
View File
@@ -1,139 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import InlineMarkdown from 'Components/Markdown/InlineMarkdown';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { kinds } from 'Helpers/Props';
import UpdateChanges from 'System/Updates/UpdateChanges';
import translate from 'Utilities/String/translate';
import styles from './AppUpdatedModalContent.css';
function mergeUpdates(items, version, prevVersion) {
let installedIndex = items.findIndex((u) => u.version === version);
let installedPreviouslyIndex = items.findIndex((u) => u.version === prevVersion);
if (installedIndex === -1) {
installedIndex = 0;
}
if (installedPreviouslyIndex === -1) {
installedPreviouslyIndex = items.length;
} else if (installedPreviouslyIndex === installedIndex && items.length) {
installedPreviouslyIndex += 1;
}
const appliedUpdates = items.slice(installedIndex, installedPreviouslyIndex);
if (!appliedUpdates.length) {
return null;
}
const appliedChanges = { new: [], fixed: [] };
appliedUpdates.forEach((u) => {
if (u.changes) {
appliedChanges.new.push(... u.changes.new);
appliedChanges.fixed.push(... u.changes.fixed);
}
});
const mergedUpdate = Object.assign({}, appliedUpdates[0], { changes: appliedChanges });
if (!appliedChanges.new.length && !appliedChanges.fixed.length) {
mergedUpdate.changes = null;
}
return mergedUpdate;
}
function AppUpdatedModalContent(props) {
const {
version,
prevVersion,
isPopulated,
error,
items,
onSeeChangesPress,
onModalClose
} = props;
const update = mergeUpdates(items, version, prevVersion);
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{translate('AppUpdated')}
</ModalHeader>
<ModalBody>
<div>
<InlineMarkdown data={translate('AppUpdatedVersion', { version })} blockClassName={styles.version} />
</div>
{
isPopulated && !error && !!update &&
<div>
{
!update.changes &&
<div className={styles.maintenance}>{translate('MaintenanceRelease')}</div>
}
{
!!update.changes &&
<div>
<div className={styles.changes}>
{translate('WhatsNew')}
</div>
<UpdateChanges
title={translate('New')}
changes={update.changes.new}
/>
<UpdateChanges
title={translate('Fixed')}
changes={update.changes.fixed}
/>
</div>
}
</div>
}
{
!isPopulated && !error &&
<LoadingIndicator />
}
</ModalBody>
<ModalFooter>
<Button
onPress={onSeeChangesPress}
>
{translate('RecentChanges')}
</Button>
<Button
kind={kinds.PRIMARY}
onPress={onModalClose}
>
{translate('Reload')}
</Button>
</ModalFooter>
</ModalContent>
);
}
AppUpdatedModalContent.propTypes = {
version: PropTypes.string.isRequired,
prevVersion: PropTypes.string,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
onSeeChangesPress: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default AppUpdatedModalContent;
+145
View File
@@ -0,0 +1,145 @@
import React, { useCallback, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import InlineMarkdown from 'Components/Markdown/InlineMarkdown';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import usePrevious from 'Helpers/Hooks/usePrevious';
import { kinds } from 'Helpers/Props';
import { fetchUpdates } from 'Store/Actions/systemActions';
import UpdateChanges from 'System/Updates/UpdateChanges';
import Update from 'typings/Update';
import translate from 'Utilities/String/translate';
import AppState from './State/AppState';
import styles from './AppUpdatedModalContent.css';
function mergeUpdates(items: Update[], version: string, prevVersion?: string) {
let installedIndex = items.findIndex((u) => u.version === version);
let installedPreviouslyIndex = items.findIndex(
(u) => u.version === prevVersion
);
if (installedIndex === -1) {
installedIndex = 0;
}
if (installedPreviouslyIndex === -1) {
installedPreviouslyIndex = items.length;
} else if (installedPreviouslyIndex === installedIndex && items.length) {
installedPreviouslyIndex += 1;
}
const appliedUpdates = items.slice(installedIndex, installedPreviouslyIndex);
if (!appliedUpdates.length) {
return null;
}
const appliedChanges: Update['changes'] = { new: [], fixed: [] };
appliedUpdates.forEach((u: Update) => {
if (u.changes) {
appliedChanges.new.push(...u.changes.new);
appliedChanges.fixed.push(...u.changes.fixed);
}
});
const mergedUpdate: Update = Object.assign({}, appliedUpdates[0], {
changes: appliedChanges,
});
if (!appliedChanges.new.length && !appliedChanges.fixed.length) {
mergedUpdate.changes = null;
}
return mergedUpdate;
}
interface AppUpdatedModalContentProps {
onModalClose: () => void;
}
function AppUpdatedModalContent(props: AppUpdatedModalContentProps) {
const dispatch = useDispatch();
const { version, prevVersion } = useSelector((state: AppState) => state.app);
const { isPopulated, error, items } = useSelector(
(state: AppState) => state.system.updates
);
const previousVersion = usePrevious(version);
const { onModalClose } = props;
const update = mergeUpdates(items, version, prevVersion);
const handleSeeChangesPress = useCallback(() => {
window.location.href = `${window.Prowlarr.urlBase}/system/updates`;
}, []);
useEffect(() => {
dispatch(fetchUpdates());
}, [dispatch]);
useEffect(() => {
if (version !== previousVersion) {
dispatch(fetchUpdates());
}
}, [version, previousVersion, dispatch]);
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>{translate('AppUpdated')}</ModalHeader>
<ModalBody>
<div>
<InlineMarkdown
data={translate('AppUpdatedVersion', { version })}
blockClassName={styles.version}
/>
</div>
{isPopulated && !error && !!update ? (
<div>
{update.changes ? (
<div className={styles.maintenance}>
{translate('MaintenanceRelease')}
</div>
) : null}
{update.changes ? (
<div>
<div className={styles.changes}>{translate('WhatsNew')}</div>
<UpdateChanges
title={translate('New')}
changes={update.changes.new}
/>
<UpdateChanges
title={translate('Fixed')}
changes={update.changes.fixed}
/>
</div>
) : null}
</div>
) : null}
{!isPopulated && !error ? <LoadingIndicator /> : null}
</ModalBody>
<ModalFooter>
<Button onPress={handleSeeChangesPress}>
{translate('RecentChanges')}
</Button>
<Button kind={kinds.PRIMARY} onPress={onModalClose}>
{translate('Reload')}
</Button>
</ModalFooter>
</ModalContent>
);
}
export default AppUpdatedModalContent;
@@ -1,78 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchUpdates } from 'Store/Actions/systemActions';
import AppUpdatedModalContent from './AppUpdatedModalContent';
function createMapStateToProps() {
return createSelector(
(state) => state.app.version,
(state) => state.app.prevVersion,
(state) => state.system.updates,
(version, prevVersion, updates) => {
const {
isPopulated,
error,
items
} = updates;
return {
version,
prevVersion,
isPopulated,
error,
items
};
}
);
}
function createMapDispatchToProps(dispatch, props) {
return {
dispatchFetchUpdates() {
dispatch(fetchUpdates());
},
onSeeChangesPress() {
window.location = `${window.Prowlarr.urlBase}/system/updates`;
}
};
}
class AppUpdatedModalContentConnector extends Component {
//
// Lifecycle
componentDidMount() {
this.props.dispatchFetchUpdates();
}
componentDidUpdate(prevProps) {
if (prevProps.version !== this.props.version) {
this.props.dispatchFetchUpdates();
}
}
//
// Render
render() {
const {
dispatchFetchUpdates,
...otherProps
} = this.props;
return (
<AppUpdatedModalContent {...otherProps} />
);
}
}
AppUpdatedModalContentConnector.propTypes = {
version: PropTypes.string.isRequired,
dispatchFetchUpdates: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, createMapDispatchToProps)(AppUpdatedModalContentConnector);
-50
View File
@@ -1,50 +0,0 @@
import PropTypes from 'prop-types';
import React, { Fragment, useCallback, useEffect } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import themes from 'Styles/Themes';
function createMapStateToProps() {
return createSelector(
(state) => state.settings.ui.item.theme || window.Prowlarr.theme,
(
theme
) => {
return {
theme
};
}
);
}
function ApplyTheme({ theme, children }) {
// Update the CSS Variables
const updateCSSVariables = useCallback(() => {
const arrayOfVariableKeys = Object.keys(themes[theme]);
const arrayOfVariableValues = Object.values(themes[theme]);
// Loop through each array key and set the CSS Variables
arrayOfVariableKeys.forEach((cssVariableKey, index) => {
// Based on our snippet from MDN
document.documentElement.style.setProperty(
`--${cssVariableKey}`,
arrayOfVariableValues[index]
);
});
}, [theme]);
// On Component Mount and Component Update
useEffect(() => {
updateCSSVariables(theme);
}, [updateCSSVariables, theme]);
return <Fragment>{children}</Fragment>;
}
ApplyTheme.propTypes = {
theme: PropTypes.string.isRequired,
children: PropTypes.object.isRequired
};
export default connect(createMapStateToProps)(ApplyTheme);
+33
View File
@@ -0,0 +1,33 @@
import { useCallback, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import themes from 'Styles/Themes';
import AppState from './State/AppState';
function createThemeSelector() {
return createSelector(
(state: AppState) => state.settings.ui.item.theme || window.Prowlarr.theme,
(theme) => {
return theme;
}
);
}
function ApplyTheme() {
const theme = useSelector(createThemeSelector());
const updateCSSVariables = useCallback(() => {
Object.entries(themes[theme]).forEach(([key, value]) => {
document.documentElement.style.setProperty(`--${key}`, value);
});
}, [theme]);
// On Component Mount and Component Update
useEffect(() => {
updateCSSVariables();
}, [updateCSSVariables, theme]);
return null;
}
export default ApplyTheme;
@@ -1,5 +1,4 @@
import PropTypes from 'prop-types'; import React, { useCallback } from 'react';
import React from 'react';
import Button from 'Components/Link/Button'; import Button from 'Components/Link/Button';
import Modal from 'Components/Modal/Modal'; import Modal from 'Components/Modal/Modal';
import ModalBody from 'Components/Modal/ModalBody'; import ModalBody from 'Components/Modal/ModalBody';
@@ -10,36 +9,31 @@ import { kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import styles from './ConnectionLostModal.css'; import styles from './ConnectionLostModal.css';
function ConnectionLostModal(props) { interface ConnectionLostModalProps {
const { isOpen: boolean;
isOpen, }
onModalClose
} = props; function ConnectionLostModal(props: ConnectionLostModalProps) {
const { isOpen } = props;
const handleModalClose = useCallback(() => {
location.reload();
}, []);
return ( return (
<Modal <Modal isOpen={isOpen} onModalClose={handleModalClose}>
isOpen={isOpen} <ModalContent onModalClose={handleModalClose}>
onModalClose={onModalClose} <ModalHeader>{translate('ConnectionLost')}</ModalHeader>
>
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{translate('ConnectionLost')}
</ModalHeader>
<ModalBody> <ModalBody>
<div> <div>{translate('ConnectionLostToBackend')}</div>
{translate('ConnectionLostToBackend')}
</div>
<div className={styles.automatic}> <div className={styles.automatic}>
{translate('ConnectionLostReconnect')} {translate('ConnectionLostReconnect')}
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button <Button kind={kinds.PRIMARY} onPress={handleModalClose}>
kind={kinds.PRIMARY}
onPress={onModalClose}
>
{translate('Reload')} {translate('Reload')}
</Button> </Button>
</ModalFooter> </ModalFooter>
@@ -48,9 +42,4 @@ function ConnectionLostModal(props) {
); );
} }
ConnectionLostModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default ConnectionLostModal; export default ConnectionLostModal;
@@ -1,12 +0,0 @@
import { connect } from 'react-redux';
import ConnectionLostModal from './ConnectionLostModal';
function createMapDispatchToProps(dispatch, props) {
return {
onModalClose() {
location.reload();
}
};
}
export default connect(undefined, createMapDispatchToProps)(ConnectionLostModal);
+11 -1
View File
@@ -1,5 +1,6 @@
import Column from 'Components/Table/Column';
import SortDirection from 'Helpers/Props/SortDirection'; import SortDirection from 'Helpers/Props/SortDirection';
import { FilterBuilderProp } from './AppState'; import { FilterBuilderProp, PropertyFilter } from './AppState';
export interface Error { export interface Error {
responseJSON: { responseJSON: {
@@ -18,10 +19,18 @@ export interface AppSectionSaveState {
} }
export interface PagedAppSectionState { export interface PagedAppSectionState {
page: number;
pageSize: number; pageSize: number;
totalPages: number;
totalRecords?: number;
}
export interface TableAppSectionState {
columns: Column[];
} }
export interface AppSectionFilterState<T> { export interface AppSectionFilterState<T> {
selectedFilterKey: string;
filters: PropertyFilter[];
filterBuilderProps: FilterBuilderProp<T>[]; filterBuilderProps: FilterBuilderProp<T>[];
} }
@@ -38,6 +47,7 @@ export interface AppSectionItemState<T> {
isFetching: boolean; isFetching: boolean;
isPopulated: boolean; isPopulated: boolean;
error: Error; error: Error;
pendingChanges: Partial<T>;
item: T; item: T;
} }
+4
View File
@@ -43,6 +43,10 @@ export interface CustomFilter {
} }
export interface AppSectionState { export interface AppSectionState {
isConnected: boolean;
isReconnecting: boolean;
version: string;
prevVersion?: string;
dimensions: { dimensions: {
isSmallScreen: boolean; isSmallScreen: boolean;
width: number; width: number;
@@ -31,6 +31,8 @@ interface IndexerAppState
AppSectionDeleteState, AppSectionDeleteState,
AppSectionSaveState { AppSectionSaveState {
itemMap: Record<number, number>; itemMap: Record<number, number>;
isTestingAll: boolean;
} }
export type IndexerStatusAppState = AppSectionState<IndexerStatus>; export type IndexerStatusAppState = AppSectionState<IndexerStatus>;
+9 -1
View File
@@ -7,7 +7,8 @@ import { IndexerCategory } from 'Indexer/Indexer';
import Application from 'typings/Application'; import Application from 'typings/Application';
import DownloadClient from 'typings/DownloadClient'; import DownloadClient from 'typings/DownloadClient';
import Notification from 'typings/Notification'; import Notification from 'typings/Notification';
import { UiSettings } from 'typings/UiSettings'; import General from 'typings/Settings/General';
import UiSettings from 'typings/Settings/UiSettings';
export interface AppProfileAppState export interface AppProfileAppState
extends AppSectionState<Application>, extends AppSectionState<Application>,
@@ -24,6 +25,12 @@ export interface ApplicationAppState
export interface DownloadClientAppState export interface DownloadClientAppState
extends AppSectionState<DownloadClient>, extends AppSectionState<DownloadClient>,
AppSectionDeleteState, AppSectionDeleteState,
AppSectionSaveState {
isTestingAll: boolean;
}
export interface GeneralAppState
extends AppSectionItemState<General>,
AppSectionSaveState {} AppSectionSaveState {}
export interface IndexerCategoryAppState export interface IndexerCategoryAppState
@@ -41,6 +48,7 @@ interface SettingsAppState {
appProfiles: AppProfileAppState; appProfiles: AppProfileAppState;
applications: ApplicationAppState; applications: ApplicationAppState;
downloadClients: DownloadClientAppState; downloadClients: DownloadClientAppState;
general: GeneralAppState;
indexerCategories: IndexerCategoryAppState; indexerCategories: IndexerCategoryAppState;
notifications: NotificationAppState; notifications: NotificationAppState;
ui: UiSettingsAppState; ui: UiSettingsAppState;
+10 -1
View File
@@ -1,10 +1,19 @@
import Health from 'typings/Health';
import SystemStatus from 'typings/SystemStatus'; import SystemStatus from 'typings/SystemStatus';
import { AppSectionItemState } from './AppSectionState'; import Task from 'typings/Task';
import Update from 'typings/Update';
import AppSectionState, { AppSectionItemState } from './AppSectionState';
export type HealthAppState = AppSectionState<Health>;
export type SystemStatusAppState = AppSectionItemState<SystemStatus>; export type SystemStatusAppState = AppSectionItemState<SystemStatus>;
export type TaskAppState = AppSectionState<Task>;
export type UpdateAppState = AppSectionState<Update>;
interface SystemAppState { interface SystemAppState {
health: HealthAppState;
status: SystemStatusAppState; status: SystemStatusAppState;
tasks: TaskAppState;
updates: UpdateAppState;
} }
export default SystemAppState; export default SystemAppState;
@@ -46,6 +46,10 @@ class StackedBarChart extends Component {
size: 14, size: 14,
family: defaultFontFamily family: defaultFontFamily
} }
},
tooltip: {
mode: 'index',
position: 'average'
} }
} }
}, },
@@ -10,6 +10,7 @@ class DescriptionListItem extends Component {
render() { render() {
const { const {
className,
titleClassName, titleClassName,
descriptionClassName, descriptionClassName,
title, title,
@@ -17,7 +18,7 @@ class DescriptionListItem extends Component {
} = this.props; } = this.props;
return ( return (
<div> <div className={className}>
<DescriptionListItemTitle <DescriptionListItemTitle
className={titleClassName} className={titleClassName}
> >
@@ -35,6 +36,7 @@ class DescriptionListItem extends Component {
} }
DescriptionListItem.propTypes = { DescriptionListItem.propTypes = {
className: PropTypes.string,
titleClassName: PropTypes.string, titleClassName: PropTypes.string,
descriptionClassName: PropTypes.string, descriptionClassName: PropTypes.string,
title: PropTypes.string, title: PropTypes.string,
@@ -63,11 +63,7 @@ function ErrorBoundaryError(props: ErrorBoundaryErrorProps) {
<div>{info.componentStack}</div> <div>{info.componentStack}</div>
)} )}
{ <div className={styles.version}>Version: {window.Prowlarr.version}</div>
<div className={styles.version}>
Version: {window.Prowlarr.version}
</div>
}
</details> </details>
</div> </div>
); );
@@ -3,6 +3,7 @@ import React, { Component } from 'react';
import SelectInput from 'Components/Form/SelectInput'; import SelectInput from 'Components/Form/SelectInput';
import IconButton from 'Components/Link/IconButton'; import IconButton from 'Components/Link/IconButton';
import { filterBuilderTypes, filterBuilderValueTypes, icons } from 'Helpers/Props'; import { filterBuilderTypes, filterBuilderValueTypes, icons } from 'Helpers/Props';
import sortByProp from 'Utilities/Array/sortByProp';
import AppProfileFilterBuilderRowValueConnector from './AppProfileFilterBuilderRowValueConnector'; import AppProfileFilterBuilderRowValueConnector from './AppProfileFilterBuilderRowValueConnector';
import BoolFilterBuilderRowValue from './BoolFilterBuilderRowValue'; import BoolFilterBuilderRowValue from './BoolFilterBuilderRowValue';
import CategoryFilterBuilderRowValue from './CategoryFilterBuilderRowValue'; import CategoryFilterBuilderRowValue from './CategoryFilterBuilderRowValue';
@@ -212,7 +213,7 @@ class FilterBuilderRow extends Component {
key: name, key: name,
value: typeof label === 'function' ? label() : label value: typeof label === 'function' ? label() : label
}; };
}).sort((a, b) => a.value.localeCompare(b.value)); }).sort(sortByProp('value'));
const ValueComponent = getRowValueConnector(selectedFilterBuilderProp); const ValueComponent = getRowValueConnector(selectedFilterBuilderProp);
@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { filterBuilderTypes } from 'Helpers/Props'; import { filterBuilderTypes } from 'Helpers/Props';
import * as filterTypes from 'Helpers/Props/filterTypes'; import * as filterTypes from 'Helpers/Props/filterTypes';
import sortByName from 'Utilities/Array/sortByName'; import sortByProp from 'Utilities/Array/sortByProp';
import FilterBuilderRowValue from './FilterBuilderRowValue'; import FilterBuilderRowValue from './FilterBuilderRowValue';
function createTagListSelector() { function createTagListSelector() {
@@ -38,7 +38,7 @@ function createTagListSelector() {
} }
return acc; return acc;
}, []).sort(sortByName); }, []).sort(sortByProp('name'));
} }
return _.uniqBy(items, 'id'); return _.uniqBy(items, 'id');
@@ -5,6 +5,7 @@ import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent'; import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter'; import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader'; import ModalHeader from 'Components/Modal/ModalHeader';
import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import CustomFilter from './CustomFilter'; import CustomFilter from './CustomFilter';
import styles from './CustomFiltersModalContent.css'; import styles from './CustomFiltersModalContent.css';
@@ -31,7 +32,7 @@ function CustomFiltersModalContent(props) {
<ModalBody> <ModalBody>
{ {
customFilters customFilters
.sort((a, b) => a.label.localeCompare(b.label)) .sort((a, b) => sortByProp(a, b, 'label'))
.map((customFilter) => { .map((customFilter) => {
return ( return (
<CustomFilter <CustomFilter
@@ -4,13 +4,13 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector'; import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
import sortByName from 'Utilities/Array/sortByName'; import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import SelectInput from './SelectInput'; import SelectInput from './SelectInput';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
createSortedSectionSelector('settings.appProfiles', sortByName), createSortedSectionSelector('settings.appProfiles', sortByProp('name')),
(state, { includeNoChange }) => includeNoChange, (state, { includeNoChange }) => includeNoChange,
(state, { includeMixed }) => includeMixed, (state, { includeMixed }) => includeMixed,
(appProfiles, includeNoChange, includeMixed) => { (appProfiles, includeNoChange, includeMixed) => {
@@ -3,7 +3,8 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { fetchDownloadClients } from 'Store/Actions/settingsActions'; import { fetchDownloadClients } from 'Store/Actions/settingsActions';
import sortByName from 'Utilities/Array/sortByName'; import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate';
import EnhancedSelectInput from './EnhancedSelectInput'; import EnhancedSelectInput from './EnhancedSelectInput';
function createMapStateToProps() { function createMapStateToProps() {
@@ -21,7 +22,7 @@ function createMapStateToProps() {
const values = items const values = items
.filter((downloadClient) => downloadClient.protocol === protocolFilter) .filter((downloadClient) => downloadClient.protocol === protocolFilter)
.sort(sortByName) .sort(sortByProp('name'))
.map((downloadClient) => ({ .map((downloadClient) => ({
key: downloadClient.id, key: downloadClient.id,
value: downloadClient.name, value: downloadClient.name,
@@ -31,7 +32,7 @@ function createMapStateToProps() {
if (includeAny) { if (includeAny) {
values.unshift({ values.unshift({
key: 0, key: 0,
value: '(Any)' value: `(${translate('Any')})`
}); });
} }
@@ -20,6 +20,8 @@ import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue';
import TextInput from './TextInput'; import TextInput from './TextInput';
import styles from './EnhancedSelectInput.css'; import styles from './EnhancedSelectInput.css';
const MINIMUM_DISTANCE_FROM_EDGE = 10;
function isArrowKey(keyCode) { function isArrowKey(keyCode) {
return keyCode === keyCodes.UP_ARROW || keyCode === keyCodes.DOWN_ARROW; return keyCode === keyCodes.UP_ARROW || keyCode === keyCodes.DOWN_ARROW;
} }
@@ -137,18 +139,9 @@ class EnhancedSelectInput extends Component {
// Listeners // Listeners
onComputeMaxHeight = (data) => { onComputeMaxHeight = (data) => {
const {
top,
bottom
} = data.offsets.reference;
const windowHeight = window.innerHeight; const windowHeight = window.innerHeight;
if ((/^botton/).test(data.placement)) { data.styles.maxHeight = windowHeight - MINIMUM_DISTANCE_FROM_EDGE;
data.styles.maxHeight = windowHeight - bottom;
} else {
data.styles.maxHeight = top;
}
return data; return data;
}; };
@@ -271,26 +264,29 @@ class EnhancedSelectInput extends Component {
this.setState({ isOpen: !this.state.isOpen }); this.setState({ isOpen: !this.state.isOpen });
}; };
onSelect = (value) => { onSelect = (newValue) => {
if (Array.isArray(this.props.value)) { const { name, value, values, onChange } = this.props;
let newValue = null;
const index = this.props.value.indexOf(value); if (Array.isArray(value)) {
let arrayValue = null;
const index = value.indexOf(newValue);
if (index === -1) { if (index === -1) {
newValue = this.props.values.map((v) => v.key).filter((v) => (v === value) || this.props.value.includes(v)); arrayValue = values.map((v) => v.key).filter((v) => (v === newValue) || value.includes(v));
} else { } else {
newValue = [...this.props.value]; arrayValue = [...value];
newValue.splice(index, 1); arrayValue.splice(index, 1);
} }
this.props.onChange({ onChange({
name: this.props.name, name,
value: newValue value: arrayValue
}); });
} else { } else {
this.setState({ isOpen: false }); this.setState({ isOpen: false });
this.props.onChange({ onChange({
name: this.props.name, name,
value value: newValue
}); });
} }
}; };
@@ -457,6 +453,10 @@ class EnhancedSelectInput extends Component {
order: 851, order: 851,
enabled: true, enabled: true,
fn: this.onComputeMaxHeight fn: this.onComputeMaxHeight
},
preventOverflow: {
enabled: true,
boundariesElement: 'viewport'
} }
}} }}
> >
@@ -485,7 +485,7 @@ class EnhancedSelectInput extends Component {
values.map((v, index) => { values.map((v, index) => {
const hasParent = v.parentKey !== undefined; const hasParent = v.parentKey !== undefined;
const depth = hasParent ? 1 : 0; const depth = hasParent ? 1 : 0;
const parentSelected = hasParent && value.includes(v.parentKey); const parentSelected = hasParent && Array.isArray(value) && value.includes(v.parentKey);
return ( return (
<OptionComponent <OptionComponent
key={v.key} key={v.key}
@@ -34,7 +34,8 @@ function getSelectOptions(items) {
key: option.value, key: option.value,
value: option.name, value: option.name,
hint: option.hint, hint: option.hint,
parentKey: option.parentValue parentKey: option.parentValue,
isDisabled: option.isDisabled
}; };
}); });
} }
+4
View File
@@ -1,3 +1,7 @@
.validationFailures { .validationFailures {
margin-bottom: 20px; margin-bottom: 20px;
} }
.details {
margin-left: 5px;
}
+1
View File
@@ -1,6 +1,7 @@
// This file is automatically generated. // This file is automatically generated.
// Please do not change this file! // Please do not change this file!
interface CssExports { interface CssExports {
'details': string;
'validationFailures': string; 'validationFailures': string;
} }
export const cssExports: CssExports; export const cssExports: CssExports;
+27 -1
View File
@@ -1,7 +1,9 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import Alert from 'Components/Alert'; import Alert from 'Components/Alert';
import { kinds } from 'Helpers/Props'; import Icon from 'Components/Icon';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
import styles from './Form.css'; import styles from './Form.css';
function Form(props) { function Form(props) {
@@ -26,6 +28,18 @@ function Form(props) {
kind={kinds.DANGER} kind={kinds.DANGER}
> >
{error.errorMessage} {error.errorMessage}
{
error.detailedDescription ?
<Tooltip
className={styles.details}
anchor={<Icon name={icons.INFO} />}
tooltip={error.detailedDescription}
kind={kinds.INVERSE}
position={tooltipPositions.TOP}
/> :
null
}
</Alert> </Alert>
); );
}) })
@@ -39,6 +53,18 @@ function Form(props) {
kind={kinds.WARNING} kind={kinds.WARNING}
> >
{warning.errorMessage} {warning.errorMessage}
{
warning.detailedDescription ?
<Tooltip
className={styles.details}
anchor={<Icon name={icons.INFO} />}
tooltip={warning.detailedDescription}
kind={kinds.INVERSE}
position={tooltipPositions.TOP}
/> :
null
}
</Alert> </Alert>
); );
}) })
@@ -1,54 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import Button from 'Components/Link/Button';
import SpinnerButton from 'Components/Link/SpinnerButton';
import { kinds } from 'Helpers/Props';
import styles from './FormInputButton.css';
function FormInputButton(props) {
const {
className,
canSpin,
isLastButton,
...otherProps
} = props;
if (canSpin) {
return (
<SpinnerButton
className={classNames(
className,
!isLastButton && styles.middleButton
)}
kind={kinds.PRIMARY}
{...otherProps}
/>
);
}
return (
<Button
className={classNames(
className,
!isLastButton && styles.middleButton
)}
kind={kinds.PRIMARY}
{...otherProps}
/>
);
}
FormInputButton.propTypes = {
className: PropTypes.string.isRequired,
isLastButton: PropTypes.bool.isRequired,
canSpin: PropTypes.bool.isRequired
};
FormInputButton.defaultProps = {
className: styles.button,
isLastButton: true,
canSpin: false
};
export default FormInputButton;
@@ -0,0 +1,38 @@
import classNames from 'classnames';
import React from 'react';
import Button, { ButtonProps } from 'Components/Link/Button';
import SpinnerButton from 'Components/Link/SpinnerButton';
import { kinds } from 'Helpers/Props';
import styles from './FormInputButton.css';
export interface FormInputButtonProps extends ButtonProps {
canSpin?: boolean;
isLastButton?: boolean;
}
function FormInputButton({
className = styles.button,
canSpin = false,
isLastButton = true,
...otherProps
}: FormInputButtonProps) {
if (canSpin) {
return (
<SpinnerButton
className={classNames(className, !isLastButton && styles.middleButton)}
kind={kinds.PRIMARY}
{...otherProps}
/>
);
}
return (
<Button
className={classNames(className, !isLastButton && styles.middleButton)}
kind={kinds.PRIMARY}
{...otherProps}
/>
);
}
export default FormInputButton;
@@ -256,6 +256,7 @@ FormInputGroup.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
value: PropTypes.any, value: PropTypes.any,
values: PropTypes.arrayOf(PropTypes.any), values: PropTypes.arrayOf(PropTypes.any),
isFloat: PropTypes.bool,
type: PropTypes.string.isRequired, type: PropTypes.string.isRequired,
kind: PropTypes.oneOf(kinds.all), kind: PropTypes.oneOf(kinds.all),
min: PropTypes.number, min: PropTypes.number,
@@ -25,7 +25,7 @@ function FormInputHelpText(props) {
isCheckInput && styles.isCheckInput isCheckInput && styles.isCheckInput
)} )}
> >
<div dangerouslySetInnerHTML={{ __html: text }} /> {text}
{ {
link ? link ?
@@ -4,14 +4,14 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector'; import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
import sortByName from 'Utilities/Array/sortByName'; import sortByProp from 'Utilities/Array/sortByProp';
import titleCase from 'Utilities/String/titleCase'; import titleCase from 'Utilities/String/titleCase';
import EnhancedSelectInput from './EnhancedSelectInput'; import EnhancedSelectInput from './EnhancedSelectInput';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
(state, { value }) => value, (state, { value }) => value,
createSortedSectionSelector('indexers', sortByName), createSortedSectionSelector('indexers', sortByProp('name')),
(value, indexers) => { (value, indexers) => {
const values = []; const values = [];
const groupedIndexers = map(groupBy(indexers.items, 'protocol'), (val, key) => ({ protocol: key, indexers: val })); const groupedIndexers = map(groupBy(indexers.items, 'protocol'), (val, key) => ({ protocol: key, indexers: val }));
@@ -1,5 +0,0 @@
.input {
composes: input from '~Components/Form/TextInput.css';
font-family: $passwordFamily;
}
@@ -1,7 +1,5 @@
import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import TextInput from './TextInput'; import TextInput from './TextInput';
import styles from './PasswordInput.css';
// Prevent a user from copying (or cutting) the password from the input // Prevent a user from copying (or cutting) the password from the input
function onCopy(e) { function onCopy(e) {
@@ -13,17 +11,14 @@ function PasswordInput(props) {
return ( return (
<TextInput <TextInput
{...props} {...props}
type="password"
onCopy={onCopy} onCopy={onCopy}
/> />
); );
} }
PasswordInput.propTypes = { PasswordInput.propTypes = {
className: PropTypes.string.isRequired ...TextInput.props
};
PasswordInput.defaultProps = {
className: styles.input
}; };
export default PasswordInput; export default PasswordInput;
+8 -1
View File
@@ -1,7 +1,14 @@
.select { .select {
@add-mixin truncate;
composes: input from '~Components/Form/Input.css'; composes: input from '~Components/Form/Input.css';
padding: 0 11px; padding: 0 30px 0 11px;
background-image: none, linear-gradient(-135deg, transparent 50%, var(--inputBackgroundColor) 50%), linear-gradient(-225deg, transparent 50%, var(--inputBackgroundColor) 50%), linear-gradient(var(--inputBackgroundColor) 42%, var(--textColor) 42%);
background-position: right 30px center, right bottom, right bottom, right bottom;
background-size: 1px 100%, 35px 27px, 30px 35px, 30px 100%;
background-repeat: no-repeat;
appearance: none;
} }
.hasError { .hasError {
-48
View File
@@ -1,48 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { kinds, sizes } from 'Helpers/Props';
import styles from './Label.css';
function Label(props) {
const {
className,
kind,
size,
outline,
children,
...otherProps
} = props;
return (
<span
className={classNames(
className,
styles[kind],
styles[size],
outline && styles.outline
)}
{...otherProps}
>
{children}
</span>
);
}
Label.propTypes = {
className: PropTypes.string.isRequired,
title: PropTypes.string,
kind: PropTypes.oneOf(kinds.all).isRequired,
size: PropTypes.oneOf(sizes.all).isRequired,
outline: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired
};
Label.defaultProps = {
className: styles.label,
kind: kinds.DEFAULT,
size: sizes.SMALL,
outline: false
};
export default Label;
+33
View File
@@ -0,0 +1,33 @@
import classNames from 'classnames';
import React, { ComponentProps, ReactNode } from 'react';
import { kinds, sizes } from 'Helpers/Props';
import { Kind } from 'Helpers/Props/kinds';
import { Size } from 'Helpers/Props/sizes';
import styles from './Label.css';
export interface LabelProps extends ComponentProps<'span'> {
kind?: Extract<Kind, keyof typeof styles>;
size?: Extract<Size, keyof typeof styles>;
outline?: boolean;
children: ReactNode;
}
export default function Label({
className = styles.label,
kind = kinds.DEFAULT,
size = sizes.SMALL,
outline = false,
...otherProps
}: LabelProps) {
return (
<span
className={classNames(
className,
styles[kind],
styles[size],
outline && styles.outline
)}
{...otherProps}
/>
);
}
-54
View File
@@ -1,54 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { align, kinds, sizes } from 'Helpers/Props';
import Link from './Link';
import styles from './Button.css';
class Button extends Component {
//
// Render
render() {
const {
className,
buttonGroupPosition,
kind,
size,
children,
...otherProps
} = this.props;
return (
<Link
className={classNames(
className,
styles[kind],
styles[size],
buttonGroupPosition && styles[buttonGroupPosition]
)}
{...otherProps}
>
{children}
</Link>
);
}
}
Button.propTypes = {
className: PropTypes.string.isRequired,
buttonGroupPosition: PropTypes.oneOf(align.all),
kind: PropTypes.oneOf(kinds.all),
size: PropTypes.oneOf(sizes.all),
children: PropTypes.node
};
Button.defaultProps = {
className: styles.button,
kind: kinds.DEFAULT,
size: sizes.MEDIUM
};
export default Button;
+37
View File
@@ -0,0 +1,37 @@
import classNames from 'classnames';
import React from 'react';
import { align, kinds, sizes } from 'Helpers/Props';
import { Kind } from 'Helpers/Props/kinds';
import { Size } from 'Helpers/Props/sizes';
import Link, { LinkProps } from './Link';
import styles from './Button.css';
export interface ButtonProps extends Omit<LinkProps, 'children' | 'size'> {
buttonGroupPosition?: Extract<
(typeof align.all)[number],
keyof typeof styles
>;
kind?: Extract<Kind, keyof typeof styles>;
size?: Extract<Size, keyof typeof styles>;
children: Required<LinkProps['children']>;
}
export default function Button({
className = styles.button,
buttonGroupPosition,
kind = kinds.DEFAULT,
size = sizes.MEDIUM,
...otherProps
}: ButtonProps) {
return (
<Link
className={classNames(
className,
styles[kind],
styles[size],
buttonGroupPosition && styles[buttonGroupPosition]
)}
{...otherProps}
/>
);
}
@@ -1,139 +0,0 @@
import Clipboard from 'clipboard';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import FormInputButton from 'Components/Form/FormInputButton';
import Icon from 'Components/Icon';
import { icons, kinds } from 'Helpers/Props';
import getUniqueElememtId from 'Utilities/getUniqueElementId';
import styles from './ClipboardButton.css';
class ClipboardButton extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this._id = getUniqueElememtId();
this._successTimeout = null;
this._testResultTimeout = null;
this.state = {
showSuccess: false,
showError: false
};
}
componentDidMount() {
this._clipboard = new Clipboard(`#${this._id}`, {
text: () => this.props.value,
container: document.getElementById(this._id)
});
this._clipboard.on('success', this.onSuccess);
}
componentDidUpdate() {
const {
showSuccess,
showError
} = this.state;
if (showSuccess || showError) {
this._testResultTimeout = setTimeout(this.resetState, 3000);
}
}
componentWillUnmount() {
if (this._clipboard) {
this._clipboard.destroy();
}
if (this._testResultTimeout) {
clearTimeout(this._testResultTimeout);
}
}
//
// Control
resetState = () => {
this.setState({
showSuccess: false,
showError: false
});
};
//
// Listeners
onSuccess = () => {
this.setState({
showSuccess: true
});
};
onError = () => {
this.setState({
showError: true
});
};
//
// Render
render() {
const {
value,
className,
...otherProps
} = this.props;
const {
showSuccess,
showError
} = this.state;
const showStateIcon = showSuccess || showError;
const iconName = showError ? icons.DANGER : icons.CHECK;
const iconKind = showError ? kinds.DANGER : kinds.SUCCESS;
return (
<FormInputButton
id={this._id}
className={className}
{...otherProps}
>
<span className={showStateIcon ? styles.showStateIcon : undefined}>
{
showSuccess &&
<span className={styles.stateIconContainer}>
<Icon
name={iconName}
kind={iconKind}
/>
</span>
}
{
<span className={styles.clipboardIconContainer}>
<Icon name={icons.CLIPBOARD} />
</span>
}
</span>
</FormInputButton>
);
}
}
ClipboardButton.propTypes = {
className: PropTypes.string.isRequired,
value: PropTypes.string.isRequired
};
ClipboardButton.defaultProps = {
className: styles.button
};
export default ClipboardButton;
@@ -0,0 +1,76 @@
import copy from 'copy-to-clipboard';
import React, { useCallback, useEffect, useState } from 'react';
import FormInputButton from 'Components/Form/FormInputButton';
import Icon from 'Components/Icon';
import { icons, kinds } from 'Helpers/Props';
import { ButtonProps } from './Button';
import styles from './ClipboardButton.css';
export interface ClipboardButtonProps extends Omit<ButtonProps, 'children'> {
value: string;
}
export type ClipboardState = 'success' | 'error' | null;
export default function ClipboardButton({
id,
value,
className = styles.button,
...otherProps
}: ClipboardButtonProps) {
const [state, setState] = useState<ClipboardState>(null);
useEffect(() => {
if (!state) {
return;
}
const timeoutId = setTimeout(() => {
setState(null);
}, 3000);
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
};
}, [state]);
const handleClick = useCallback(async () => {
try {
if ('clipboard' in navigator) {
await navigator.clipboard.writeText(value);
} else {
copy(value);
}
setState('success');
} catch (e) {
setState('error');
console.error(`Failed to copy to clipboard`, e);
}
}, [value]);
return (
<FormInputButton
className={className}
onClick={handleClick}
{...otherProps}
>
<span className={state ? styles.showStateIcon : undefined}>
{state ? (
<span className={styles.stateIconContainer}>
<Icon
name={state === 'error' ? icons.DANGER : icons.CHECK}
kind={state === 'error' ? kinds.DANGER : kinds.SUCCESS}
/>
</span>
) : null}
<span className={styles.clipboardIconContainer}>
<Icon name={icons.CLIPBOARD} />
</span>
</span>
</FormInputButton>
);
}
+67 -70
View File
@@ -1,96 +1,93 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React, { import React, {
ComponentClass, ComponentPropsWithoutRef,
FunctionComponent, ElementType,
SyntheticEvent, SyntheticEvent,
useCallback, useCallback,
} from 'react'; } from 'react';
import { Link as RouterLink } from 'react-router-dom'; import { Link as RouterLink } from 'react-router-dom';
import styles from './Link.css'; import styles from './Link.css';
interface ReactRouterLinkProps { export type LinkProps<C extends ElementType = 'button'> =
to?: string; ComponentPropsWithoutRef<C> & {
} component?: C;
to?: string;
target?: string;
isDisabled?: LinkProps<C>['disabled'];
noRouter?: boolean;
onPress?(event: SyntheticEvent): void;
};
export interface LinkProps extends React.HTMLProps<HTMLAnchorElement> { export default function Link<C extends ElementType = 'button'>({
className?: string; className,
component?: component,
| string to,
| FunctionComponent<LinkProps> target,
| ComponentClass<LinkProps, unknown>; type,
to?: string; isDisabled,
target?: string; noRouter,
isDisabled?: boolean; onPress,
noRouter?: boolean; ...otherProps
onPress?(event: SyntheticEvent): void; }: LinkProps<C>) {
} const Component = component || 'button';
function Link(props: LinkProps) {
const {
className,
component = 'button',
to,
target,
type,
isDisabled,
noRouter = false,
onPress,
...otherProps
} = props;
const onClick = useCallback( const onClick = useCallback(
(event: SyntheticEvent) => { (event: SyntheticEvent) => {
if (!isDisabled && onPress) { if (isDisabled) {
onPress(event); return;
} }
onPress?.(event);
}, },
[isDisabled, onPress] [isDisabled, onPress]
); );
const linkProps: React.HTMLProps<HTMLAnchorElement> & ReactRouterLinkProps = { const linkClass = classNames(
target,
};
let el = component;
if (to) {
if (/\w+?:\/\//.test(to)) {
el = 'a';
linkProps.href = to;
linkProps.target = target || '_blank';
linkProps.rel = 'noreferrer';
} else if (noRouter) {
el = 'a';
linkProps.href = to;
linkProps.target = target || '_self';
} else {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
el = RouterLink;
linkProps.to = `${window.Prowlarr.urlBase}/${to.replace(/^\//, '')}`;
linkProps.target = target;
}
}
if (el === 'button' || el === 'input') {
linkProps.type = type || 'button';
linkProps.disabled = isDisabled;
}
linkProps.className = classNames(
className, className,
styles.link, styles.link,
to && styles.to, to && styles.to,
isDisabled && 'isDisabled' isDisabled && 'isDisabled'
); );
const elementProps = { if (to) {
...otherProps, const toLink = /\w+?:\/\//.test(to);
type,
...linkProps,
};
elementProps.onClick = onClick; if (toLink || noRouter) {
return (
<a
href={to}
target={target || (toLink ? '_blank' : '_self')}
rel={toLink ? 'noreferrer' : undefined}
className={linkClass}
onClick={onClick}
{...otherProps}
/>
);
}
return React.createElement(el, elementProps); return (
<RouterLink
to={`${window.Prowlarr.urlBase}/${to.replace(/^\//, '')}`}
target={target}
className={linkClass}
onClick={onClick}
{...otherProps}
/>
);
}
return (
<Component
type={
component === 'button' || component === 'input'
? type || 'button'
: type
}
target={target}
className={linkClass}
disabled={isDisabled}
onClick={onClick}
{...otherProps}
/>
);
} }
export default Link;
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import FilterMenuItem from './FilterMenuItem'; import FilterMenuItem from './FilterMenuItem';
import MenuContent from './MenuContent'; import MenuContent from './MenuContent';
@@ -47,7 +48,7 @@ class FilterMenuContent extends Component {
{ {
customFilters customFilters
.sort((a, b) => a.label.localeCompare(b.label)) .sort(sortByProp('label'))
.map((filter) => { .map((filter) => {
return ( return (
<FilterMenuItem <FilterMenuItem
+1
View File
@@ -19,6 +19,7 @@
.modal { .modal {
position: relative; position: relative;
display: flex; display: flex;
max-width: 90%;
max-height: 90%; max-height: 90%;
border-radius: 6px; border-radius: 6px;
opacity: 1; opacity: 1;
@@ -7,7 +7,7 @@ import { icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import IndexerSearchInputConnector from './IndexerSearchInputConnector'; import IndexerSearchInputConnector from './IndexerSearchInputConnector';
import KeyboardShortcutsModal from './KeyboardShortcutsModal'; import KeyboardShortcutsModal from './KeyboardShortcutsModal';
import PageHeaderActionsMenuConnector from './PageHeaderActionsMenuConnector'; import PageHeaderActionsMenu from './PageHeaderActionsMenu';
import styles from './PageHeader.css'; import styles from './PageHeader.css';
class PageHeader extends Component { class PageHeader extends Component {
@@ -87,7 +87,8 @@ class PageHeader extends Component {
to="https://translate.servarr.com/projects/servarr/prowlarr/" to="https://translate.servarr.com/projects/servarr/prowlarr/"
size={24} size={24}
/> />
<PageHeaderActionsMenuConnector
<PageHeaderActionsMenu
onKeyboardShortcutsPress={this.onOpenKeyboardShortcutsModal} onKeyboardShortcutsPress={this.onOpenKeyboardShortcutsModal}
/> />
</div> </div>
@@ -1,90 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Icon from 'Components/Icon';
import Menu from 'Components/Menu/Menu';
import MenuButton from 'Components/Menu/MenuButton';
import MenuContent from 'Components/Menu/MenuContent';
import MenuItem from 'Components/Menu/MenuItem';
import MenuItemSeparator from 'Components/Menu/MenuItemSeparator';
import { align, icons, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './PageHeaderActionsMenu.css';
function PageHeaderActionsMenu(props) {
const {
formsAuth,
onKeyboardShortcutsPress,
onRestartPress,
onShutdownPress
} = props;
return (
<div>
<Menu alignMenu={align.RIGHT}>
<MenuButton className={styles.menuButton} aria-label="Menu Button">
<Icon
name={icons.INTERACTIVE}
title={translate('Menu')}
/>
</MenuButton>
<MenuContent>
<MenuItem onPress={onKeyboardShortcutsPress}>
<Icon
className={styles.itemIcon}
name={icons.KEYBOARD}
/>
{translate('KeyboardShortcuts')}
</MenuItem>
<MenuItemSeparator />
<MenuItem onPress={onRestartPress}>
<Icon
className={styles.itemIcon}
name={icons.RESTART}
/>
{translate('Restart')}
</MenuItem>
<MenuItem onPress={onShutdownPress}>
<Icon
className={styles.itemIcon}
name={icons.SHUTDOWN}
kind={kinds.DANGER}
/>
{translate('Shutdown')}
</MenuItem>
{
formsAuth &&
<div className={styles.separator} />
}
{
formsAuth &&
<MenuItem
to={`${window.Prowlarr.urlBase}/logout`}
noRouter={true}
>
<Icon
className={styles.itemIcon}
name={icons.LOGOUT}
/>
Logout
</MenuItem>
}
</MenuContent>
</Menu>
</div>
);
}
PageHeaderActionsMenu.propTypes = {
formsAuth: PropTypes.bool.isRequired,
onKeyboardShortcutsPress: PropTypes.func.isRequired,
onRestartPress: PropTypes.func.isRequired,
onShutdownPress: PropTypes.func.isRequired
};
export default PageHeaderActionsMenu;
@@ -0,0 +1,90 @@
import React, { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import AppState from 'App/State/AppState';
import Icon from 'Components/Icon';
import Menu from 'Components/Menu/Menu';
import MenuButton from 'Components/Menu/MenuButton';
import MenuContent from 'Components/Menu/MenuContent';
import MenuItem from 'Components/Menu/MenuItem';
import MenuItemSeparator from 'Components/Menu/MenuItemSeparator';
import { align, icons, kinds } from 'Helpers/Props';
import { restart, shutdown } from 'Store/Actions/systemActions';
import translate from 'Utilities/String/translate';
import styles from './PageHeaderActionsMenu.css';
interface PageHeaderActionsMenuProps {
onKeyboardShortcutsPress(): void;
}
function PageHeaderActionsMenu(props: PageHeaderActionsMenuProps) {
const { onKeyboardShortcutsPress } = props;
const dispatch = useDispatch();
const { authentication, isDocker } = useSelector(
(state: AppState) => state.system.status.item
);
const formsAuth = authentication === 'forms';
const handleRestartPress = useCallback(() => {
dispatch(restart());
}, [dispatch]);
const handleShutdownPress = useCallback(() => {
dispatch(shutdown());
}, [dispatch]);
return (
<div>
<Menu alignMenu={align.RIGHT}>
<MenuButton className={styles.menuButton} aria-label="Menu Button">
<Icon name={icons.INTERACTIVE} title={translate('Menu')} />
</MenuButton>
<MenuContent>
<MenuItem onPress={onKeyboardShortcutsPress}>
<Icon className={styles.itemIcon} name={icons.KEYBOARD} />
{translate('KeyboardShortcuts')}
</MenuItem>
{isDocker ? null : (
<>
<MenuItemSeparator />
<MenuItem onPress={handleRestartPress}>
<Icon className={styles.itemIcon} name={icons.RESTART} />
{translate('Restart')}
</MenuItem>
<MenuItem onPress={handleShutdownPress}>
<Icon
className={styles.itemIcon}
name={icons.SHUTDOWN}
kind={kinds.DANGER}
/>
{translate('Shutdown')}
</MenuItem>
</>
)}
{formsAuth ? (
<>
<MenuItemSeparator />
<MenuItem
to={`${window.Prowlarr.urlBase}/logout`}
noRouter={true}
>
<Icon className={styles.itemIcon} name={icons.LOGOUT} />
{translate('Logout')}
</MenuItem>
</>
) : null}
</MenuContent>
</Menu>
</div>
);
}
export default PageHeaderActionsMenu;
@@ -1,56 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { restart, shutdown } from 'Store/Actions/systemActions';
import PageHeaderActionsMenu from './PageHeaderActionsMenu';
function createMapStateToProps() {
return createSelector(
(state) => state.system.status,
(status) => {
return {
formsAuth: status.item.authentication === 'forms'
};
}
);
}
const mapDispatchToProps = {
restart,
shutdown
};
class PageHeaderActionsMenuConnector extends Component {
//
// Listeners
onRestartPress = () => {
this.props.restart();
};
onShutdownPress = () => {
this.props.shutdown();
};
//
// Render
render() {
return (
<PageHeaderActionsMenu
{...this.props}
onRestartPress={this.onRestartPress}
onShutdownPress={this.onShutdownPress}
/>
);
}
}
PageHeaderActionsMenuConnector.propTypes = {
restart: PropTypes.func.isRequired,
shutdown: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(PageHeaderActionsMenuConnector);
+4 -4
View File
@@ -1,8 +1,8 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import AppUpdatedModalConnector from 'App/AppUpdatedModalConnector'; import AppUpdatedModal from 'App/AppUpdatedModal';
import ColorImpairedContext from 'App/ColorImpairedContext'; import ColorImpairedContext from 'App/ColorImpairedContext';
import ConnectionLostModalConnector from 'App/ConnectionLostModalConnector'; import ConnectionLostModal from 'App/ConnectionLostModal';
import SignalRConnector from 'Components/SignalRConnector'; import SignalRConnector from 'Components/SignalRConnector';
import AuthenticationRequiredModal from 'FirstRun/AuthenticationRequiredModal'; import AuthenticationRequiredModal from 'FirstRun/AuthenticationRequiredModal';
import locationShape from 'Helpers/Props/Shapes/locationShape'; import locationShape from 'Helpers/Props/Shapes/locationShape';
@@ -102,12 +102,12 @@ class Page extends Component {
{children} {children}
</div> </div>
<AppUpdatedModalConnector <AppUpdatedModal
isOpen={this.state.isUpdatedModalOpen} isOpen={this.state.isUpdatedModalOpen}
onModalClose={this.onUpdatedModalClose} onModalClose={this.onUpdatedModalClose}
/> />
<ConnectionLostModalConnector <ConnectionLostModal
isOpen={this.state.isConnectionLostModalOpen} isOpen={this.state.isConnectionLostModalOpen}
onModalClose={this.onConnectionLostModalClose} onModalClose={this.onConnectionLostModalClose}
/> />
@@ -8,7 +8,7 @@ import Scroller from 'Components/Scroller/Scroller';
import { icons } from 'Helpers/Props'; import { icons } from 'Helpers/Props';
import locationShape from 'Helpers/Props/Shapes/locationShape'; import locationShape from 'Helpers/Props/Shapes/locationShape';
import dimensions from 'Styles/Variables/dimensions'; import dimensions from 'Styles/Variables/dimensions';
import HealthStatusConnector from 'System/Status/Health/HealthStatusConnector'; import HealthStatus from 'System/Status/Health/HealthStatus';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import MessagesConnector from './Messages/MessagesConnector'; import MessagesConnector from './Messages/MessagesConnector';
import PageSidebarItem from './PageSidebarItem'; import PageSidebarItem from './PageSidebarItem';
@@ -87,7 +87,7 @@ const links = [
{ {
title: () => translate('Status'), title: () => translate('Status'),
to: '/system/status', to: '/system/status',
statusComponent: HealthStatusConnector statusComponent: HealthStatus
}, },
{ {
title: () => translate('Tasks'), title: () => translate('Tasks'),
@@ -24,6 +24,7 @@
composes: link; composes: link;
padding: 10px 24px; padding: 10px 24px;
padding-left: 35px;
} }
.isActiveLink { .isActiveLink {
@@ -41,10 +42,6 @@
text-align: center; text-align: center;
} }
.noIcon {
margin-left: 25px;
}
.status { .status {
float: right; float: right;
} }
@@ -8,7 +8,6 @@ interface CssExports {
'isActiveParentLink': string; 'isActiveParentLink': string;
'item': string; 'item': string;
'link': string; 'link': string;
'noIcon': string;
'status': string; 'status': string;
} }
export const cssExports: CssExports; export const cssExports: CssExports;
@@ -63,9 +63,7 @@ class PageSidebarItem extends Component {
</span> </span>
} }
<span className={isChildItem ? styles.noIcon : null}> {typeof title === 'function' ? title() : title}
{typeof title === 'function' ? title() : title}
</span>
{ {
!!StatusComponent && !!StatusComponent &&
@@ -22,11 +22,14 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
overflow: hidden;
height: 24px; height: 24px;
} }
.label { .label {
padding: 0 3px; padding: 0 3px;
max-width: 100%;
max-height: 100%;
color: var(--toolbarLabelColor); color: var(--toolbarLabelColor);
font-size: $extraSmallFontSize; font-size: $extraSmallFontSize;
line-height: calc($extraSmallFontSize + 1px); line-height: calc($extraSmallFontSize + 1px);
@@ -23,6 +23,7 @@ function PageToolbarButton(props) {
isDisabled && styles.isDisabled isDisabled && styles.isDisabled
)} )}
isDisabled={isDisabled || isSpinning} isDisabled={isDisabled || isSpinning}
title={label}
{...otherProps} {...otherProps}
> >
<Icon <Icon
+46 -7
View File
@@ -141,6 +141,16 @@ class SignalRConnector extends Component {
console.error(`signalR: Unable to find handler for ${name}`); console.error(`signalR: Unable to find handler for ${name}`);
}; };
handleApplications = ({ action, resource }) => {
const section = 'settings.applications';
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: resource.id });
}
};
handleCommand = (body) => { handleCommand = (body) => {
if (body.action === 'sync') { if (body.action === 'sync') {
this.props.dispatchFetchCommands(); this.props.dispatchFetchCommands();
@@ -150,8 +160,8 @@ class SignalRConnector extends Component {
const resource = body.resource; const resource = body.resource;
const status = resource.status; const status = resource.status;
// Both sucessful and failed commands need to be // Both successful and failed commands need to be
// completed, otherwise they spin until they timeout. // completed, otherwise they spin until they time out.
if (status === 'completed' || status === 'failed') { if (status === 'completed' || status === 'failed') {
this.props.dispatchFinishCommand(resource); this.props.dispatchFinishCommand(resource);
@@ -160,6 +170,16 @@ class SignalRConnector extends Component {
} }
}; };
handleDownloadclient = ({ action, resource }) => {
const section = 'settings.downloadClients';
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: resource.id });
}
};
handleHealth = () => { handleHealth = () => {
this.props.dispatchFetchHealth(); this.props.dispatchFetchHealth();
}; };
@@ -168,14 +188,33 @@ class SignalRConnector extends Component {
this.props.dispatchFetchIndexerStatus(); this.props.dispatchFetchIndexerStatus();
}; };
handleIndexer = (body) => { handleIndexer = ({ action, resource }) => {
const action = body.action;
const section = 'indexers'; const section = 'indexers';
if (action === 'updated') { if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...body.resource }); this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') { } else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: body.resource.id }); this.props.dispatchRemoveItem({ section, id: resource.id });
}
};
handleIndexerproxy = ({ action, resource }) => {
const section = 'settings.indexerProxies';
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: resource.id });
}
};
handleNotification = ({ action, resource }) => {
const section = 'settings.notifications';
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: resource.id });
} }
}; };
+2
View File
@@ -2,9 +2,11 @@ import React from 'react';
type PropertyFunction<T> = () => T; type PropertyFunction<T> = () => T;
// TODO: Convert to generic so `name` can be a type
interface Column { interface Column {
name: string; name: string;
label: string | PropertyFunction<string> | React.ReactNode; label: string | PropertyFunction<string> | React.ReactNode;
className?: string;
columnLabel?: string; columnLabel?: string;
isSortable?: boolean; isSortable?: boolean;
isVisible: boolean; isVisible: boolean;
+15 -2
View File
@@ -65,17 +65,30 @@ class VirtualTable extends Component {
if (this._grid && scrollTop !== undefined && scrollTop !== 0 && !scrollRestored) { if (this._grid && scrollTop !== undefined && scrollTop !== 0 && !scrollRestored) {
this.setState({ scrollRestored: true }); this.setState({ scrollRestored: true });
this._grid.scrollToPosition({ scrollTop }); this._gridScrollToPosition({ scrollTop });
} }
if (scrollIndex != null && scrollIndex !== prevProps.scrollIndex) { if (scrollIndex != null && scrollIndex !== prevProps.scrollIndex) {
this._grid.scrollToCell({ this._gridScrollToCell({
rowIndex: scrollIndex, rowIndex: scrollIndex,
columnIndex: 0 columnIndex: 0
}); });
} }
} }
_gridScrollToCell = ({ rowIndex = 0, columnIndex = 0 }) => {
const scrollOffset = this._grid.getOffsetForCell({
rowIndex,
columnIndex
});
this._gridScrollToPosition(scrollOffset);
};
_gridScrollToPosition = ({ scrollTop = 0, scrollLeft = 0 }) => {
this.props.scroller?.scrollTo({ top: scrollTop, left: scrollLeft });
};
// //
// Control // Control
@@ -0,0 +1,54 @@
import { useCallback, useMemo } from 'react';
import { useDispatch } from 'react-redux';
interface PagingOptions {
page: number;
totalPages: number;
gotoPage: ({ page }: { page: number }) => void;
}
function usePaging(options: PagingOptions) {
const { page, totalPages, gotoPage } = options;
const dispatch = useDispatch();
const handleFirstPagePress = useCallback(() => {
dispatch(gotoPage({ page: 1 }));
}, [dispatch, gotoPage]);
const handlePreviousPagePress = useCallback(() => {
dispatch(gotoPage({ page: Math.max(page - 1, 1) }));
}, [page, dispatch, gotoPage]);
const handleNextPagePress = useCallback(() => {
dispatch(gotoPage({ page: Math.min(page + 1, totalPages) }));
}, [page, totalPages, dispatch, gotoPage]);
const handleLastPagePress = useCallback(() => {
dispatch(gotoPage({ page: totalPages }));
}, [totalPages, dispatch, gotoPage]);
const handlePageSelect = useCallback(
(page: number) => {
dispatch(gotoPage({ page }));
},
[dispatch, gotoPage]
);
return useMemo(() => {
return {
handleFirstPagePress,
handlePreviousPagePress,
handleNextPagePress,
handleLastPagePress,
handlePageSelect,
};
}, [
handleFirstPagePress,
handlePreviousPagePress,
handleNextPagePress,
handleLastPagePress,
handlePageSelect,
]);
}
export default usePaging;
+3 -2
View File
@@ -1,14 +1,15 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { kinds } from 'Helpers/Props'; import { kinds } from 'Helpers/Props';
import sortByProp from 'Utilities/Array/sortByProp';
import Label from './Label'; import Label from './Label';
import styles from './TagList.css'; import styles from './TagList.css';
function TagList({ tags, tagList }) { function TagList({ tags, tagList }) {
const sortedTags = tags const sortedTags = tags
.map((tagId) => tagList.find((tag) => tag.id === tagId)) .map((tagId) => tagList.find((tag) => tag.id === tagId))
.filter((t) => t !== undefined) .filter((tag) => !!tag)
.sort((a, b) => a.label.localeCompare(b.label)); .sort(sortByProp('label'));
return ( return (
<div className={styles.tags}> <div className={styles.tags}>
-11
View File
@@ -25,14 +25,3 @@
font-family: 'Ubuntu Mono'; font-family: 'Ubuntu Mono';
src: url('UbuntuMono-Regular.eot?#iefix&v=1.3.0') format('embedded-opentype'), url('UbuntuMono-Regular.woff?v=1.3.0') format('woff'), url('UbuntuMono-Regular.ttf?v=1.3.0') format('truetype'); src: url('UbuntuMono-Regular.eot?#iefix&v=1.3.0') format('embedded-opentype'), url('UbuntuMono-Regular.woff?v=1.3.0') format('woff'), url('UbuntuMono-Regular.ttf?v=1.3.0') format('truetype');
} }
/*
* text-security-disc
*/
@font-face {
font-weight: normal;
font-style: normal;
font-family: 'text-security-disc';
src: url('text-security-disc.woff?v=1.3.0') format('woff'), url('text-security-disc.ttf?v=1.3.0') format('truetype');
}
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
type DownloadProtocol = 'usenet' | 'torrent' | 'unknown';
export default DownloadProtocol;
@@ -0,0 +1,9 @@
import { useHistory } from 'react-router-dom';
function useCurrentPage() {
const history = useHistory();
return history.action === 'POP';
}
export default useCurrentPage;
@@ -3,15 +3,15 @@ import { useCallback, useState } from 'react';
export default function useModalOpenState( export default function useModalOpenState(
initialState: boolean initialState: boolean
): [boolean, () => void, () => void] { ): [boolean, () => void, () => void] {
const [isOpen, setOpen] = useState(initialState); const [isOpen, setIsOpen] = useState(initialState);
const setModalOpen = useCallback(() => { const setModalOpen = useCallback(() => {
setOpen(true); setIsOpen(true);
}, [setOpen]); }, [setIsOpen]);
const setModalClosed = useCallback(() => { const setModalClosed = useCallback(() => {
setOpen(false); setIsOpen(false);
}, [setOpen]); }, [setIsOpen]);
return [isOpen, setModalOpen, setModalClosed]; return [isOpen, setModalOpen, setModalClosed];
} }
+56
View File
@@ -0,0 +1,56 @@
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import themes from 'Styles/Themes';
function createThemeSelector() {
return createSelector(
(state: AppState) => state.settings.ui.item.theme || window.Prowlarr.theme,
(theme) => theme
);
}
const useTheme = () => {
const selectedTheme = useSelector(createThemeSelector());
const [resolvedTheme, setResolvedTheme] = useState(selectedTheme);
useEffect(() => {
if (selectedTheme !== 'auto') {
setResolvedTheme(selectedTheme);
return;
}
const applySystemTheme = () => {
setResolvedTheme(
window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light'
);
};
applySystemTheme();
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', applySystemTheme);
return () => {
window
.matchMedia('(prefers-color-scheme: dark)')
.removeEventListener('change', applySystemTheme);
};
}, [selectedTheme]);
return resolvedTheme;
};
export default useTheme;
export const useThemeColor = (color: string) => {
const theme = useTheme();
const themeVariables = themes[theme];
// @ts-expect-error - themeVariables is a string indexable type
return themeVariables[color];
};
@@ -0,0 +1,3 @@
type TooltipPosition = 'top' | 'right' | 'bottom' | 'left';
export default TooltipPosition;
+2
View File
@@ -43,6 +43,7 @@ import {
faChevronCircleRight as fasChevronCircleRight, faChevronCircleRight as fasChevronCircleRight,
faChevronCircleUp as fasChevronCircleUp, faChevronCircleUp as fasChevronCircleUp,
faCircle as fasCircle, faCircle as fasCircle,
faCircleDown as fasCircleDown,
faCloud as fasCloud, faCloud as fasCloud,
faCloudDownloadAlt as fasCloudDownloadAlt, faCloudDownloadAlt as fasCloudDownloadAlt,
faCog as fasCog, faCog as fasCog,
@@ -141,6 +142,7 @@ export const CHECK_INDETERMINATE = fasMinus;
export const CHECK_CIRCLE = fasCheckCircle; export const CHECK_CIRCLE = fasCheckCircle;
export const CHECK_SQUARE = fasSquareCheck; export const CHECK_SQUARE = fasSquareCheck;
export const CIRCLE = fasCircle; export const CIRCLE = fasCircle;
export const CIRCLE_DOWN = fasCircleDown;
export const CIRCLE_OUTLINE = farCircle; export const CIRCLE_OUTLINE = farCircle;
export const CLEAR = fasTrashAlt; export const CLEAR = fasTrashAlt;
export const CLIPBOARD = fasCopy; export const CLIPBOARD = fasCopy;
@@ -7,7 +7,6 @@ export const PRIMARY = 'primary';
export const PURPLE = 'purple'; export const PURPLE = 'purple';
export const SUCCESS = 'success'; export const SUCCESS = 'success';
export const WARNING = 'warning'; export const WARNING = 'warning';
export const QUEUE = 'queue';
export const all = [ export const all = [
DANGER, DANGER,
@@ -19,5 +18,15 @@ export const all = [
PURPLE, PURPLE,
SUCCESS, SUCCESS,
WARNING, WARNING,
QUEUE ] as const;
];
export type Kind =
| 'danger'
| 'default'
| 'disabled'
| 'info'
| 'inverse'
| 'primary'
| 'purple'
| 'success'
| 'warning';
@@ -4,4 +4,6 @@ export const MEDIUM = 'medium';
export const LARGE = 'large'; export const LARGE = 'large';
export const EXTRA_LARGE = 'extraLarge'; export const EXTRA_LARGE = 'extraLarge';
export const all = [EXTRA_SMALL, SMALL, MEDIUM, LARGE, EXTRA_LARGE]; export const all = [EXTRA_SMALL, SMALL, MEDIUM, LARGE, EXTRA_LARGE] as const;
export type Size = 'extraSmall' | 'small' | 'medium' | 'large' | 'extraLarge';
+139 -3
View File
@@ -3,6 +3,7 @@ import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList'; import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import Link from 'Components/Link/Link'; import Link from 'Components/Link/Link';
import formatDateTime from 'Utilities/Date/formatDateTime';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import styles from './HistoryDetails.css'; import styles from './HistoryDetails.css';
@@ -10,7 +11,10 @@ function HistoryDetails(props) {
const { const {
indexer, indexer,
eventType, eventType,
data date,
data,
shortDateFormat,
timeFormat
} = props; } = props;
if (eventType === 'indexerQuery' || eventType === 'indexerRss') { if (eventType === 'indexerQuery' || eventType === 'indexerRss') {
@@ -21,7 +25,10 @@ function HistoryDetails(props) {
limit, limit,
offset, offset,
source, source,
url host,
url,
elapsedTime,
cached
} = data; } = data;
return ( return (
@@ -86,6 +93,15 @@ function HistoryDetails(props) {
null null
} }
{
data ?
<DescriptionListItem
title={translate('Host')}
data={host}
/> :
null
}
{ {
data ? data ?
<DescriptionListItem <DescriptionListItem
@@ -94,6 +110,24 @@ function HistoryDetails(props) {
/> : /> :
null null
} }
{
elapsedTime ?
<DescriptionListItem
title={translate('ElapsedTime')}
data={`${elapsedTime}ms${cached === '1' ? ' (cached)' : ''}`}
/> :
null
}
{
date ?
<DescriptionListItem
title={translate('Date')}
data={formatDateTime(date, shortDateFormat, timeFormat, { includeSeconds: true })}
/> :
null
}
</DescriptionList> </DescriptionList>
); );
} }
@@ -101,10 +135,19 @@ function HistoryDetails(props) {
if (eventType === 'releaseGrabbed') { if (eventType === 'releaseGrabbed') {
const { const {
source, source,
host,
grabTitle, grabTitle,
url url,
publishedDate,
infoUrl,
downloadClient,
downloadClientName,
elapsedTime,
grabMethod
} = data; } = data;
const downloadClientNameInfo = downloadClientName ?? downloadClient;
return ( return (
<DescriptionList> <DescriptionList>
{ {
@@ -125,6 +168,15 @@ function HistoryDetails(props) {
null null
} }
{
data ?
<DescriptionListItem
title={translate('Host')}
data={host}
/> :
null
}
{ {
data ? data ?
<DescriptionListItem <DescriptionListItem
@@ -134,6 +186,33 @@ function HistoryDetails(props) {
null null
} }
{
infoUrl ?
<DescriptionListItem
title={translate('InfoUrl')}
data={<Link to={infoUrl}>{infoUrl}</Link>}
/> :
null
}
{
publishedDate ?
<DescriptionListItem
title={translate('PublishedDate')}
data={formatDateTime(publishedDate, shortDateFormat, timeFormat, { includeSeconds: true })}
/> :
null
}
{
downloadClientNameInfo ?
<DescriptionListItem
title={translate('DownloadClient')}
data={downloadClientNameInfo}
/> :
null
}
{ {
data ? data ?
<DescriptionListItem <DescriptionListItem
@@ -142,11 +221,40 @@ function HistoryDetails(props) {
/> : /> :
null null
} }
{
elapsedTime ?
<DescriptionListItem
title={translate('ElapsedTime')}
data={`${elapsedTime}ms`}
/> :
null
}
{
grabMethod ?
<DescriptionListItem
title={translate('Redirected')}
data={grabMethod.toLowerCase() === 'redirect' ? translate('Yes') : translate('No')}
/> :
null
}
{
date ?
<DescriptionListItem
title={translate('Date')}
data={formatDateTime(date, shortDateFormat, timeFormat, { includeSeconds: true })}
/> :
null
}
</DescriptionList> </DescriptionList>
); );
} }
if (eventType === 'indexerAuth') { if (eventType === 'indexerAuth') {
const { elapsedTime } = data;
return ( return (
<DescriptionList <DescriptionList
descriptionClassName={styles.description} descriptionClassName={styles.description}
@@ -160,6 +268,24 @@ function HistoryDetails(props) {
/> : /> :
null null
} }
{
elapsedTime ?
<DescriptionListItem
title={translate('ElapsedTime')}
data={`${elapsedTime}ms`}
/> :
null
}
{
date ?
<DescriptionListItem
title={translate('Date')}
data={formatDateTime(date, shortDateFormat, timeFormat, { includeSeconds: true })}
/> :
null
}
</DescriptionList> </DescriptionList>
); );
} }
@@ -171,6 +297,15 @@ function HistoryDetails(props) {
title={translate('Name')} title={translate('Name')}
data={data.query} data={data.query}
/> />
{
date ?
<DescriptionListItem
title={translate('Date')}
data={formatDateTime(date, shortDateFormat, timeFormat, { includeSeconds: true })}
/> :
null
}
</DescriptionList> </DescriptionList>
); );
} }
@@ -178,6 +313,7 @@ function HistoryDetails(props) {
HistoryDetails.propTypes = { HistoryDetails.propTypes = {
indexer: PropTypes.object.isRequired, indexer: PropTypes.object.isRequired,
eventType: PropTypes.string.isRequired, eventType: PropTypes.string.isRequired,
date: PropTypes.string.isRequired,
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
shortDateFormat: PropTypes.string.isRequired, shortDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired timeFormat: PropTypes.string.isRequired
@@ -29,6 +29,7 @@ function HistoryDetailsModal(props) {
isOpen, isOpen,
eventType, eventType,
indexer, indexer,
date,
data, data,
shortDateFormat, shortDateFormat,
timeFormat, timeFormat,
@@ -49,6 +50,7 @@ function HistoryDetailsModal(props) {
<HistoryDetails <HistoryDetails
eventType={eventType} eventType={eventType}
indexer={indexer} indexer={indexer}
date={date}
data={data} data={data}
shortDateFormat={shortDateFormat} shortDateFormat={shortDateFormat}
timeFormat={timeFormat} timeFormat={timeFormat}
@@ -71,6 +73,7 @@ HistoryDetailsModal.propTypes = {
isOpen: PropTypes.bool.isRequired, isOpen: PropTypes.bool.isRequired,
eventType: PropTypes.string.isRequired, eventType: PropTypes.string.isRequired,
indexer: PropTypes.object.isRequired, indexer: PropTypes.object.isRequired,
date: PropTypes.string.isRequired,
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
shortDateFormat: PropTypes.string.isRequired, shortDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired, timeFormat: PropTypes.string.isRequired,
+14 -10
View File
@@ -20,21 +20,22 @@ function getIconName(eventType) {
} }
} }
function getIconKind(successful) { function getIconKind(successful, redirect) {
switch (successful) { if (redirect) {
case false: return kinds.INFO;
return kinds.DANGER; } else if (!successful) {
default: return kinds.DANGER;
return kinds.DEFAULT;
} }
return kinds.DEFAULT;
} }
function getTooltip(eventType, data, indexer) { function getTooltip(eventType, data, indexer, redirect) {
switch (eventType) { switch (eventType) {
case 'indexerQuery': case 'indexerQuery':
return `Query "${data.query}" sent to ${indexer.name}`; return `Query "${data.query}" sent to ${indexer.name}`;
case 'releaseGrabbed': case 'releaseGrabbed':
return `Release grabbed from ${indexer.name}`; return redirect ? `Release grabbed via redirect from ${indexer.name}` : `Release grabbed from ${indexer.name}`;
case 'indexerAuth': case 'indexerAuth':
return `Auth attempted for ${indexer.name}`; return `Auth attempted for ${indexer.name}`;
case 'indexerRss': case 'indexerRss':
@@ -45,9 +46,12 @@ function getTooltip(eventType, data, indexer) {
} }
function HistoryEventTypeCell({ eventType, successful, data, indexer }) { function HistoryEventTypeCell({ eventType, successful, data, indexer }) {
const { grabMethod } = data;
const redirect = grabMethod && grabMethod.toLowerCase() === 'redirect';
const iconName = getIconName(eventType); const iconName = getIconName(eventType);
const iconKind = getIconKind(successful); const iconKind = getIconKind(successful, redirect);
const tooltip = getTooltip(eventType, data, indexer); const tooltip = getTooltip(eventType, data, indexer, redirect);
return ( return (
<TableRowCell <TableRowCell
+19 -1
View File
@@ -257,6 +257,7 @@ class HistoryRow extends Component {
key={parameter.key} key={parameter.key}
title={parameter.title} title={parameter.title}
value={data[parameter.key]} value={data[parameter.key]}
queryType={data.queryType}
/> />
); );
} }
@@ -331,6 +332,21 @@ class HistoryRow extends Component {
); );
} }
if (name === 'host') {
return (
<TableRowCell
key={name}
className={styles.indexer}
>
{
data.host ?
data.host :
null
}
</TableRowCell>
);
}
if (name === 'elapsedTime') { if (name === 'elapsedTime') {
return ( return (
<TableRowCell <TableRowCell
@@ -355,8 +371,9 @@ class HistoryRow extends Component {
return ( return (
<RelativeDateCell <RelativeDateCell
key={name} key={name}
date={date}
className={styles.date} className={styles.date}
date={date}
includeSeconds={true}
/> />
); );
} }
@@ -393,6 +410,7 @@ class HistoryRow extends Component {
<HistoryDetailsModal <HistoryDetailsModal
isOpen={this.state.isDetailsModalOpen} isOpen={this.state.isDetailsModalOpen}
eventType={eventType} eventType={eventType}
date={date}
data={data} data={data}
indexer={indexer} indexer={indexer}
isMarkingAsFailed={isMarkingAsFailed} isMarkingAsFailed={isMarkingAsFailed}
+10 -2
View File
@@ -1,14 +1,16 @@
import React from 'react'; import React from 'react';
import Link from 'Components/Link/Link'; import Link from 'Components/Link/Link';
import { HistoryQueryType } from 'typings/History';
import styles from './HistoryRowParameter.css'; import styles from './HistoryRowParameter.css';
interface HistoryRowParameterProps { interface HistoryRowParameterProps {
title: string; title: string;
value: string; value: string;
queryType: HistoryQueryType;
} }
function HistoryRowParameter(props: HistoryRowParameterProps) { function HistoryRowParameter(props: HistoryRowParameterProps) {
const { title, value } = props; const { title, value, queryType } = props;
const type = title.toLowerCase(); const type = title.toLowerCase();
@@ -18,7 +20,13 @@ function HistoryRowParameter(props: HistoryRowParameterProps) {
link = <Link to={`https://imdb.com/title/${value}/`}>{value}</Link>; link = <Link to={`https://imdb.com/title/${value}/`}>{value}</Link>;
} else if (type === 'tmdb') { } else if (type === 'tmdb') {
link = ( link = (
<Link to={`https://www.themoviedb.org/movie/${value}`}>{value}</Link> <Link
to={`https://www.themoviedb.org/${
queryType === 'tvsearch' ? 'tv' : 'movie'
}/${value}`}
>
{value}
</Link>
); );
} else if (type === 'tvdb') { } else if (type === 'tvdb') {
link = ( link = (

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