Compare commits

...

236 Commits

Author SHA1 Message Date
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
342 changed files with 6131 additions and 3395 deletions

View File

@@ -2,11 +2,11 @@
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{
"name": "Prowlarr",
"image": "mcr.microsoft.com/devcontainers/dotnet:1-6.0",
"image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true,
"version": "16",
"version": "20",
"nvmVersion": "latest"
}
},

2
.vscode/launch.json vendored
View File

@@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build dotnet",
// 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": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console

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

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

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

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

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

View File

@@ -68,16 +68,16 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
## 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="/Logo/webstorm.svg" 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="/Logo/dottrace.svg" alt="dotTrace" width="32"> dotTrace](http://www.jetbrains.com/dottrace/)
* [<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="https://resources.jetbrains.com/storage/products/company/brand/logos/WebStorm_icon.png" alt="WebStorm" width="32"> WebStorm](http://www.jetbrains.com/webstorm/)
* [<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="https://resources.jetbrains.com/storage/products/company/brand/logos/dotTrace_icon.png" alt="dotTrace" width="32"> dotTrace](http://www.jetbrains.com/dottrace/)
### License
- [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)

View File

@@ -9,17 +9,17 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '1.25.4'
majorVersion: '2.0.1'
minorVersion: $[counter('minorVersion', 1)]
prowlarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(prowlarrVersion)'
sentryOrg: 'servarr'
sentryUrl: 'https://sentry.servarr.com'
dotnetVersion: '6.0.427'
dotnetVersion: '8.0.405'
nodeVersion: '20.X'
innoVersion: '6.2.2'
windowsImage: 'windows-2022'
linuxImage: 'ubuntu-20.04'
linuxImage: 'ubuntu-22.04'
macImage: 'macOS-13'
trigger:
@@ -106,7 +106,7 @@ stages:
echo "Extra platforms already enabled"
else
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
displayName: Enable Extra Platform Support
- bash: ./build.sh --backend --enable-extra-platforms
@@ -122,27 +122,23 @@ stages:
artifact: '$(osName)Backend'
displayName: Publish Backend
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
displayName: Publish win-x64 Test Package
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
displayName: Publish linux-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-x86/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'
- publish: '$(testsFolder)/net8.0/linux-musl-x64/publish'
artifact: linux-musl-x64-tests
displayName: Publish linux-musl-x64 Test Package
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
displayName: Publish freebsd-x64 Test Package
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
displayName: Publish osx-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
@@ -189,7 +185,7 @@ stages:
artifact: '$(osName)Frontend'
displayName: Publish Frontend
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- stage: Installer
dependsOn:
- Build_Backend
@@ -259,21 +255,21 @@ stages:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x64/net6.0
rootFolderOrFile: $(artifactsFolder)/win-x64/net8.0
- task: ArchiveFiles@2
displayName: Create win-x86 zip
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x86.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x86/net6.0
rootFolderOrFile: $(artifactsFolder)/win-x86/net8.0
- task: ArchiveFiles@2
displayName: Create osx-x64 app
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-x64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net6.0
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net8.0
- task: ArchiveFiles@2
displayName: Create osx-x64 tar
inputs:
@@ -281,14 +277,14 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64/net6.0
rootFolderOrFile: $(artifactsFolder)/osx-x64/net8.0
- task: ArchiveFiles@2
displayName: Create osx-arm64 app
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-arm64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net6.0
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net8.0
- task: ArchiveFiles@2
displayName: Create osx-arm64 tar
inputs:
@@ -296,7 +292,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net6.0
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-x64 tar
inputs:
@@ -304,7 +300,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x64/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-x64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-musl-x64 tar
inputs:
@@ -312,15 +308,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net6.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
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-arm tar
inputs:
@@ -328,7 +316,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-arm/net8.0
- task: ArchiveFiles@2
displayName: Create linux-musl-arm tar
inputs:
@@ -336,7 +324,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net8.0
- task: ArchiveFiles@2
displayName: Create linux-arm64 tar
inputs:
@@ -344,7 +332,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-musl-arm64 tar
inputs:
@@ -352,7 +340,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net8.0
- task: ArchiveFiles@2
displayName: Create freebsd-x64 tar
inputs:
@@ -360,7 +348,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/freebsd-x64/net6.0
rootFolderOrFile: $(artifactsFolder)/freebsd-x64/net8.0
- publish: $(Build.ArtifactStagingDirectory)
artifact: 'Packages'
displayName: Publish Packages
@@ -391,7 +379,7 @@ stages:
SENTRY_AUTH_TOKEN: $(sentryAuthTokenServarr)
SENTRY_ORG: $(sentryOrg)
SENTRY_URL: $(sentryUrl)
- stage: Unit_Test
displayName: Unit Tests
dependsOn: Build_Backend
@@ -476,6 +464,7 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Unit Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: ne(variables['testName'], 'freebsd-x64')
- job: Unit_Docker
displayName: Unit Docker
@@ -487,29 +476,19 @@ stages:
testName: 'Musl Net Core'
artifactName: linux-musl-x64-tests
containerImage: ghcr.io/servarr/testimages:alpine
linux-x86:
testName: 'linux-x86'
artifactName: linux-x86-tests
containerImage: ghcr.io/servarr/testimages:linux-x86
pool:
vmImage: ${{ variables.linuxImage }}
container: $[ variables['containerImage'] ]
timeoutInMinutes: 10
steps:
- task: UseDotNet@2
displayName: 'Install .NET'
inputs:
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
- task: DownloadPipelineArtifact@2
displayName: Download Test Artifact
@@ -532,7 +511,8 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Unit Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
- job: Unit_LinuxCore_Postgres14
displayName: Unit Native LinuxCore with Postgres14 Database
dependsOn: Prepare
@@ -549,7 +529,7 @@ stages:
vmImage: ${{ variables.linuxImage }}
timeoutInMinutes: 10
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
@@ -585,6 +565,7 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'LinuxCore Postgres14 Unit Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
- job: Unit_LinuxCore_Postgres15
displayName: Unit Native LinuxCore with Postgres15 Database
@@ -597,12 +578,12 @@ stages:
Prowlarr__Postgres__Port: '5432'
Prowlarr__Postgres__User: 'prowlarr'
Prowlarr__Postgres__Password: 'prowlarr'
pool:
vmImage: ${{ variables.linuxImage }}
timeoutInMinutes: 10
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
@@ -638,6 +619,7 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'LinuxCore Postgres15 Unit Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
- stage: Integration
displayName: Integration
@@ -681,7 +663,7 @@ stages:
pool:
vmImage: $(imageName)
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
@@ -703,7 +685,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -720,6 +702,7 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Integration Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
displayName: Publish Test Results
- job: Integration_LinuxCore_Postgres14
@@ -757,7 +740,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -782,6 +765,7 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'Integration LinuxCore Postgres14 Database Integration Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
displayName: Publish Test Results
@@ -820,7 +804,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -845,6 +829,7 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'Integration LinuxCore Postgres15 Database Integration Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
displayName: Publish Test Results
- job: Integration_FreeBSD
@@ -891,6 +876,7 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'FreeBSD Integration Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: false
displayName: Publish Test Results
- job: Integration_Docker
@@ -904,29 +890,18 @@ stages:
artifactName: linux-musl-x64-tests
containerImage: ghcr.io/servarr/testimages:alpine
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:
vmImage: ${{ variables.linuxImage }}
container: $[ variables['containerImage'] ]
timeoutInMinutes: 15
steps:
- task: UseDotNet@2
displayName: 'Install .NET'
inputs:
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
- task: DownloadPipelineArtifact@2
displayName: Download Test Artifact
@@ -943,7 +918,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -960,12 +935,13 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Integration Tests'
failTaskOnFailedTests: true
failTaskOnMissingResultsFile: true
displayName: Publish Test Results
- stage: Automation
displayName: Automation
dependsOn: Packages
jobs:
- job: Automation
strategy:
@@ -991,7 +967,7 @@ stages:
pool:
vmImage: $(imageName)
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
@@ -1013,7 +989,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -1041,6 +1017,7 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(osName) Automation Tests'
failTaskOnFailedTests: $(failBuild)
failTaskOnMissingResultsFile: $(failBuild)
displayName: Publish Test Results
- stage: Analyze
@@ -1116,7 +1093,7 @@ stages:
- checkout: self
submodules: true
persistCredentials: true
fetchDepth: 1
fetchDepth: 1
- bash: ./docs.sh Windows
displayName: Create openapi.json
- bash: |
@@ -1169,12 +1146,12 @@ stages:
submodules: true
- powershell: Set-Service SCardSvr -StartupType Manual
displayName: Enable Windows Test Service
- task: SonarCloudPrepare@2
- task: SonarCloudPrepare@3
condition: eq(variables['System.PullRequest.IsFork'], 'False')
inputs:
SonarCloud: 'SonarCloud'
organization: 'prowlarr'
scannerMode: 'MSBuild'
scannerMode: 'dotnet'
projectKey: 'Prowlarr_Prowlarr'
projectName: 'Prowlarr'
projectVersion: '$(prowlarrVersion)'
@@ -1184,10 +1161,10 @@ stages:
sonar.cs.opencover.reportsPaths=$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml
sonar.cs.nunit.reportsPaths=$(Build.SourcesDirectory)/TestResult.xml
- bash: |
./build.sh --backend -f net6.0 -r win-x64
TEST_DIR=_tests/net6.0/win-x64/publish/ ./test.sh Windows Unit Coverage
./build.sh --backend -f net8.0 -r win-x64
TEST_DIR=_tests/net8.0/win-x64/publish/ ./test.sh Windows Unit Coverage
displayName: Coverage Unit Tests
- task: SonarCloudAnalyze@2
- task: SonarCloudAnalyze@3
condition: eq(variables['System.PullRequest.IsFork'], 'False')
displayName: Publish SonarCloud Results
- task: reportgenerator@5
@@ -1228,4 +1205,3 @@ stages:
DISCORDCHANNELID: $(discordChannelId)
DISCORDWEBHOOKKEY: $(discordWebhookKey)
DISCORDTHREADID: $(discordThreadId)

View File

@@ -33,14 +33,14 @@ EnableExtraPlatformsInSDK()
echo "Extra platforms already enabled"
else
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
}
EnableExtraPlatforms()
{
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
}
@@ -79,9 +79,9 @@ Build()
if [[ -z "$RID" || -z "$FRAMEWORK" ]];
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
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
ProgressEnd 'Build'
@@ -137,7 +137,7 @@ PackageLinux()
echo "Adding Prowlarr.Mono to UpdatePackage"
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/libMonoPosixHelper.* $folder/Prowlarr.Update
fi
@@ -165,7 +165,7 @@ PackageMacOS()
echo "Adding Prowlarr.Mono to UpdatePackage"
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/libMonoPosixHelper.* $folder/Prowlarr.Update
fi
@@ -377,15 +377,14 @@ then
Build
if [[ -z "$RID" || -z "$FRAMEWORK" ]];
then
PackageTests "net6.0" "win-x64"
PackageTests "net6.0" "win-x86"
PackageTests "net6.0" "linux-x64"
PackageTests "net6.0" "linux-musl-x64"
PackageTests "net6.0" "osx-x64"
PackageTests "net8.0" "win-x64"
PackageTests "net8.0" "win-x86"
PackageTests "net8.0" "linux-x64"
PackageTests "net8.0" "linux-musl-x64"
PackageTests "net8.0" "osx-x64"
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then
PackageTests "net6.0" "freebsd-x64"
PackageTests "net6.0" "linux-x86"
PackageTests "net8.0" "freebsd-x64"
fi
else
PackageTests "$FRAMEWORK" "$RID"
@@ -413,20 +412,19 @@ then
if [[ -z "$RID" || -z "$FRAMEWORK" ]];
then
Package "net6.0" "win-x64"
Package "net6.0" "win-x86"
Package "net6.0" "linux-x64"
Package "net6.0" "linux-musl-x64"
Package "net6.0" "linux-arm64"
Package "net6.0" "linux-musl-arm64"
Package "net6.0" "linux-arm"
Package "net6.0" "linux-musl-arm"
Package "net6.0" "osx-x64"
Package "net6.0" "osx-arm64"
Package "net8.0" "win-x64"
Package "net8.0" "win-x86"
Package "net8.0" "linux-x64"
Package "net8.0" "linux-musl-x64"
Package "net8.0" "linux-arm64"
Package "net8.0" "linux-musl-arm64"
Package "net8.0" "linux-arm"
Package "net8.0" "linux-musl-arm"
Package "net8.0" "osx-x64"
Package "net8.0" "osx-arm64"
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then
Package "net6.0" "freebsd-x64"
Package "net6.0" "linux-x86"
Package "net8.0" "freebsd-x64"
fi
else
Package "$FRAMEWORK" "$RID"
@@ -436,7 +434,7 @@ fi
if [ "$INSTALLER" = "YES" ];
then
InstallInno
BuildInstaller "net6.0" "win-x64"
BuildInstaller "net6.0" "win-x86"
BuildInstaller "net8.0" "win-x64"
BuildInstaller "net8.0" "win-x86"
RemoveInno
fi

13
docs.sh
View File

@@ -1,17 +1,18 @@
#!/bin/bash
set -e
FRAMEWORK="net6.0"
FRAMEWORK="net8.0"
PLATFORM=$1
ARCHITECTURE="${2:-x64}"
if [ "$PLATFORM" = "Windows" ]; then
RUNTIME="win-x64"
RUNTIME="win-$ARCHITECTURE"
elif [ "$PLATFORM" = "Linux" ]; then
RUNTIME="linux-x64"
RUNTIME="linux-$ARCHITECTURE"
elif [ "$PLATFORM" = "Mac" ]; then
RUNTIME="osx-x64"
RUNTIME="osx-$ARCHITECTURE"
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
fi
@@ -37,7 +38,7 @@ dotnet clean $slnFile -c Release
dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids
dotnet new tool-manifest
dotnet tool install --version 6.6.2 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/$FRAMEWORK/$RUNTIME/$application" v1 &

View File

@@ -25,6 +25,7 @@ module.exports = (env) => {
const config = {
mode: isProduction ? 'production' : 'development',
devtool: isProduction ? 'source-map' : 'eval-source-map',
target: 'web',
stats: {
children: false
@@ -169,7 +170,7 @@ module.exports = (env) => {
loose: true,
debug: false,
useBuiltIns: 'entry',
corejs: 3
corejs: '3.42'
}
]
]

View File

@@ -20,6 +20,8 @@ import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue';
import TextInput from './TextInput';
import styles from './EnhancedSelectInput.css';
const MINIMUM_DISTANCE_FROM_EDGE = 10;
function isArrowKey(keyCode) {
return keyCode === keyCodes.UP_ARROW || keyCode === keyCodes.DOWN_ARROW;
}
@@ -137,18 +139,9 @@ class EnhancedSelectInput extends Component {
// Listeners
onComputeMaxHeight = (data) => {
const {
top,
bottom
} = data.offsets.reference;
const windowHeight = window.innerHeight;
if ((/^botton/).test(data.placement)) {
data.styles.maxHeight = windowHeight - bottom;
} else {
data.styles.maxHeight = top;
}
data.styles.maxHeight = windowHeight - MINIMUM_DISTANCE_FROM_EDGE;
return data;
};
@@ -460,6 +453,10 @@ class EnhancedSelectInput extends Component {
order: 851,
enabled: true,
fn: this.onComputeMaxHeight
},
preventOverflow: {
enabled: true,
boundariesElement: 'viewport'
}
}}
>

View File

@@ -24,6 +24,7 @@
composes: link;
padding: 10px 24px;
padding-left: 35px;
}
.isActiveLink {
@@ -41,10 +42,6 @@
text-align: center;
}
.noIcon {
margin-left: 25px;
}
.status {
float: right;
}

View File

@@ -8,7 +8,6 @@ interface CssExports {
'isActiveParentLink': string;
'item': string;
'link': string;
'noIcon': string;
'status': string;
}
export const cssExports: CssExports;

View File

@@ -63,9 +63,7 @@ class PageSidebarItem extends Component {
</span>
}
<span className={isChildItem ? styles.noIcon : null}>
{typeof title === 'function' ? title() : title}
</span>
{typeof title === 'function' ? title() : title}
{
!!StatusComponent &&

View File

@@ -22,11 +22,14 @@
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
height: 24px;
}
.label {
padding: 0 3px;
max-width: 100%;
max-height: 100%;
color: var(--toolbarLabelColor);
font-size: $extraSmallFontSize;
line-height: calc($extraSmallFontSize + 1px);

View File

@@ -23,6 +23,7 @@ function PageToolbarButton(props) {
isDisabled && styles.isDisabled
)}
isDisabled={isDisabled || isSpinning}
title={label}
{...otherProps}
>
<Icon

View File

@@ -65,17 +65,30 @@ class VirtualTable extends Component {
if (this._grid && scrollTop !== undefined && scrollTop !== 0 && !scrollRestored) {
this.setState({ scrollRestored: true });
this._grid.scrollToPosition({ scrollTop });
this._gridScrollToPosition({ scrollTop });
}
if (scrollIndex != null && scrollIndex !== prevProps.scrollIndex) {
this._grid.scrollToCell({
this._gridScrollToCell({
rowIndex: scrollIndex,
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

View File

@@ -257,6 +257,7 @@ class HistoryRow extends Component {
key={parameter.key}
title={parameter.title}
value={data[parameter.key]}
queryType={data.queryType}
/>
);
}

View File

@@ -1,14 +1,16 @@
import React from 'react';
import Link from 'Components/Link/Link';
import { HistoryQueryType } from 'typings/History';
import styles from './HistoryRowParameter.css';
interface HistoryRowParameterProps {
title: string;
value: string;
queryType: HistoryQueryType;
}
function HistoryRowParameter(props: HistoryRowParameterProps) {
const { title, value } = props;
const { title, value, queryType } = props;
const type = title.toLowerCase();
@@ -18,7 +20,13 @@ function HistoryRowParameter(props: HistoryRowParameterProps) {
link = <Link to={`https://imdb.com/title/${value}/`}>{value}</Link>;
} else if (type === 'tmdb') {
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') {
link = (

View File

@@ -68,6 +68,7 @@ function IndexerHistoryRow(props: IndexerHistoryRowProps) {
key={parameter.key}
title={parameter.title}
value={data[parameter.key as keyof HistoryData].toString()}
queryType={data.queryType}
/>
);
})}

View File

@@ -21,7 +21,7 @@ function createMapStateToProps() {
) => {
// If a release is deleted this selector may fire before the parent
// selecors, which will result in an undefined release, if that happens
// selectors, which will result in an undefined release, if that happens
// we want to return early here and again in the render function to avoid
// trying to show a release that has no information available.

View File

@@ -30,7 +30,9 @@ export const authenticationMethodOptions = [
key: 'basic',
get value() {
return translate('AuthBasic');
}
},
isDisabled: true,
isHidden: true
},
{
key: 'forms',

View File

@@ -419,7 +419,7 @@ export const reducers = createHandleActions({
const items = newState.items;
const index = items.findIndex((item) => item.guid === guid);
// Don't try to update if there isnt a matching item (the user closed the modal)
// Don't try to update if there isn't a matching item (the user closed the modal)
if (index >= 0) {
const item = Object.assign({}, items[index], payload);

View File

@@ -2,8 +2,8 @@ import { createSelector } from 'reselect';
import { isCommandExecuting } from 'Utilities/Command';
import createCommandSelector from './createCommandSelector';
function createCommandExecutingSelector(name: string, contraints = {}) {
return createSelector(createCommandSelector(name, contraints), (command) => {
function createCommandExecutingSelector(name: string, constraints = {}) {
return createSelector(createCommandSelector(name, constraints), (command) => {
return isCommandExecuting(command);
});
}

View File

@@ -2,9 +2,9 @@ import { createSelector } from 'reselect';
import { findCommand } from 'Utilities/Command';
import createCommandsSelector from './createCommandsSelector';
function createCommandSelector(name: string, contraints = {}) {
function createCommandSelector(name: string, constraints = {}) {
return createSelector(createCommandsSelector(), (commands) => {
return findCommand(commands, { name, ...contraints });
return findCommand(commands, { name, ...constraints });
});
}

View File

@@ -270,7 +270,7 @@ function Updates() {
{generalSettingsError ? (
<Alert kind={kinds.DANGER}>
{translate('FailedToUpdateSettings')}
{translate('FailedToFetchSettings')}
</Alert>
) : null}

View File

@@ -17,7 +17,7 @@ export async function fetchTranslations(): Promise<boolean> {
translations = data.Strings;
resolve(true);
} catch (error) {
} catch {
resolve(false);
}
});

View File

@@ -1,5 +1,12 @@
import ModelBase from 'App/ModelBase';
export type HistoryQueryType =
| 'search'
| 'tvsearch'
| 'movie'
| 'book'
| 'music';
export interface HistoryData {
source: string;
host: string;
@@ -7,7 +14,7 @@ export interface HistoryData {
offset: number;
elapsedTime: number;
query: string;
queryType: string;
queryType: HistoryQueryType;
}
interface History extends ModelBase {

5
global.json Normal file
View File

@@ -0,0 +1,5 @@
{
"sdk": {
"version": "8.0.405"
}
}

View File

@@ -23,17 +23,17 @@
"defaults"
],
"dependencies": {
"@fortawesome/fontawesome-free": "6.6.0",
"@fortawesome/fontawesome-svg-core": "6.6.0",
"@fortawesome/free-regular-svg-icons": "6.6.0",
"@fortawesome/free-solid-svg-icons": "6.6.0",
"@fortawesome/fontawesome-free": "6.7.2",
"@fortawesome/fontawesome-svg-core": "6.7.2",
"@fortawesome/free-regular-svg-icons": "6.7.2",
"@fortawesome/free-solid-svg-icons": "6.7.2",
"@fortawesome/react-fontawesome": "0.2.2",
"@juggle/resize-observer": "3.4.0",
"@microsoft/signalr": "6.0.25",
"@microsoft/signalr": "8.0.7",
"@sentry/browser": "7.119.1",
"@sentry/integrations": "7.119.1",
"@types/node": "20.16.11",
"@types/react": "18.2.79",
"@types/react": "18.3.21",
"@types/react-dom": "18.2.25",
"chart.js": "4.4.4",
"classnames": "2.5.1",
@@ -71,9 +71,9 @@
"react-router-dom": "5.2.0",
"react-tabs": "4.3.0",
"react-text-truncate": "0.19.0",
"react-use-measure": "2.1.1",
"react-virtualized": "9.21.1",
"react-window": "1.8.10",
"react-use-measure": "2.1.7",
"react-virtualized": "9.22.6",
"react-window": "1.8.11",
"redux": "4.2.1",
"redux-actions": "2.6.5",
"redux-batched-actions": "0.5.0",
@@ -81,30 +81,30 @@
"redux-thunk": "2.4.2",
"reselect": "4.1.8",
"stacktrace-js": "2.0.2",
"typescript": "5.1.6"
"typescript": "5.7.2"
},
"devDependencies": {
"@babel/core": "7.25.8",
"@babel/eslint-parser": "7.25.8",
"@babel/plugin-proposal-export-default-from": "7.25.8",
"@babel/core": "7.27.1",
"@babel/eslint-parser": "7.27.1",
"@babel/plugin-proposal-export-default-from": "7.27.1",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@babel/preset-env": "7.25.8",
"@babel/preset-react": "7.25.7",
"@babel/preset-typescript": "7.25.7",
"@babel/preset-env": "7.27.2",
"@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1",
"@types/lodash": "4.14.195",
"@types/react-document-title": "2.0.10",
"@types/react-router-dom": "5.3.3",
"@types/react-text-truncate": "0.19.0",
"@types/react-window": "1.8.8",
"@types/webpack-livereload-plugin": "2.3.6",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"@typescript-eslint/eslint-plugin": "8.18.1",
"@typescript-eslint/parser": "8.18.1",
"are-you-es5": "2.1.2",
"autoprefixer": "10.4.20",
"babel-loader": "9.2.1",
"babel-plugin-inline-classnames": "2.0.1",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
"core-js": "3.38.1",
"core-js": "3.42.0",
"css-loader": "6.7.3",
"css-modules-typescript-loader": "4.0.1",
"eslint": "8.57.1",

View File

@@ -99,13 +99,6 @@
<RootNamespace Condition="'$(ProwlarrProject)'=='true'">$(MSBuildProjectName.Replace('Prowlarr','NzbDrone'))</RootNamespace>
</PropertyGroup>
<ItemGroup Condition="'$(TestProject)'!='true'">
<!-- Annotates .NET assemblies with repository information including SHA -->
<!-- Sentry uses this to link directly to GitHub at the exact version/file/line -->
<!-- This is built-in on .NET 8 and can be removed once the project is updated -->
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
<!-- Sentry specific configuration: Only in Release mode -->
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<!-- https://docs.sentry.io/platforms/dotnet/configuration/msbuild/ -->
@@ -136,7 +129,7 @@
<PackageReference Include="NunitXml.TestLogger" Version="3.0.131" />
</ItemGroup>
<ItemGroup Condition="'$(TestProject)'=='true' and '$(TargetFramework)'=='net6.0'">
<ItemGroup Condition="'$(TestProject)'=='true' and '$(TargetFramework)'=='net8.0'">
<PackageReference Include="coverlet.collector" Version="3.0.4-preview.27.ge7cb7c3b40" />
</ItemGroup>
@@ -148,9 +141,9 @@
<!-- Set up stylecop -->
<ItemGroup Condition="'$(ProwlarrProject)'=='true' and '$(EnableAnalyzers)'!='false'">
<!-- StyleCop analysis -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PackageReference Include="StyleCop.Analyzers.Unstable" Version="1.2.0.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<AdditionalFiles Include="$(SolutionDir)stylecop.json" />
</ItemGroup>
@@ -221,7 +214,7 @@
<PropertyGroup Condition="'$(IsOSX)' == 'true' and
'$(RuntimeIdentifier)' == ''">
<_UsingDefaultRuntimeIdentifier>true</_UsingDefaultRuntimeIdentifier>
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
<RuntimeIdentifier>osx-$(Architecture)</RuntimeIdentifier>
</PropertyGroup>
</Project>

View File

@@ -39,15 +39,16 @@ namespace NzbDrone.Automation.Test
var service = ChromeDriverService.CreateDefaultService();
// Timeout as windows automation tests seem to take alot longer to get going
driver = new ChromeDriver(service, options, new TimeSpan(0, 3, 0));
driver = new ChromeDriver(service, options, TimeSpan.FromMinutes(3));
driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080);
driver.Manage().Window.FullScreen();
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), null);
_runner.KillAll();
_runner.Start(true);
driver.Url = "http://localhost:9696";
driver.Navigate().GoToUrl("http://localhost:9696");
var page = new PageBase(driver);
page.WaitForNoSpinner();
@@ -67,7 +68,7 @@ namespace NzbDrone.Automation.Test
{
try
{
var image = ((ITakesScreenshot)driver).GetScreenshot();
var image = (driver as ITakesScreenshot).GetScreenshot();
image.SaveAsFile($"./{name}_test_screenshot.png", ScreenshotImageFormat.Png);
}
catch (Exception ex)

View File

@@ -7,12 +7,11 @@ namespace NzbDrone.Automation.Test.PageModel
{
public class PageBase
{
private readonly WebDriver _driver;
private readonly IWebDriver _driver;
public PageBase(WebDriver driver)
public PageBase(IWebDriver driver)
{
_driver = driver;
driver.Manage().Window.Maximize();
}
public IWebElement FindByClass(string className, int timeout = 5)

View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Selenium.Support" Version="4.1.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="99.0.4844.5100" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="134.0.6998.16500" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Test.Common\Prowlarr.Test.Common.csproj" />

View File

@@ -10,13 +10,13 @@ namespace NzbDrone.Common.Test.EnvironmentInfo
[Test]
public void should_return_version()
{
BuildInfo.Version.Major.Should().BeOneOf(0, 1, 10);
BuildInfo.Version.Major.Should().BeOneOf(0, 2, 10);
}
[Test]
public void should_get_branch()
{
BuildInfo.Branch.Should().NotBe("unknow");
BuildInfo.Branch.Should().NotBe("unknown");
BuildInfo.Branch.Should().NotBeNullOrWhiteSpace();
}
}

View File

@@ -21,9 +21,28 @@ namespace NzbDrone.Common.Test.ExtensionTests
[TestCase("1.2.3.4")]
[TestCase("172.55.0.1")]
[TestCase("192.55.0.1")]
[TestCase("100.64.0.1")]
[TestCase("100.127.255.254")]
public void should_return_false_for_public_ip_address(string ipAddress)
{
IPAddress.Parse(ipAddress).IsLocalAddress().Should().BeFalse();
}
[TestCase("100.64.0.1")]
[TestCase("100.127.255.254")]
[TestCase("100.100.100.100")]
public void should_return_true_for_cgnat_ip_address(string ipAddress)
{
IPAddress.Parse(ipAddress).IsCgnatIpAddress().Should().BeTrue();
}
[TestCase("1.2.3.4")]
[TestCase("192.168.5.1")]
[TestCase("100.63.255.255")]
[TestCase("100.128.0.0")]
public void should_return_false_for_non_cgnat_ip_address(string ipAddress)
{
IPAddress.Parse(ipAddress).IsCgnatIpAddress().Should().BeFalse();
}
}
}

View File

@@ -35,7 +35,7 @@ namespace NzbDrone.Common.Test.Http
private string _httpBinHost;
private string _httpBinHost2;
private System.Net.Http.HttpClient _httpClient = new ();
private System.Net.Http.HttpClient _httpClient = new();
[OneTimeSetUp]
public void FixtureSetUp()

View File

@@ -16,6 +16,8 @@ namespace NzbDrone.Common.Test.Http
[TestCase("Readarr/1.0.0.2300 (ubuntu 20.04)", "Readarr")]
[TestCase("Sonarr/3.0.6.9999 (ubuntu 20.04)", "Sonarr")]
[TestCase("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", "Other")]
[TestCase("appbrr", "appbrr")]
[TestCase(" appbrr ", "appbrr")]
public void should_parse_user_agent(string userAgent, string parsedAgent)
{
UserAgentParser.ParseSource(userAgent).Should().Be(parsedAgent);

View File

@@ -30,6 +30,7 @@ namespace NzbDrone.Common.Test.InstrumentationTests
[TestCase(@"https://anthelion.me/api.php?api_key=2b51db35e1910123321025a12b9933d2&o=json&t=movie&q=&tmdb=&imdb=&cat=&limit=100&offset=0")]
[TestCase(@"https://avistaz.to/api/v1/jackett/auth: username=mySecret&password=mySecret&pid=mySecret")]
[TestCase(@"https://www.sharewood.tv/api/2b51db35e1910123321025a12b9933d2/last-torrents")]
[TestCase(@"https://example.org/rss/torrents?rsskey=2b51db35e1910123321025a12b9933d2&search=")]
// Indexer and Download Client Responses

View File

@@ -133,11 +133,16 @@ namespace NzbDrone.Common.Test
[TestCase(@"C:\test\", @"C:\Test\mydir")]
[TestCase(@"C:\test", @"C:\Test\mydir\")]
public void path_should_be_parent_on_windows_only(string parentPath, string childPath)
public void windows_path_should_be_parent(string parentPath, string childPath)
{
var expectedResult = OsInfo.IsWindows;
parentPath.IsParentPath(childPath).Should().Be(true);
}
parentPath.IsParentPath(childPath).Should().Be(expectedResult);
[TestCase("/test", "/test/mydir/")]
[TestCase("/test/", "/test/mydir")]
public void posix_path_should_be_parent(string parentPath, string childPath)
{
parentPath.IsParentPath(childPath).Should().Be(true);
}
[TestCase(@"C:\Test\mydir", @"C:\Test")]
@@ -145,20 +150,57 @@ namespace NzbDrone.Common.Test
[TestCase(@"C:\", null)]
[TestCase(@"\\server\share", null)]
[TestCase(@"\\server\share\test", @"\\server\share")]
public void path_should_return_parent_windows(string path, string parentPath)
public void windows_path_should_return_parent(string path, string parentPath)
{
WindowsOnly();
path.GetParentPath().Should().Be(parentPath);
}
[TestCase(@"/", null)]
[TestCase(@"/test", "/")]
public void path_should_return_parent_mono(string path, string parentPath)
[TestCase(@"/test/tv", "/test")]
public void unix_path_should_return_parent(string path, string parentPath)
{
PosixOnly();
path.GetParentPath().Should().Be(parentPath);
}
[TestCase(@"C:\Test\mydir", "Test")]
[TestCase(@"C:\Test\", @"C:\")]
[TestCase(@"C:\Test", @"C:\")]
[TestCase(@"C:\", null)]
[TestCase(@"\\server\share", null)]
[TestCase(@"\\server\share\test", @"\\server\share")]
public void path_should_return_parent_name_windows(string path, string parentPath)
{
path.GetParentName().Should().Be(parentPath);
}
[TestCase(@"/", null)]
[TestCase(@"/test", "/")]
[TestCase(@"/test/tv", "test")]
public void path_should_return_parent_name_mono(string path, string parentPath)
{
path.GetParentName().Should().Be(parentPath);
}
[TestCase(@"C:\Test\mydir", "mydir")]
[TestCase(@"C:\Test\", "Test")]
[TestCase(@"C:\Test", "Test")]
[TestCase(@"C:\", "C:\\")]
[TestCase(@"\\server\share", @"\\server\share")]
[TestCase(@"\\server\share\test", "test")]
public void path_should_return_directory_name_windows(string path, string parentPath)
{
path.GetDirectoryName().Should().Be(parentPath);
}
[TestCase(@"/", "/")]
[TestCase(@"/test", "test")]
[TestCase(@"/test/tv", "tv")]
public void path_should_return_directory_name_mono(string path, string parentPath)
{
path.GetDirectoryName().Should().Be(parentPath);
}
[Test]
public void path_should_return_parent_for_oversized_path()
{
@@ -166,7 +208,7 @@ namespace NzbDrone.Common.Test
// This test will fail on Windows if long path support is not enabled: https://www.howtogeek.com/266621/how-to-make-windows-10-accept-file-paths-over-260-characters/
// It will also fail if the app isn't configured to use long path (such as resharper): https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/
var path = @"C:\media\2e168617-f2ae-43fb-b88c-3663af1c8eea\downloads\sabnzbd\nzbdrone\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories".AsOsAgnostic();
var path = @"C:\media\2e168617-f2ae-43fb-b88c-3663af1c8eea\downloads\sabnzbd\nzbdrone\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories".AsOsAgnostic();
var parentPath = @"C:\media\2e168617-f2ae-43fb-b88c-3663af1c8eea\downloads\sabnzbd\nzbdrone\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing\With.Alot.Of.Nested.Directories\Some.Real.Big.Thing".AsOsAgnostic();
path.GetParentPath().Should().Be(parentPath);
@@ -350,5 +392,46 @@ namespace NzbDrone.Common.Test
PosixOnly();
path.AsOsAgnostic().IsPathValid(PathValidationType.CurrentOs).Should().BeFalse();
}
[TestCase(@"C:\", @"C:\")]
[TestCase(@"C:\\", @"C:\")]
[TestCase(@"C:\Test", @"C:\Test")]
[TestCase(@"C:\Test\", @"C:\Test")]
[TestCase(@"\\server\share", @"\\server\share")]
[TestCase(@"\\server\share\", @"\\server\share")]
public void windows_path_should_return_clean_path(string path, string cleanPath)
{
path.GetCleanPath().Should().Be(cleanPath);
}
[TestCase("/", "/")]
[TestCase("//", "/")]
[TestCase("/test", "/test")]
[TestCase("/test/", "/test")]
[TestCase("/test//", "/test")]
public void unix_path_should_return_clean_path(string path, string cleanPath)
{
path.GetCleanPath().Should().Be(cleanPath);
}
[TestCase(@"C:\Test\", @"C:\Test\Series Title", "Series Title")]
[TestCase(@"C:\Test\", @"C:\Test\Collection\Series Title", @"Collection\Series Title")]
[TestCase(@"C:\Test\mydir\", @"C:\Test\mydir\Collection\Series Title", @"Collection\Series Title")]
[TestCase(@"\\server\share", @"\\server\share\Series Title", "Series Title")]
[TestCase(@"\\server\share\mydir\", @"\\server\share\mydir\/Collection\Series Title", @"Collection\Series Title")]
public void windows_path_should_return_relative_path(string parentPath, string childPath, string relativePath)
{
parentPath.GetRelativePath(childPath).Should().Be(relativePath);
}
[TestCase(@"/test", "/test/Series Title", "Series Title")]
[TestCase(@"/test/", "/test/Collection/Series Title", "Collection/Series Title")]
[TestCase(@"/test/mydir", "/test/mydir/Series Title", "Series Title")]
[TestCase(@"/test/mydir/", "/test/mydir/Collection/Series Title", "Collection/Series Title")]
[TestCase(@"/test/mydir/", @"/test/mydir/\Collection/Series Title", "Collection/Series Title")]
public void unix_path_should_return_relative_path(string parentPath, string childPath, string relativePath)
{
parentPath.GetRelativePath(childPath).Should().Be(relativePath);
}
}
}

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Host\Prowlarr.Host.csproj" />

View File

@@ -42,17 +42,18 @@ namespace NzbDrone.Common
public void CreateZip(string path, IEnumerable<string> files)
{
using (var zipFile = ZipFile.Create(path))
_logger.Debug("Creating archive {0}", path);
using var zipFile = ZipFile.Create(path);
zipFile.BeginUpdate();
foreach (var file in files)
{
zipFile.BeginUpdate();
foreach (var file in files)
{
zipFile.Add(file, Path.GetFileName(file));
}
zipFile.CommitUpdate();
zipFile.Add(file, Path.GetFileName(file));
}
zipFile.CommitUpdate();
}
private void ExtractZip(string compressedFile, string destination)

View File

@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Runtime.Serialization;
namespace NzbDrone.Common.Disk
{
@@ -24,10 +23,5 @@ namespace NzbDrone.Common.Disk
: base(message, innerException)
{
}
protected DestinationAlreadyExistsException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

View File

@@ -189,6 +189,25 @@ namespace NzbDrone.Common.Disk
}
var fi = new FileInfo(path);
try
{
// If the file is a symlink, resolve the target path and get the size of the target file.
if (fi.Attributes.HasFlag(FileAttributes.ReparsePoint))
{
var targetPath = fi.ResolveLinkTarget(true)?.FullName;
if (targetPath != null)
{
fi = new FileInfo(targetPath);
}
}
}
catch (IOException ex)
{
Logger.Trace(ex, "Unable to resolve symlink target for {0}", path);
}
return fi.Length;
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using NzbDrone.Common.Extensions;
namespace NzbDrone.Common.Disk
@@ -9,6 +10,8 @@ namespace NzbDrone.Common.Disk
private readonly string _path;
private readonly OsPathKind _kind;
private static readonly Regex UncPathRegex = new Regex(@"(?<unc>^\\\\(?:\?\\UNC\\)?[^\\]+\\[^\\]+)(?:\\|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public OsPath(string path)
{
if (path == null)
@@ -96,6 +99,29 @@ namespace NzbDrone.Common.Disk
return path;
}
private static string TrimTrailingSlash(string path, OsPathKind kind)
{
switch (kind)
{
case OsPathKind.Windows when !path.EndsWith(":\\"):
while (!path.EndsWith(":\\") && path.EndsWith('\\'))
{
path = path[..^1];
}
return path;
case OsPathKind.Unix when path != "/":
while (path != "/" && path.EndsWith('/'))
{
path = path[..^1];
}
return path;
}
return path;
}
public OsPathKind Kind => _kind;
public bool IsWindowsPath => _kind == OsPathKind.Windows;
@@ -130,7 +156,19 @@ namespace NzbDrone.Common.Disk
if (index == -1)
{
return new OsPath(null);
return Null;
}
var rootLength = GetRootLength();
if (rootLength == _path.Length)
{
return Null;
}
if (rootLength > index + 1)
{
return new OsPath(_path.Substring(0, rootLength));
}
return new OsPath(_path.Substring(0, index), _kind).AsDirectory();
@@ -139,6 +177,8 @@ namespace NzbDrone.Common.Disk
public string FullPath => _path;
public string PathWithoutTrailingSlash => TrimTrailingSlash(_path, _kind);
public string FileName
{
get
@@ -161,6 +201,29 @@ namespace NzbDrone.Common.Disk
}
}
public string Name
{
// Meant to behave similar to DirectoryInfo.Name
get
{
var index = GetFileNameIndex();
if (index == -1)
{
return PathWithoutTrailingSlash;
}
var rootLength = GetRootLength();
if (rootLength > index + 1)
{
return _path.Substring(0, rootLength);
}
return TrimTrailingSlash(_path.Substring(index).TrimStart('/', '\\'), _kind);
}
}
public bool IsValid => _path.IsPathValid(PathValidationType.CurrentOs);
private int GetFileNameIndex()
@@ -190,11 +253,50 @@ namespace NzbDrone.Common.Disk
return index;
}
private int GetRootLength()
{
if (!IsRooted)
{
return 0;
}
if (_kind == OsPathKind.Unix)
{
return 1;
}
if (_kind == OsPathKind.Windows)
{
if (HasWindowsDriveLetter(_path))
{
return 3;
}
var uncMatch = UncPathRegex.Match(_path);
// \\?\UNC\server\share\ or \\server\share
if (uncMatch.Success)
{
return uncMatch.Groups["unc"].Length;
}
// \\?\C:\
if (_path.StartsWith(@"\\?\"))
{
return 7;
}
}
return 0;
}
private string[] GetFragments()
{
return _path.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries);
}
public static OsPath Null => new(null);
public override string ToString()
{
return _path;
@@ -267,6 +369,11 @@ namespace NzbDrone.Common.Disk
}
public bool Equals(OsPath other)
{
return Equals(other, false);
}
public bool Equals(OsPath other, bool ignoreTrailingSlash)
{
if (ReferenceEquals(other, null))
{
@@ -278,8 +385,8 @@ namespace NzbDrone.Common.Disk
return true;
}
var left = _path;
var right = other._path;
var left = ignoreTrailingSlash ? PathWithoutTrailingSlash : _path;
var right = ignoreTrailingSlash ? other.PathWithoutTrailingSlash : other._path;
if (Kind == OsPathKind.Windows || other.Kind == OsPathKind.Windows)
{

View File

@@ -75,6 +75,17 @@ namespace NzbDrone.Common.EnvironmentInfo
{
try
{
if (OsInfo.IsOsx)
{
var userAppDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile, Environment.SpecialFolderOption.DoNotVerify), ".config", "Prowlarr");
if (_diskProvider.FolderExists(userAppDataFolder) && !_diskProvider.FileExists(_appFolderInfo.GetConfigPath()))
{
_diskTransferService.MirrorFolder(userAppDataFolder, _appFolderInfo.AppDataFolder);
_diskProvider.DeleteFolder(userAppDataFolder, true);
}
}
var oldDbFile = Path.Combine(_appFolderInfo.AppDataFolder, "nzbdrone.db");
if (_startupContext.Args.ContainsKey(StartupContext.APPDATA))
@@ -115,7 +126,7 @@ namespace NzbDrone.Common.EnvironmentInfo
catch (Exception ex)
{
_logger.Debug(ex, ex.Message);
throw new ProwlarrStartupException("Unable to migrate DB from nzbdrone.db to {0}. Migrate manually", _appFolderInfo.GetDatabase());
throw new ProwlarrStartupException(ex, "Unable to migrate DB from nzbdrone.db to {0}. Migrate manually", _appFolderInfo.GetDatabase());
}
}

View File

@@ -15,7 +15,7 @@ namespace NzbDrone.Common.EnvironmentInfo
var attributes = assembly.GetCustomAttributes(true);
Branch = "unknow";
Branch = "unknown";
var config = attributes.OfType<AssemblyConfigurationAttribute>().FirstOrDefault();
if (config != null)

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using NLog;
@@ -25,22 +24,25 @@ namespace NzbDrone.Common.EnvironmentInfo
static OsInfo()
{
var platform = Environment.OSVersion.Platform;
switch (platform)
if (OperatingSystem.IsWindows())
{
case PlatformID.Win32NT:
{
Os = Os.Windows;
break;
}
case PlatformID.MacOSX:
case PlatformID.Unix:
{
Os = GetPosixFlavour();
break;
}
Os = Os.Windows;
}
else if (OperatingSystem.IsMacOS())
{
Os = Os.Osx;
}
else if (OperatingSystem.IsFreeBSD())
{
Os = Os.Bsd;
}
else
{
#if ISMUSL
Os = Os.LinuxMusl;
#else
Os = Os.Linux;
#endif
}
}
@@ -84,59 +86,6 @@ namespace NzbDrone.Common.EnvironmentInfo
IsDocker = true;
}
}
private static Os GetPosixFlavour()
{
var output = RunAndCapture("uname", "-s");
if (output.StartsWith("Darwin"))
{
return Os.Osx;
}
else if (output.Contains("BSD"))
{
return Os.Bsd;
}
else
{
#if ISMUSL
return Os.LinuxMusl;
#else
return Os.Linux;
#endif
}
}
private static string RunAndCapture(string filename, string args)
{
var processStartInfo = new ProcessStartInfo
{
FileName = filename,
Arguments = args,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
var output = string.Empty;
try
{
using (var p = Process.Start(processStartInfo))
{
// To avoid deadlocks, always read the output stream first and then wait.
output = p.StandardOutput.ReadToEnd();
p.WaitForExit(1000);
}
}
catch (Exception)
{
output = string.Empty;
}
return output;
}
}
public interface IOsInfo

View File

@@ -31,7 +31,7 @@ namespace NzbDrone.Common.Extensions
}
public static IDictionary<TNewKey, TNewValue> SelectDictionary<TKey, TValue, TNewKey, TNewValue>(this IDictionary<TKey, TValue> dictionary,
Func<KeyValuePair<TKey, TValue>, ValueTuple<TNewKey, TNewValue>> selection)
Func<KeyValuePair<TKey, TValue>, (TNewKey Item1, TNewValue Item2)> selection)
{
return dictionary.Select(selection).ToDictionary(t => t.Item1, t => t.Item2);
}

View File

@@ -39,18 +39,24 @@ namespace NzbDrone.Common.Extensions
private static bool IsLocalIPv4(byte[] ipv4Bytes)
{
// Link local (no IP assigned by DHCP): 169.254.0.0 to 169.254.255.255 (169.254.0.0/16)
bool IsLinkLocal() => ipv4Bytes[0] == 169 && ipv4Bytes[1] == 254;
var isLinkLocal = ipv4Bytes[0] == 169 && ipv4Bytes[1] == 254;
// Class A private range: 10.0.0.0 10.255.255.255 (10.0.0.0/8)
bool IsClassA() => ipv4Bytes[0] == 10;
var isClassA = ipv4Bytes[0] == 10;
// Class B private range: 172.16.0.0 172.31.255.255 (172.16.0.0/12)
bool IsClassB() => ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31;
var isClassB = ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31;
// Class C private range: 192.168.0.0 192.168.255.255 (192.168.0.0/16)
bool IsClassC() => ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168;
var isClassC = ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168;
return IsLinkLocal() || IsClassA() || IsClassC() || IsClassB();
return isLinkLocal || isClassA || isClassC || isClassB;
}
public static bool IsCgnatIpAddress(this IPAddress ipAddress)
{
var bytes = ipAddress.GetAddressBytes();
return bytes.Length == 4 && bytes[0] == 100 && bytes[1] >= 64 && bytes[1] <= 127;
}
}
}

View File

@@ -25,8 +25,6 @@ namespace NzbDrone.Common.Extensions
private static readonly string UPDATE_CLIENT_FOLDER_NAME = "Prowlarr.Update" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_LOG_FOLDER_NAME = "UpdateLogs" + Path.DirectorySeparatorChar;
private static readonly Regex PARENT_PATH_END_SLASH_REGEX = new Regex(@"(?<!:)\\$", RegexOptions.Compiled);
public static string CleanFilePath(this string path)
{
if (path.IsNotNullOrWhiteSpace())
@@ -87,55 +85,50 @@ namespace NzbDrone.Common.Extensions
throw new NotParentException("{0} is not a child of {1}", childPath, parentPath);
}
return childPath.Substring(parentPath.Length).Trim(Path.DirectorySeparatorChar);
return childPath.Substring(parentPath.Length).Trim('\\', '/');
}
public static string GetParentPath(this string childPath)
{
var cleanPath = OsInfo.IsWindows
? PARENT_PATH_END_SLASH_REGEX.Replace(childPath, "")
: childPath.TrimEnd(Path.DirectorySeparatorChar);
var path = new OsPath(childPath).Directory;
if (cleanPath.IsNullOrWhiteSpace())
{
return null;
}
return path == OsPath.Null ? null : path.PathWithoutTrailingSlash;
}
return Directory.GetParent(cleanPath)?.FullName;
public static string GetParentName(this string childPath)
{
var path = new OsPath(childPath).Directory;
return path == OsPath.Null ? null : path.Name;
}
public static string GetDirectoryName(this string childPath)
{
var path = new OsPath(childPath);
return path == OsPath.Null ? null : path.Name;
}
public static string GetCleanPath(this string path)
{
var cleanPath = OsInfo.IsWindows
? PARENT_PATH_END_SLASH_REGEX.Replace(path, "")
: path.TrimEnd(Path.DirectorySeparatorChar);
var osPath = new OsPath(path);
return cleanPath;
return osPath == OsPath.Null ? null : osPath.PathWithoutTrailingSlash;
}
public static bool IsParentPath(this string parentPath, string childPath)
{
if (parentPath != "/" && !parentPath.EndsWith(":\\"))
{
parentPath = parentPath.TrimEnd(Path.DirectorySeparatorChar);
}
var parent = new OsPath(parentPath);
var child = new OsPath(childPath);
if (childPath != "/" && !parentPath.EndsWith(":\\"))
while (child.Directory != OsPath.Null)
{
childPath = childPath.TrimEnd(Path.DirectorySeparatorChar);
}
var parent = new DirectoryInfo(parentPath);
var child = new DirectoryInfo(childPath);
while (child.Parent != null)
{
if (child.Parent.FullName.Equals(parent.FullName, DiskProviderBase.PathStringComparison))
if (child.Directory.Equals(parent, true))
{
return true;
}
child = child.Parent;
child = child.Directory;
}
return false;
@@ -150,14 +143,14 @@ namespace NzbDrone.Common.Extensions
return false;
}
if (path.Trim() != path)
{
return false;
}
// Only check for leading or trailing spaces for path when running on Windows.
if (OsInfo.IsWindows)
{
if (path.Trim() != path)
{
return false;
}
var directoryInfo = new DirectoryInfo(path);
while (directoryInfo != null)

View File

@@ -9,7 +9,7 @@ namespace NzbDrone.Common.Http
{
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
// NOTE: we are not checking non-ascii characters and we should
private static readonly Regex CookieRegex = new (@"([^\(\)<>@,;:\\""/\[\]\?=\{\}\s]+)=([^,;\\""\s]+)");
private static readonly Regex CookieRegex = new(@"([^\(\)<>@,;:\\""/\[\]\?=\{\}\s]+)=([^,;\\""\s]+)");
private static readonly string[] FilterProps = { "COMMENT", "COMMENTURL", "DISCORD", "DOMAIN", "EXPIRES", "MAX-AGE", "PATH", "PORT", "SECURE", "VERSION", "HTTPONLY", "SAMESITE" };
private static readonly char[] InvalidKeyChars = { '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t', '\n' };
private static readonly char[] InvalidValueChars = { '"', ',', ';', '\\', ' ', '\t', '\n' };

View File

@@ -167,7 +167,7 @@ namespace NzbDrone.Common.Http.Dispatchers
}
catch (OperationCanceledException ex) when (cts.IsCancellationRequested)
{
throw new WebException("Http request timed out", ex.InnerException, WebExceptionStatus.Timeout, null);
throw new WebException("Http request timed out", ex, WebExceptionStatus.Timeout, null);
}
}

View File

@@ -97,7 +97,7 @@ namespace NzbDrone.Common.Http
// Save to add to final response
var responseCookies = response.Cookies;
// Update cookiecontainer for next request with any cookies recieved on last request
// Update cookie container for next request with any cookies received on last request
var responseContainer = HandleRedirectCookies(request, response);
response = await ExecuteRequestAsync(request, responseContainer);

View File

@@ -9,7 +9,7 @@ namespace NzbDrone.Common.Http
{
public class HttpResponse
{
private static readonly Regex RegexRefresh = new ("^(.*?url)=(.*?)(?:;|$)", RegexOptions.Compiled);
private static readonly Regex RegexRefresh = new("^(.*?url)=(.*?)(?:;|$)", RegexOptions.Compiled);
public HttpResponse(HttpRequest request, HttpHeader headers, CookieCollection cookies, byte[] binaryData, long elapsedTime = 0, HttpStatusCode statusCode = HttpStatusCode.OK, Version version = null)
{

View File

@@ -1,15 +1,16 @@
using System;
using System.Text.RegularExpressions;
namespace NzbDrone.Common.Http
{
public static class UserAgentParser
{
private static readonly Regex AppSourceRegex = new Regex(@"(?<agent>[a-z0-9]*)\/.*(?:\(.*\))?",
private static readonly Regex AppSourceRegex = new(@"^(?<agent>[a-z0-9]+)(?:\/.+(?:\(.*\))?|$)",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
public static string SimplifyUserAgent(string userAgent)
{
if (userAgent == null || userAgent.StartsWith("Mozilla/5.0"))
if (userAgent == null || userAgent.StartsWith("Mozilla/5.0", StringComparison.Ordinal))
{
return null;
}
@@ -19,14 +20,9 @@ namespace NzbDrone.Common.Http
public static string ParseSource(string userAgent)
{
var match = AppSourceRegex.Match(SimplifyUserAgent(userAgent) ?? string.Empty);
var match = AppSourceRegex.Match(SimplifyUserAgent(userAgent?.Trim()) ?? string.Empty);
if (match.Groups["agent"].Success)
{
return match.Groups["agent"].Value;
}
return "Other";
return match.Groups["agent"].Success ? match.Groups["agent"].Value : "Other";
}
}
}

View File

@@ -10,64 +10,64 @@ namespace NzbDrone.Common.Instrumentation
private static readonly Regex[] CleansingRules =
{
// Url
new (@"(?<=[?&: ;])(apikey|api_key|(?:(?:access|api)[-_]?)?token|pass(?:key|wd)?|auth|authkey|user|u?id|api|[a-z_]*apikey|account|pid|pwd)=(?<secret>[^&=""]+?)(?=[ ""&=]|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"(?<=[?& ;])[^=]*?(_?(?<!use|get_)token|username|passwo?rd)=(?<secret>[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"rss(24h)?\.torrentleech\.org/(?!rss)(?<secret>[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"torrentleech\.org/rss/download/[0-9]+/(?<secret>[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"iptorrents\.com/[/a-z0-9?&;]*?(?:[?&;](u|tp)=(?<secret>[^&=;]+?))+(?= |;|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"/fetch/[a-z0-9]{32}/(?<secret>[a-z0-9]{32})", RegexOptions.Compiled),
new (@"getnzb.*?(?<=\?|&)(r)=(?<secret>[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"\b(\w*)?(_?(?<!use|get_)token|username|passwo?rd)=(?<secret>[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"(?<=authkey = "")(?<secret>[^&=]+?)(?="")", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"(?<=beyond-hd\.[a-z]+/api/torrents/)(?<secret>[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"(?<=beyond-hd\.[a-z]+/torrent/download/[\w\d-]+[.]\d+[.])(?<secret>[a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"(?:sharewood)\.[a-z]{2,3}/api/(?<secret>[a-z0-9]{16,})/", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?<=[?&: ;])(apikey|api_key|(?:(?:access|api)[-_]?)?token|pass(?:key|wd)?|auth|authkey|rsskey|user|u?id|api|[a-z_]*apikey|account|pid|pwd)=(?<secret>[^&=""]+?)(?=[ ""&=]|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?<=[?& ;])[^=]*?(_?(?<!use|get_)token|username|passwo?rd)=(?<secret>[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"rss(24h)?\.torrentleech\.org/(?!rss)(?<secret>[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"torrentleech\.org/rss/download/[0-9]+/(?<secret>[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"iptorrents\.com/[/a-z0-9?&;]*?(?:[?&;](u|tp)=(?<secret>[^&=;]+?))+(?= |;|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"/fetch/[a-z0-9]{32}/(?<secret>[a-z0-9]{32})", RegexOptions.Compiled),
new(@"getnzb.*?(?<=\?|&)(r)=(?<secret>[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"\b(\w*)?(_?(?<!use|get_)token|username|passwo?rd)=(?<secret>[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?<=authkey = "")(?<secret>[^&=]+?)(?="")", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?<=beyond-hd\.[a-z]+/api/torrents/)(?<secret>[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?<=beyond-hd\.[a-z]+/torrent/download/[\w\d-]+[.]\d+[.])(?<secret>[a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?:sharewood)\.[a-z]{2,3}/api/(?<secret>[a-z0-9]{16,})/", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// UNIT3D
new (@"(?<=[a-z0-9-]+\.[a-z]+/torrent/download/\d+\.)(?<secret>[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?<=[a-z0-9-]+\.[a-z]+/torrent/download/\d+\.)(?<secret>[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Path
new (@"""C:\\Users\\(?<secret>[^\""]+?)(\\|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"""/(home|Users)/(?<secret>[^/""]+?)(/|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"""C:\\Users\\(?<secret>[^\""]+?)(\\|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"""/(home|Users)/(?<secret>[^/""]+?)(/|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Trackers Announce Keys; Designed for Qbit Json; should work for all in theory
new (@"announce(\.php)?(/|%2f|%3fpasskey%3d)(?<secret>[a-z0-9]{16,})|(?<secret>[a-z0-9]{16,})(/|%2f)announce", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"announce(\.php)?(/|%2f|%3fpasskey%3d)(?<secret>[a-z0-9]{16,})|(?<secret>[a-z0-9]{16,})(/|%2f)announce", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// NzbGet
new (@"""Name""\s*:\s*""[^""]*(username|password)""\s*,\s*""Value""\s*:\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"""Name""\s*:\s*""[^""]*(username|password)""\s*,\s*""Value""\s*:\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Sabnzbd
new (@"""[^""]*(username|password|api_?key|nzb_key)""\s*:\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"""email_(account|to|from|pwd)""\s*:\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"""[^""]*(username|password|api_?key|nzb_key)""\s*:\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"""email_(account|to|from|pwd)""\s*:\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// uTorrent
new (@"\[""[a-z._]*(username|password)"",\d,""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"\[""(boss_key|boss_key_salt|proxy\.proxy)"",\d,""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"\[""[a-z._]*(username|password)"",\d,""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"\[""(boss_key|boss_key_salt|proxy\.proxy)"",\d,""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Deluge
new (@"auth.login\(""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"auth.login\(""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// BroadcastheNet (;torrent_pass|torrents_notify_ is for MTV)
new (@"""?method""?\s*:\s*""(getTorrents)"",\s*""?params""?\s*:\s*\[\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"getTorrents\(""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"(?<=\?|&|;|=)(authkey|torrent_pass|torrents_notify)[_=](?<secret>[^&=]+?)(?=""|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"""?method""?\s*:\s*""(getTorrents)"",\s*""?params""?\s*:\s*\[\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"getTorrents\(""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?<=\?|&|;|=)(authkey|torrent_pass|torrents_notify)[_=](?<secret>[^&=]+?)(?=""|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Plex
new (@"(?<=\?|&)(X-Plex-Client-Identifier|X-Plex-Token)=(?<secret>[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?<=\?|&)(X-Plex-Client-Identifier|X-Plex-Token)=(?<secret>[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Indexer Responses
new (@"(?:avistaz|exoticaz|cinemaz|privatehd)\.[a-z]{2,3}/rss/download/(?<secret>[^&=]+?)/(?<secret>[^&=]+?)\.torrent", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"(?:animebytes)\.[a-z]{2,3}/torrent/[0-9]+/download/(?<secret>[^&=]+?)[""]", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"""(info_hash|token|((pass|rss)[- _]?key))"":""(?<secret>[^&=]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?:avistaz|exoticaz|cinemaz|privatehd)\.[a-z]{2,3}/rss/download/(?<secret>[^&=]+?)/(?<secret>[^&=]+?)\.torrent", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"(?:animebytes)\.[a-z]{2,3}/torrent/[0-9]+/download/(?<secret>[^&=]+?)[""]", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"""(info_hash|token|((pass|rss)[- _]?key))"":""(?<secret>[^&=]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Applications
new (@"""name"":""apikey"",""value"":""(?<secret>[^&=]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"""name"":""apikey"",""value"":""(?<secret>[^&=]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Discord
new (@"discord.com/api/webhooks/((?<secret>[\w-]+)/)?(?<secret>[\w-]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase)
new(@"discord.com/api/webhooks/((?<secret>[\w-]+)/)?(?<secret>[\w-]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase)
};
private static readonly Regex CleanseRemoteIPRegex = new (@"(?:Auth-\w+(?<!Failure|Unauthorized) ip|from) (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", RegexOptions.Compiled);
private static readonly Regex CleanseRemoteIPRegex = new(@"(?:Auth-\w+(?<!Failure|Unauthorized) ip|from) (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", RegexOptions.Compiled);
public static string Cleanse(string message)
{

View File

@@ -0,0 +1,21 @@
using System.Text;
using NLog;
using NLog.Layouts.ClefJsonLayout;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Common.Instrumentation;
public class CleansingClefLogLayout : CompactJsonLayout
{
protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target)
{
base.RenderFormattedMessage(logEvent, target);
if (RuntimeInfo.IsProduction)
{
var result = CleanseLogMessage.Cleanse(target.ToString());
target.Clear();
target.Append(result);
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Text;
using NLog;
using NLog.Layouts;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Common.Instrumentation;
public class CleansingConsoleLogLayout : SimpleLayout
{
public CleansingConsoleLogLayout(string format)
: base(format)
{
}
protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target)
{
base.RenderFormattedMessage(logEvent, target);
if (RuntimeInfo.IsProduction)
{
var result = CleanseLogMessage.Cleanse(target.ToString());
target.Clear();
target.Append(result);
}
}
}

View File

@@ -4,7 +4,7 @@ using NLog.Targets;
namespace NzbDrone.Common.Instrumentation
{
public class NzbDroneFileTarget : FileTarget
public class CleansingFileTarget : FileTarget
{
protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target)
{

View File

@@ -4,27 +4,27 @@ namespace NzbDrone.Common.Instrumentation.Extensions
{
public static class LoggerExtensions
{
[MessageTemplateFormatMethod("message")]
public static void ProgressInfo(this Logger logger, string message, params object[] args)
{
var formattedMessage = string.Format(message, args);
LogProgressMessage(logger, LogLevel.Info, formattedMessage);
LogProgressMessage(logger, LogLevel.Info, message, args);
}
[MessageTemplateFormatMethod("message")]
public static void ProgressDebug(this Logger logger, string message, params object[] args)
{
var formattedMessage = string.Format(message, args);
LogProgressMessage(logger, LogLevel.Debug, formattedMessage);
LogProgressMessage(logger, LogLevel.Debug, message, args);
}
[MessageTemplateFormatMethod("message")]
public static void ProgressTrace(this Logger logger, string message, params object[] args)
{
var formattedMessage = string.Format(message, args);
LogProgressMessage(logger, LogLevel.Trace, formattedMessage);
LogProgressMessage(logger, LogLevel.Trace, message, args);
}
private static void LogProgressMessage(Logger logger, LogLevel level, string message)
private static void LogProgressMessage(Logger logger, LogLevel level, string message, object[] parameters)
{
var logEvent = new LogEventInfo(level, logger.Name, message);
var logEvent = new LogEventInfo(level, logger.Name, null, message, parameters);
logEvent.Properties.Add("Status", "");
logger.Log(logEvent);

View File

@@ -3,7 +3,6 @@ using System.Diagnostics;
using System.IO;
using NLog;
using NLog.Config;
using NLog.Layouts.ClefJsonLayout;
using NLog.Targets;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
@@ -13,9 +12,11 @@ namespace NzbDrone.Common.Instrumentation
{
public static class NzbDroneLogger
{
private const string FILE_LOG_LAYOUT = @"${date:format=yyyy-MM-dd HH\:mm\:ss.f}|${level}|${logger}|${message}${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}";
public const string ConsoleLogLayout = "[${level}] ${logger}: ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}";
public static CompactJsonLayout ClefLogLayout = new CompactJsonLayout();
private const string FileLogLayout = @"${date:format=yyyy-MM-dd HH\:mm\:ss.f}|${level}|${logger}|${message}${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}";
private const string ConsoleFormat = "[${level}] ${logger}: ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}";
private static readonly CleansingConsoleLogLayout CleansingConsoleLayout = new(ConsoleFormat);
private static readonly CleansingClefLogLayout ClefLogLayout = new();
private static bool _isConfigured;
@@ -119,11 +120,7 @@ namespace NzbDrone.Common.Instrumentation
? formatEnumValue
: ConsoleLogFormat.Standard;
coloredConsoleTarget.Layout = logFormat switch
{
ConsoleLogFormat.Clef => ClefLogLayout,
_ => ConsoleLogLayout
};
ConfigureConsoleLayout(coloredConsoleTarget, logFormat);
var loggingRule = new LoggingRule("*", level, coloredConsoleTarget);
@@ -140,7 +137,7 @@ namespace NzbDrone.Common.Instrumentation
private static void RegisterAppFile(IAppFolderInfo appFolderInfo, string name, string fileName, int maxArchiveFiles, LogLevel minLogLevel)
{
var fileTarget = new NzbDroneFileTarget();
var fileTarget = new CleansingFileTarget();
fileTarget.Name = name;
fileTarget.FileName = Path.Combine(appFolderInfo.GetLogFolder(), fileName);
@@ -153,7 +150,7 @@ namespace NzbDrone.Common.Instrumentation
fileTarget.MaxArchiveFiles = maxArchiveFiles;
fileTarget.EnableFileDelete = true;
fileTarget.ArchiveNumbering = ArchiveNumberingMode.Rolling;
fileTarget.Layout = FILE_LOG_LAYOUT;
fileTarget.Layout = FileLogLayout;
var loggingRule = new LoggingRule("*", minLogLevel, fileTarget);
@@ -172,7 +169,7 @@ namespace NzbDrone.Common.Instrumentation
fileTarget.ConcurrentWrites = false;
fileTarget.ConcurrentWriteAttemptDelay = 50;
fileTarget.ConcurrentWriteAttempts = 100;
fileTarget.Layout = FILE_LOG_LAYOUT;
fileTarget.Layout = FileLogLayout;
var loggingRule = new LoggingRule("*", LogLevel.Trace, fileTarget);
@@ -217,6 +214,15 @@ namespace NzbDrone.Common.Instrumentation
{
return GetLogger(obj.GetType());
}
public static void ConfigureConsoleLayout(ColoredConsoleTarget target, ConsoleLogFormat format)
{
target.Layout = format switch
{
ConsoleLogFormat.Clef => NzbDroneLogger.ClefLogLayout,
_ => NzbDroneLogger.CleansingConsoleLayout
};
}
}
public enum ConsoleLogFormat

View File

@@ -119,7 +119,7 @@ namespace NzbDrone.Common.Instrumentation.Sentry
o.Environment = BuildInfo.Branch;
// Crash free run statistics (sends a ping for healthy and for crashes sessions)
o.AutoSessionTracking = true;
o.AutoSessionTracking = false;
// Caches files in the event device is offline
// Sentry creates a 'sentry' sub directory, no need to concat here
@@ -148,7 +148,7 @@ namespace NzbDrone.Common.Instrumentation.Sentry
_debounce = new SentryDebounce();
// initialize to true and reconfigure later
// Otherwise it will default to false and any errors occuring
// Otherwise it will default to false and any errors occurring
// before config file gets read will not be filtered
FilterEvents = true;
SentryEnabled = true;
@@ -207,9 +207,7 @@ namespace NzbDrone.Common.Instrumentation.Sentry
private void OnError(Exception ex)
{
var webException = ex as WebException;
if (webException != null)
if (ex is WebException webException)
{
var response = webException.Response as HttpWebResponse;
var statusCode = response?.StatusCode;

View File

@@ -6,4 +6,5 @@ public class AuthOptions
public bool? Enabled { get; set; }
public string Method { get; set; }
public string Required { get; set; }
public bool? TrustCgnatIpAddresses { get; set; }
}

View File

@@ -6,6 +6,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Model;
@@ -117,7 +118,9 @@ namespace NzbDrone.Common.Processes
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true
RedirectStandardInput = true,
StandardOutputEncoding = Encoding.UTF8,
StandardErrorEncoding = Encoding.UTF8
};
if (environmentVariables != null)
@@ -313,7 +316,7 @@ namespace NzbDrone.Common.Processes
processInfo = new ProcessInfo();
processInfo.Id = process.Id;
processInfo.Name = process.ProcessName;
processInfo.StartPath = process.MainModule.FileName;
processInfo.StartPath = process.MainModule?.FileName;
if (process.Id != GetCurrentProcessId() && process.HasExited)
{

View File

@@ -1,27 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64'">ISMUSL</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DryIoc.dll" Version="5.4.3" />
<PackageReference Include="IPAddressRange" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.2" />
<PackageReference Include="IPAddressRange" Version="6.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.3.3" />
<PackageReference Include="NLog.Layouts.ClefJsonLayout" Version="1.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.12" />
<PackageReference Include="Npgsql" Version="7.0.8" />
<PackageReference Include="NLog" Version="5.4.0" />
<PackageReference Include="NLog.Layouts.ClefJsonLayout" Version="1.0.3" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" />
<PackageReference Include="Npgsql" Version="9.0.3" />
<PackageReference Include="Sentry" Version="4.0.2" />
<PackageReference Include="NLog.Targets.Syslog" Version="7.0.0" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
<PackageReference Include="System.ValueTuple" Version="4.6.1" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.1" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.1" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<Compile Update="EnsureThat\Resources\ExceptionMessages.Designer.cs">

View File

@@ -94,7 +94,8 @@ namespace NzbDrone.Common.TPL
{
_currentThreadIsProcessingItems = false;
}
}, null);
},
null);
}
/// <summary>Attempts to execute the specified task on the current thread.</summary>

View File

@@ -20,7 +20,8 @@ namespace NzbDrone.Common.TPL
Logger.Error(exception, "Task Error");
}
}
}, TaskContinuationOptions.OnlyOnFaulted);
},
TaskContinuationOptions.OnlyOnFaulted);
return task;
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<ApplicationIcon>..\NzbDrone.Host\Prowlarr.ico</ApplicationIcon>
</PropertyGroup>

View File

@@ -0,0 +1,43 @@
using System;
using System.Data.SQLite;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Converters;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.Datastore.Converters;
[TestFixture]
public class TimeSpanConverterFixture : CoreTest<TimeSpanConverter>
{
private SQLiteParameter _param;
[SetUp]
public void Setup()
{
_param = new SQLiteParameter();
}
[Test]
public void should_return_string_when_saving_timespan_to_db()
{
var span = TimeSpan.FromMilliseconds(10);
Subject.SetValue(_param, span);
_param.Value.Should().Be(span.ToString());
}
[Test]
public void should_return_timespan_when_getting_string_from_db()
{
var span = TimeSpan.FromMilliseconds(10);
Subject.Parse(span.ToString()).Should().Be(span);
}
[Test]
public void should_return_zero_timespan_for_db_null_value_when_getting_from_db()
{
Subject.Parse(null).Should().Be(TimeSpan.Zero);
}
}

View File

@@ -0,0 +1,38 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Test.Datastore;
[TestFixture]
public class DatabaseVersionParserFixture
{
[TestCase("3.44.2", 3, 44, 2)]
public void should_parse_sqlite_database_version(string serverVersion, int majorVersion, int minorVersion, int buildVersion)
{
var version = DatabaseVersionParser.ParseServerVersion(serverVersion);
version.Should().NotBeNull();
version.Major.Should().Be(majorVersion);
version.Minor.Should().Be(minorVersion);
version.Build.Should().Be(buildVersion);
}
[TestCase("14.8 (Debian 14.8-1.pgdg110+1)", 14, 8, null)]
[TestCase("16.3 (Debian 16.3-1.pgdg110+1)", 16, 3, null)]
[TestCase("16.3 - Percona Distribution", 16, 3, null)]
[TestCase("17.0 - Percona Server", 17, 0, null)]
public void should_parse_postgres_database_version(string serverVersion, int majorVersion, int minorVersion, int? buildVersion)
{
var version = DatabaseVersionParser.ParseServerVersion(serverVersion);
version.Should().NotBeNull();
version.Major.Should().Be(majorVersion);
version.Minor.Should().Be(minorVersion);
if (buildVersion.HasValue)
{
version.Build.Should().Be(buildVersion.Value);
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<caps>
<server version="1.0" title="Anime Tosho" strapline="Anime NZB/DDL mirror" url="https://animetosho.org/"/>
<limits max="200" default="75"/>
<retention days="9999"/>
<registration available="no" open="yes" />
<searching>
<search available="yes" supportedParams="q" />
<tv-search available="no" supportedParams="q" />
<movie-search available="no" supportedParams="q" />
</searching>
<categories>
<category id="5070" name="Anime" description="Anime"/>
</categories>
</caps>
<server version="1.0" title="Anime Tosho" strapline="Anime NZB/DDL mirror" url="https://animetosho.org/" />
<limits max="200" default="75" />
<retention days="9999" />
<registration available="no" open="yes" />
<searching>
<search available="yes" supportedParams="q" />
<tv-search available="no" supportedParams="q" />
<movie-search available="no" supportedParams="q" />
</searching>
<categories>
<category id="5070" name="Anime" description="Anime" />
<category id="2020" name="Movies/Other" description="Movies (Anime)" />
</categories>
</caps>

View File

@@ -122,7 +122,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AnimeBytesTests
var fifthTorrentInfo = releases.ElementAt(28) as TorrentInfo;
fifthTorrentInfo.Title.Should().Be("[-ZR-] Dr. STONE: STONE WARS S02 [Web][MKV][h264][1080p][AAC 2.0][Dual Audio][Softsubs (-ZR-)]");
fifthTorrentInfo.Title.Should().Be("[-ZR-] Dr. STONE: STONE WARS 2021 S02 [Web][MKV][h264][1080p][AAC 2.0][Dual Audio][Softsubs (-ZR-)]");
fifthTorrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
fifthTorrentInfo.DownloadUrl.Should().Be("https://animebytes.tv/torrent/944509/download/somepass");
fifthTorrentInfo.InfoUrl.Should().Be("https://animebytes.tv/torrent/944509/group");

View File

@@ -26,15 +26,15 @@ namespace NzbDrone.Core.Test.IndexerTests.HDBitsTests
[SetUp]
public void Setup()
{
Subject.Definition = new IndexerDefinition()
Subject.Definition = new IndexerDefinition
{
Name = "HdBits",
Settings = new HDBitsSettings() { ApiKey = "fakekey" }
Settings = new HDBitsSettings { ApiKey = "fakekey" }
};
_movieSearchCriteria = new MovieSearchCriteria
{
Categories = new int[] { 2000, 2010 },
Categories = new[] { 2000, 2010 },
ImdbId = "0076759"
};
}
@@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.IndexerTests.HDBitsTests
var torrents = (await Subject.Fetch(_movieSearchCriteria)).Releases;
torrents.Should().HaveCount(2);
torrents.First().Should().BeOfType<HDBitsInfo>();
torrents.First().Should().BeOfType<TorrentInfo>();
var first = torrents.First() as TorrentInfo;

View File

@@ -83,17 +83,18 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
bookCats.Should().Contain("8000");
}
[Test]
public void should_find_sub_categories_as_main_categories()
[TestCase(5070)]
[TestCase(2020)]
public void should_find_sub_categories_as_main_categories(int category)
{
GivenCapsResponse(ReadAllText("Files/Indexers/Torznab/torznab_animetosho_caps.xml"));
var caps = Subject.GetCapabilities(_settings, _definition);
var bookCats = caps.Categories.MapTrackerCatToNewznab("5070");
var indexerCategories = caps.Categories.MapTrackerCatToNewznab(category.ToString());
bookCats.Count.Should().Be(2);
bookCats.First().Id.Should().Be(5070);
indexerCategories.Count.Should().Be(2);
indexerCategories.First().Id.Should().Be(category);
}
[Test]

View File

@@ -50,7 +50,7 @@ namespace NzbDrone.Core.Test.IndexerTests.PTPTests
first.Guid.Should().Be("PassThePopcorn-452135");
first.Title.Should().Be("The.Night.Of.S01.BluRay.AAC2.0.x264-DEPTH");
first.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
first.DownloadUrl.Should().Be("https://passthepopcorn.me/torrents.php?action=download&id=452135&authkey=00000000000000000000000000000000&torrent_pass=00000000000000000000000000000000");
first.DownloadUrl.Should().Be("https://passthepopcorn.me/torrents.php?action=download&id=452135");
first.InfoUrl.Should().Be("https://passthepopcorn.me/torrents.php?id=148131&torrentid=452135");
//first.PublishDate.Should().Be(DateTime.Parse("2017-04-17T12:13:42+0000").ToUniversalTime()); stupid timezones

View File

@@ -46,8 +46,8 @@ namespace NzbDrone.Core.Test.IndexerTests.RedactedTests
torrentInfo.Title.Should().Be("Red Hot Chili Peppers - Californication (1999) [Album] [US / Reissue 2020] [FLAC 24bit Lossless / Vinyl]");
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
torrentInfo.DownloadUrl.Should().Be("https://redacted.ch/ajax.php?action=download&id=3892313");
torrentInfo.InfoUrl.Should().Be("https://redacted.ch/torrents.php?id=16720&torrentid=3892313");
torrentInfo.DownloadUrl.Should().Be("https://redacted.sh/ajax.php?action=download&id=3892313");
torrentInfo.InfoUrl.Should().Be("https://redacted.sh/torrents.php?id=16720&torrentid=3892313");
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-12-17 08:02:35"));

View File

@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.151" />
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="NBuilder" Version="6.1.0" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="YamlDotNet" Version="13.1.1" />
<PackageReference Include="YamlDotNet" Version="16.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Test.Common\Prowlarr.Test.Common.csproj" />

View File

@@ -16,7 +16,7 @@ namespace NzbDrone.Core.Applications
protected readonly IAppIndexerMapService _appIndexerMapService;
protected readonly Logger _logger;
protected static readonly Regex AppIndexerRegex = new (@"\/(?<indexer>\d{1,3})(?:\/(?:api)?\/?)?$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
protected static readonly Regex AppIndexerRegex = new(@"\/(?<indexer>\d{1,3})(?:\/(?:api)?\/?)?$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
public abstract string Name { get; }

View File

@@ -53,7 +53,7 @@ namespace NzbDrone.Core.Applications
foreach (var application in applications)
{
if (blockedApplications.TryGetValue(application.Definition.Id, out var blockedApplicationStatus))
if (blockedApplications.TryGetValue(application.Definition.Id, out var blockedApplicationStatus) && blockedApplicationStatus.DisabledTill.HasValue)
{
_logger.Debug("Temporarily ignoring application {0} till {1} due to recent failures.", application.Definition.Name, blockedApplicationStatus.DisabledTill.Value.ToLocalTime());
continue;

View File

@@ -19,7 +19,7 @@ namespace NzbDrone.Core.Applications.LazyLibrarian
public class LazyLibrarianSettings : IApplicationSettings
{
private static readonly LazyLibrarianSettingsValidator Validator = new ();
private static readonly LazyLibrarianSettingsValidator Validator = new();
public LazyLibrarianSettings()
{

View File

@@ -121,9 +121,16 @@ namespace NzbDrone.Core.Applications.Lidarr
{
var indexerCapabilities = GetIndexerCapabilities(indexer);
if (!indexerCapabilities.MusicSearchAvailable && !indexerCapabilities.SearchAvailable)
{
_logger.Debug("Skipping add for indexer {0} [{1}] due to missing music or basic search support by the indexer", indexer.Name, indexer.Id);
return;
}
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Empty())
{
_logger.Trace("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
_logger.Debug("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
return;
}
@@ -178,7 +185,8 @@ namespace NzbDrone.Core.Applications.Lidarr
{
_logger.Debug("Syncing remote indexer with current settings");
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if ((indexerCapabilities.MusicSearchAvailable || indexerCapabilities.SearchAvailable) &&
indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Retain user fields not-affiliated with Prowlarr
lidarrIndexer.Fields.AddRange(remoteIndexer.Fields.Where(f => lidarrIndexer.Fields.All(s => s.Name != f.Name)));
@@ -204,7 +212,8 @@ namespace NzbDrone.Core.Applications.Lidarr
{
_appIndexerMapService.Delete(indexerMapping.Id);
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if ((indexerCapabilities.MusicSearchAvailable || indexerCapabilities.SearchAvailable) &&
indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
_logger.Debug("Remote indexer not found, re-adding {0} [{1}] to Lidarr", indexer.Name, indexer.Id);
lidarrIndexer.Id = 0;

View File

@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Applications.Lidarr
public class LidarrSettings : IApplicationSettings
{
private static readonly LidarrSettingsValidator Validator = new ();
private static readonly LidarrSettingsValidator Validator = new();
public LidarrSettings()
{

View File

@@ -23,7 +23,7 @@ namespace NzbDrone.Core.Applications.Lidarr
public class LidarrV1Proxy : ILidarrV1Proxy
{
private static Version MinimumApplicationVersion => new (1, 0, 2, 0);
private static Version MinimumApplicationVersion => new(1, 0, 2, 0);
private const string AppApiRoute = "/api/v1";
private const string AppIndexerApiRoute = $"{AppApiRoute}/indexer";

View File

@@ -19,7 +19,7 @@ namespace NzbDrone.Core.Applications.Mylar
public class MylarSettings : IApplicationSettings
{
private static readonly MylarSettingsValidator Validator = new ();
private static readonly MylarSettingsValidator Validator = new();
public MylarSettings()
{

View File

@@ -121,9 +121,16 @@ namespace NzbDrone.Core.Applications.Radarr
{
var indexerCapabilities = GetIndexerCapabilities(indexer);
if (!indexerCapabilities.MovieSearchAvailable && !indexerCapabilities.SearchAvailable)
{
_logger.Debug("Skipping add for indexer {0} [{1}] due to missing movie or basic search support by the indexer", indexer.Name, indexer.Id);
return;
}
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Empty())
{
_logger.Trace("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
_logger.Debug("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
return;
}
@@ -176,7 +183,8 @@ namespace NzbDrone.Core.Applications.Radarr
if (!radarrIndexer.Equals(remoteIndexer) || forceSync)
{
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if ((indexerCapabilities.MovieSearchAvailable || indexerCapabilities.SearchAvailable) &&
indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Retain user fields not-affiliated with Prowlarr
radarrIndexer.Fields.AddRange(remoteIndexer.Fields.Where(f => radarrIndexer.Fields.All(s => s.Name != f.Name)));
@@ -202,7 +210,8 @@ namespace NzbDrone.Core.Applications.Radarr
{
_appIndexerMapService.Delete(indexerMapping.Id);
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if ((indexerCapabilities.MovieSearchAvailable || indexerCapabilities.SearchAvailable) &&
indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
_logger.Debug("Remote indexer not found, re-adding {0} [{1}] to Radarr", indexer.Name, indexer.Id);
radarrIndexer.Id = 0;

View File

@@ -19,7 +19,7 @@ namespace NzbDrone.Core.Applications.Radarr
public class RadarrSettings : IApplicationSettings
{
private static readonly RadarrSettingsValidator Validator = new ();
private static readonly RadarrSettingsValidator Validator = new();
public RadarrSettings()
{

View File

@@ -23,8 +23,8 @@ namespace NzbDrone.Core.Applications.Radarr
public class RadarrV3Proxy : IRadarrV3Proxy
{
private static Version MinimumApplicationV4Version => new (4, 0, 4, 0);
private static Version MinimumApplicationV3Version => new (3, 1, 1, 0);
private static Version MinimumApplicationV4Version => new(4, 0, 4, 0);
private static Version MinimumApplicationV3Version => new(3, 1, 1, 0);
private const string AppApiRoute = "/api/v3";
private const string AppIndexerApiRoute = $"{AppApiRoute}/indexer";

View File

@@ -121,9 +121,16 @@ namespace NzbDrone.Core.Applications.Readarr
{
var indexerCapabilities = GetIndexerCapabilities(indexer);
if (!indexerCapabilities.BookSearchAvailable && !indexerCapabilities.SearchAvailable)
{
_logger.Debug("Skipping add for indexer {0} [{1}] due to missing book or basic search support by the indexer", indexer.Name, indexer.Id);
return;
}
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Empty())
{
_logger.Trace("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
_logger.Debug("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
return;
}
@@ -178,7 +185,8 @@ namespace NzbDrone.Core.Applications.Readarr
{
_logger.Debug("Syncing remote indexer with current settings");
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if ((indexerCapabilities.BookSearchAvailable || indexerCapabilities.SearchAvailable) &&
indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Retain user fields not-affiliated with Prowlarr
readarrIndexer.Fields.AddRange(remoteIndexer.Fields.Where(f => readarrIndexer.Fields.All(s => s.Name != f.Name)));
@@ -204,7 +212,8 @@ namespace NzbDrone.Core.Applications.Readarr
{
_appIndexerMapService.Delete(indexerMapping.Id);
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if ((indexerCapabilities.BookSearchAvailable || indexerCapabilities.SearchAvailable) &&
indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
_logger.Debug("Remote indexer not found, re-adding {0} [{1}] to Readarr", indexer.Name, indexer.Id);
readarrIndexer.Id = 0;

View File

@@ -19,7 +19,7 @@ namespace NzbDrone.Core.Applications.Readarr
public class ReadarrSettings : IApplicationSettings
{
private static readonly ReadarrSettingsValidator Validator = new ();
private static readonly ReadarrSettingsValidator Validator = new();
public ReadarrSettings()
{

View File

@@ -125,10 +125,17 @@ namespace NzbDrone.Core.Applications.Sonarr
{
var indexerCapabilities = GetIndexerCapabilities(indexer);
if (!indexerCapabilities.TvSearchAvailable && !indexerCapabilities.SearchAvailable)
{
_logger.Debug("Skipping add for indexer {0} [{1}] due to missing TV or basic search support by the indexer", indexer.Name, indexer.Id);
return;
}
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Empty() &&
indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Empty())
{
_logger.Trace("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
_logger.Debug("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
return;
}
@@ -183,7 +190,8 @@ namespace NzbDrone.Core.Applications.Sonarr
{
_logger.Debug("Syncing remote indexer with current settings");
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any())
if ((indexerCapabilities.TvSearchAvailable || indexerCapabilities.SearchAvailable) &&
(indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any()))
{
// Retain user fields not-affiliated with Prowlarr
sonarrIndexer.Fields.AddRange(remoteIndexer.Fields.Where(f => sonarrIndexer.Fields.All(s => s.Name != f.Name)));
@@ -210,7 +218,8 @@ namespace NzbDrone.Core.Applications.Sonarr
{
_appIndexerMapService.Delete(indexerMapping.Id);
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any())
if ((indexerCapabilities.TvSearchAvailable || indexerCapabilities.SearchAvailable) &&
(indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any()))
{
_logger.Debug("Remote indexer not found, re-adding {0} [{1}] to Sonarr", indexer.Name, indexer.Id);
sonarrIndexer.Id = 0;

View File

@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Applications.Sonarr
public class SonarrSettings : IApplicationSettings
{
private static readonly SonarrSettingsValidator Validator = new ();
private static readonly SonarrSettingsValidator Validator = new();
public SonarrSettings()
{

View File

@@ -23,7 +23,7 @@ namespace NzbDrone.Core.Applications.Sonarr
public class SonarrV3Proxy : ISonarrV3Proxy
{
private static Version MinimumApplicationVersion => new (3, 0, 5, 0);
private static Version MinimumApplicationVersion => new(3, 0, 5, 0);
private const string AppApiRoute = "/api/v3";
private const string AppIndexerApiRoute = $"{AppApiRoute}/indexer";

View File

@@ -19,7 +19,7 @@ namespace NzbDrone.Core.Applications.Whisparr
public class WhisparrSettings : IApplicationSettings
{
private static readonly WhisparrSettingsValidator Validator = new ();
private static readonly WhisparrSettingsValidator Validator = new();
public WhisparrSettings()
{

View File

@@ -1,8 +1,11 @@
using System;
namespace NzbDrone.Core.Authentication
{
public enum AuthenticationType
{
None = 0,
[Obsolete("Use Forms authentication instead")]
Basic = 1,
Forms = 2,
External = 3

View File

@@ -66,12 +66,19 @@ namespace NzbDrone.Core.Backup
{
_logger.ProgressInfo("Starting Backup");
var backupFolder = GetBackupFolder(backupType);
_diskProvider.EnsureFolder(_backupTempFolder);
_diskProvider.EnsureFolder(GetBackupFolder(backupType));
_diskProvider.EnsureFolder(backupFolder);
if (!_diskProvider.FolderWritable(backupFolder))
{
throw new UnauthorizedAccessException($"Backup folder {backupFolder} is not writable");
}
var dateNow = DateTime.Now;
var backupFilename = $"prowlarr_backup_v{BuildInfo.Version}_{dateNow:yyyy.MM.dd_HH.mm.ss}.zip";
var backupPath = Path.Combine(GetBackupFolder(backupType), backupFilename);
var backupPath = Path.Combine(backupFolder, backupFilename);
Cleanup();

View File

@@ -65,6 +65,7 @@ namespace NzbDrone.Core.Configuration
string PostgresPassword { get; }
string PostgresMainDb { get; }
string PostgresLogDb { get; }
bool TrustCgnatIpAddresses { get; }
}
public class ConfigFileProvider : IConfigFileProvider
@@ -206,13 +207,24 @@ namespace NzbDrone.Core.Configuration
if (enabled)
{
SetValue("AuthenticationMethod", AuthenticationType.Basic);
return AuthenticationType.Basic;
SetValue("AuthenticationMethod", AuthenticationType.Forms);
return AuthenticationType.Forms;
}
return Enum.TryParse<AuthenticationType>(_authOptions.Method, out var enumValue)
var value = Enum.TryParse<AuthenticationType>(_authOptions.Method, out var enumValue)
? enumValue
: GetValueEnum("AuthenticationMethod", AuthenticationType.None);
#pragma warning disable CS0618 // Type or member is obsolete
if (value == AuthenticationType.Basic)
#pragma warning restore CS0618 // Type or member is obsolete
{
SetValue("AuthenticationMethod", AuthenticationType.Forms);
return AuthenticationType.Forms;
}
return value;
}
}
@@ -273,7 +285,7 @@ namespace NzbDrone.Core.Configuration
{
var instanceName = _appOptions.InstanceName ?? GetValue("InstanceName", BuildInfo.AppName);
if (instanceName.ContainsIgnoreCase(BuildInfo.AppName))
if (instanceName.Contains(BuildInfo.AppName, StringComparison.OrdinalIgnoreCase))
{
return instanceName;
}
@@ -388,6 +400,12 @@ namespace NzbDrone.Core.Configuration
{
SetValue("EnableSsl", false);
}
#pragma warning disable CS0618 // Type or member is obsolete
if (AuthenticationMethod == AuthenticationType.Basic)
#pragma warning restore CS0618 // Type or member is obsolete
{
SetValue("AuthenticationMethod", AuthenticationType.Forms);
}
}
private void DeleteOldValues()
@@ -479,5 +497,7 @@ namespace NzbDrone.Core.Configuration
SetValue("ApiKey", GenerateApiKey());
_eventAggregator.PublishEvent(new ApiKeyChangedEvent());
}
public bool TrustCgnatIpAddresses => _authOptions.TrustCgnatIpAddresses ?? GetValueBoolean("TrustCgnatIpAddresses", false, persist: false);
}
}

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