1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-21 16:54:30 -04:00

Compare commits

..

63 Commits

Author SHA1 Message Date
Qstick
1b4a6b1309 New: Add Changes to UpdatedEvent Notifications 2022-06-04 00:02:09 -05:00
Qstick
fcebfe6759 Fixed: Duplicate changes in app updated modal
[common]
2022-06-04 00:01:56 -05:00
Qstick
f890aadffa New: Movie Added Notification 2022-06-03 23:39:28 -05:00
Qstick
a8695959f1 Cleanup Collections UI Options 2022-06-02 21:50:30 -05:00
Qstick
696bb845a5 Fixed: Speed up Collections API Endpoint 2022-06-02 21:50:30 -05:00
Qstick
301a6904c0 New: Add DB Indexes for MovieMetadata 2022-06-02 21:50:30 -05:00
ta264
8b4621db61 New: .NET 6.0.5 2022-06-02 19:48:44 -05:00
Weblate
822b597f26 Translated using Weblate (Polish) [skip ci]
Currently translated at 99.4% (1130 of 1136 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 99.9% (1135 of 1136 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1136 of 1136 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 98.4% (1118 of 1136 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 98.0% (1114 of 1136 strings)

Translated using Weblate (Norwegian Bokmål) [skip ci]

Currently translated at 15.7% (179 of 1136 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN)) [skip ci]

Currently translated at 100.0% (1136 of 1136 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 99.7% (1133 of 1136 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1136 of 1136 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 19.1% (217 of 1136 strings)

Translated using Weblate (Norwegian Bokmål) [skip ci]

Currently translated at 12.3% (140 of 1136 strings)

Translated using Weblate (Arabic) [skip ci]

Currently translated at 92.2% (1048 of 1136 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 98.5% (1119 of 1136 strings)

Translated using Weblate (Thai) [skip ci]

Currently translated at 91.8% (1043 of 1136 strings)

Translated using Weblate (Bulgarian) [skip ci]

Currently translated at 89.7% (1019 of 1136 strings)

Translated using Weblate (Hindi) [skip ci]

Currently translated at 91.8% (1043 of 1136 strings)

Translated using Weblate (Romanian) [skip ci]

Currently translated at 91.3% (1038 of 1136 strings)

Translated using Weblate (Vietnamese) [skip ci]

Currently translated at 91.8% (1043 of 1136 strings)

Translated using Weblate (Turkish) [skip ci]

Currently translated at 91.6% (1041 of 1136 strings)

Translated using Weblate (Swedish) [skip ci]

Currently translated at 92.1% (1047 of 1136 strings)

Translated using Weblate (Russian) [skip ci]

Currently translated at 97.0% (1103 of 1136 strings)

Translated using Weblate (Portuguese) [skip ci]

Currently translated at 98.2% (1116 of 1136 strings)

Translated using Weblate (Polish) [skip ci]

Currently translated at 91.7% (1042 of 1136 strings)

Translated using Weblate (Dutch) [skip ci]

Currently translated at 95.6% (1087 of 1136 strings)

Translated using Weblate (Korean) [skip ci]

Currently translated at 22.1% (252 of 1136 strings)

Translated using Weblate (Japanese) [skip ci]

Currently translated at 91.8% (1043 of 1136 strings)

Translated using Weblate (Icelandic) [skip ci]

Currently translated at 91.8% (1043 of 1136 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 98.3% (1117 of 1136 strings)

Translated using Weblate (Hebrew) [skip ci]

Currently translated at 94.8% (1077 of 1136 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 98.5% (1119 of 1136 strings)

Translated using Weblate (Greek) [skip ci]

Currently translated at 91.7% (1042 of 1136 strings)

Translated using Weblate (Danish) [skip ci]

Currently translated at 91.5% (1040 of 1136 strings)

Translated using Weblate (Czech) [skip ci]

Currently translated at 92.5% (1051 of 1136 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 95.5% (1085 of 1136 strings)

Translated using Weblate (Spanish) [skip ci]

Currently translated at 98.1% (1115 of 1136 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 97.8% (1112 of 1136 strings)

Translated using Weblate (German) [skip ci]

Currently translated at 98.2% (1116 of 1136 strings)

Update translation files  [skip ci]

Updated by "Cleanup translation files" hook in Weblate.

Update translation files  [skip ci]

Updated by "Cleanup translation files" hook in Weblate.

Translated using Weblate (Chinese (Simplified) (zh_CN)) [skip ci]

Currently translated at 99.9% (1119 of 1120 strings)

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Csaba <csab0825@gmail.com>
Co-authored-by: Gjermund Wiggen <gjermundwiggen@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Matrixlee <matrix.alax@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Pan Jarek <jsawiuk@gmail.com>
Co-authored-by: Roibabouin <boulestint@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: un110 <13735581@qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2022-06-02 19:45:55 -05:00
Qstick
737a0176d4 Fixed: Remove Collection on last Movie delete 2022-05-30 22:06:23 -05:00
Qstick
5dc541c69e Fixed: Correctly use loadash in FE Migrations
Fixes #7314
2022-05-30 21:56:36 -05:00
Qstick
a9627771e6 Fixed: Partial Revert CF Validation for more robust solution
Fixes #7319
2022-05-30 08:29:17 -05:00
ta264
5facab0744 Ensure .Mono and .Windows projects have all dependencies in build output
Fixes development on linux

[common]
2022-05-29 22:51:59 +01:00
ta264
63dde3eb89 Fix frontend monitor migration 2022-05-29 22:49:03 +01:00
Qstick
144f564076 Try to fix CF null error for imported movie files 2022-05-29 10:10:38 -05:00
Qstick
a6205c1ad4 Tweak monitor migration to avoid overwrites of valid settings 2022-05-29 10:09:40 -05:00
Qstick
64f27bca4f Fixed: Run Frontend Migration for MonitorType
FIxes #7314
2022-05-29 09:03:56 -05:00
Qstick
8a84975954 New: Improve validation errors for Custom Formats
Fixes #4733
2022-05-28 19:41:49 -05:00
Qstick
e923b2fc6c Fixed: Don't Import Files with lower CF Score 2022-05-28 19:41:49 -05:00
Qstick
a4136150d0 Fixed: Parse UHD2BD as BluRay instead of HDTV
Co-Authored-By: Gabriel Patzleiner <gabriel.patzleiner@gmail.com>
2022-05-28 18:27:14 -05:00
Qstick
1f1f3cdaa2 Fixed: Bluray 576p parsing
Fixes #7261

Co-Authored-By: Jure Merhar <703710+jmerhar@users.noreply.github.com>
2022-05-28 18:27:14 -05:00
Daniel Martin Gonzalez
bd85936a62 New: Release Group Custom Format (#7154) 2022-05-28 18:26:35 -05:00
Rafael Wille
93b2395228 Added term "brazilian" to Brazilian Portuguese parsing (#7296)
* Added term "brazilian" to Brazilian Portuguese regex
* Removed "brazilian" from Regex and added to lowerTitle.Contains() + Added Test Case for "Brazilian"
2022-05-28 18:20:38 -05:00
Servarr
14cccd3a23 Automated API Docs update 2022-05-28 18:07:50 -05:00
Mark McDowall
006c9289de New: Don't default manual import to move
Closes #7280
Closes #7309

(cherry picked from commit 0d739cd26d3b18d1456444e9ddf7e71d84e40253)
2022-05-28 18:03:16 -05:00
Mark McDowall
79cd2b2346 Fixed: Cutoff Unmet showing items above lowest accepted quality when upgrades are disabled
(cherry picked from commit c1e5b7f642d03414f7c5587d4db377ef979f2067)

Fixes #7301
Fixes #7305
2022-05-28 17:57:19 -05:00
Qstick
f80272a659 New: Collections View 2022-05-28 17:46:44 -05:00
Weblate
a158e008e9 Translated using Weblate (Portuguese (Brazil)) [skip ci]
Currently translated at 100.0% (1120 of 1120 strings)

Translated using Weblate (Hebrew) [skip ci]

Currently translated at 95.5% (1070 of 1120 strings)

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: talqwe <docbelton1@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translation: Servarr/Radarr
2022-05-28 17:01:51 -05:00
Weblate
c798987379 Translated using Weblate (Portuguese (Brazil)) [skip ci]
Currently translated at 100.0% (1120 of 1120 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1120 of 1120 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1120 of 1120 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.8% (1085 of 1120 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1118 of 1118 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.8% (1083 of 1118 strings)

Translated using Weblate (Spanish) [skip ci]

Currently translated at 99.7% (1115 of 1118 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1118 of 1118 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 100.0% (1118 of 1118 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1118 of 1118 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.6% (1081 of 1118 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.6% (1081 of 1118 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 99.4% (1112 of 1118 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN)) [skip ci]

Currently translated at 100.0% (1118 of 1118 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.0% (1074 of 1118 strings)

Update translation files  [skip ci]

Updated by "Cleanup translation files" hook in Weblate.

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.2% (1075 of 1117 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.2% (1075 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 19.3% (216 of 1117 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Dutch) [skip ci]

Currently translated at 97.4% (1088 of 1117 strings)

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Csaba <csab0825@gmail.com>
Co-authored-by: DarkFighterLuke <luca-consoli@live.it>
Co-authored-by: Francesco <francy.ammirati@hotmail.com>
Co-authored-by: Giorgio <sannagiorgio1997@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: lhquark <lhquark@gmail.com>
Co-authored-by: twolaw <twolaw@free.fr>
Co-authored-by: 無情天 <kofzhanganguo@126.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2022-05-21 08:39:00 -05:00
bakerboy448
097b46c49f New: Parse QxR Group r00t
Fixes #7290
2022-05-15 12:45:31 -05:00
Servarr
ddeb3a7840 Automated API Docs update 2022-05-13 17:45:11 -05:00
Qstick
50018d0325 New: Instance name in System/Status API endpoint 2022-05-13 23:37:53 +01:00
Qstick
a37fc0dc1f New: Instance name for Page Title 2022-05-13 23:37:53 +01:00
Robin Dadswell
39ad315e73 New: Instance Name used for Syslog 2022-05-13 23:37:53 +01:00
Robin Dadswell
0559996566 New: Set Instance Name 2022-05-13 23:37:53 +01:00
Stevie Robinson
e7d4429fe4 New: Add optional Source Title column to history
(cherry picked from commit 581fb2cb3d47d62fe16b840081647056ec77043d)
Fixes #7159
2022-05-12 21:48:22 -05:00
bakerboy448
6c494e9a92 New: Support for new Nyaa RSS Feed format
(cherry picked from commit 40ecdbc12de8b320a4d650aea65a36e8edea77d8)
2022-05-12 19:16:46 -05:00
Qstick
62faa1aad8 Fixed: Don't try to add MovieMeta if mapping fails for list items 2022-05-11 19:46:41 -05:00
Mark McDowall
907950e309 Fixed: Importing file from UNC shared folder without job folder
(cherry picked from commit 9183c6b84638e3654c3f90a80e560a06575606bb)
2022-05-08 19:05:31 -05:00
Qstick
1caced614e Fixed: No restart requirement for Refresh Monitored interval change 2022-05-08 16:11:53 -05:00
Qstick
5824ba963b Fixed: Correct User-Agent api logging 2022-05-06 08:25:34 -05:00
Qstick
7f2d5d8d10 Delete nan.json 2022-05-01 22:30:00 -05:00
Qstick
81bffe243a Delete zh_Hans.json 2022-05-01 22:29:50 -05:00
Weblate
2d6fde282a Translated using Weblate (Chinese (Simplified)) [skip ci]
Currently translated at 28.6% (320 of 1117 strings)

Translated using Weblate (Chinese (Simplified)) [skip ci]

Currently translated at 28.6% (320 of 1117 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Chinese (Simplified)) [skip ci]

Currently translated at 4.6% (52 of 1117 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Dutch) [skip ci]

Currently translated at 97.2% (1086 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 19.1% (214 of 1117 strings)

Translated using Weblate (Chinese (Simplified)) [skip ci]

Currently translated at 4.5% (51 of 1117 strings)

Translated using Weblate (Dutch) [skip ci]

Currently translated at 95.9% (1072 of 1117 strings)

Update translation files  [skip ci]

Updated by "Remove blank strings" hook in Weblate.

Translated using Weblate (Chinese (Simplified)) [skip ci]

Currently translated at 3.5% (40 of 1117 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Chinese (Simplified)) [skip ci]

Currently translated at 2.0% (23 of 1117 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 99.5% (1112 of 1117 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 97.9% (1094 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 19.0% (213 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 19.0% (213 of 1117 strings)

Translated using Weblate (Chinese (Simplified)) [skip ci]

Currently translated at 1.1% (13 of 1117 strings)

Translated using Weblate (Arabic) [skip ci]

Currently translated at 93.9% (1049 of 1117 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Thai) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Bulgarian) [skip ci]

Currently translated at 91.3% (1020 of 1117 strings)

Translated using Weblate (Hindi) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Romanian) [skip ci]

Currently translated at 93.0% (1039 of 1117 strings)

Translated using Weblate (Vietnamese) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Turkish) [skip ci]

Currently translated at 93.2% (1042 of 1117 strings)

Translated using Weblate (Swedish) [skip ci]

Currently translated at 93.8% (1048 of 1117 strings)

Translated using Weblate (Russian) [skip ci]

Currently translated at 98.8% (1104 of 1117 strings)

Translated using Weblate (Portuguese) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Polish) [skip ci]

Currently translated at 93.3% (1043 of 1117 strings)

Translated using Weblate (Dutch) [skip ci]

Currently translated at 95.7% (1070 of 1117 strings)

Translated using Weblate (Korean) [skip ci]

Currently translated at 22.2% (248 of 1117 strings)

Translated using Weblate (Japanese) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Icelandic) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Hebrew) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Greek) [skip ci]

Currently translated at 93.3% (1043 of 1117 strings)

Translated using Weblate (Danish) [skip ci]

Currently translated at 93.1% (1041 of 1117 strings)

Translated using Weblate (Czech) [skip ci]

Currently translated at 94.1% (1052 of 1117 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.5% (1078 of 1117 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 97.9% (1094 of 1117 strings)

Translated using Weblate (German) [skip ci]

Currently translated at 99.8% (1115 of 1117 strings)

Translated using Weblate (German) [skip ci]

Currently translated at 99.8% (1115 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 15.7% (176 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 15.7% (176 of 1117 strings)

Co-authored-by: AnlakHui <AnlakHui@gmail.com>
Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Csaba <csab0825@gmail.com>
Co-authored-by: EldestBard <449734150@qq.com>
Co-authored-by: Florian <sephrat.flo@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: M1C <webnar@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Zalhera <tobias.bechen@gmail.com>
Co-authored-by: andrey4korop <andrey999@i.ua>
Co-authored-by: jianjam <jianjam@qq.com>
Co-authored-by: killsover <w904202822@163.com>
Co-authored-by: lhquark <lhquark@gmail.com>
Co-authored-by: marcosteam <wdy71608161@gmail.com>
Co-authored-by: minermartijn <minermartijn@gmail.com>
Co-authored-by: neoestremi <remidu34070@hotmail.fr>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_Hans/
Translation: Servarr/Radarr
2022-04-29 10:59:36 -05:00
Qstick
3125b038d5 Fixed: Wrong translation mapping can be used for file naming and metadata
Fixes #7243
2022-04-26 19:27:07 -05:00
Qstick
89e25a6241 Fixed: Translated fields are mapped incorrectly for existing search results 2022-04-26 18:29:15 -05:00
Qstick
4db6688fe0 Fixed: UI hiding search results with duplicate GUIDs
Closes #7241

Co-Authored-By: Mark McDowall <markus101@users.noreply.github.com>
2022-04-24 13:16:20 -05:00
Qstick
4ac1aeaf06 Fixed: QBittorrent unknown download state: forcedMetaDL
Closes #7242

Co-Authored-By: Mark McDowall <markus101@users.noreply.github.com>
2022-04-24 13:14:58 -05:00
Qstick
e2ae743ee1 Fix migration 207 distinct on tmdbid only for list movie insert 2022-04-24 13:13:05 -05:00
Robin Dadswell
9ad316a6f5 Fix metadata migration 2022-04-23 16:41:43 -05:00
Servarr
b643d2e23d Automated API Docs update 2022-04-23 20:35:25 +01:00
Qstick
6a03eddda9 Rework Movie Metadata data model 2022-04-23 13:14:03 -05:00
ta264
1576bf1f17 Temporarily ignore update tests until linux-x86 released 2022-04-23 02:25:39 -05:00
ta264
6325b70e27 New: Add linux-x86 builds
[common]
2022-04-23 02:25:39 -05:00
Qstick
24206ad0a3 New: Support Plex API Path Scan (Similar to autoscan)
Closes #4640
Closes #5527
2022-04-21 22:49:09 -05:00
Mark McDowall
2fc7cbff89 Fixed: Interactive Search Filter not filtering multiple qualities in the same filter row
(cherry picked from commit c93f63cd204bf62dab3dffef6e29c8dd4c408cab)
2022-04-18 21:07:50 -05:00
Tristan Kennedy
55ef505d74 Added padding to search tab to maintain visual consistancy 2022-04-15 23:58:45 -05:00
Qstick
cabdad6306 Fixed: Update ScheduledTask cache LastStartTime on command execution 2022-04-15 18:16:01 -05:00
Qstick
8d4b2dd21b Bump Version to 4.2 2022-04-15 16:47:28 -05:00
Qstick
ad04031c99 Bump webpack packages 2022-04-14 21:08:10 -05:00
Qstick
e9a5f87e45 Remove old DotNetVersion method and dep 2022-04-14 21:06:29 -05:00
Qstick
bc6ac0cd4b Bump Monotorrent to 2.0.5
Fixes #7206
2022-04-11 19:18:01 -05:00
Qstick
c2328e4b79 Fixed: Don't die if Plex watchlist guid node is missing or null
Fixes #7213
2022-04-11 08:30:39 -05:00
Servarr
36119facf0 Automated API Docs update 2022-04-10 22:10:41 -05:00
194 changed files with 4057 additions and 1960 deletions

View File

@@ -9,13 +9,13 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '4.1.0'
majorVersion: '4.2.0'
minorVersion: $[counter('minorVersion', 2000)]
radarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
sentryOrg: 'servarr'
sentryUrl: 'https://sentry.servarr.com'
dotnetVersion: '6.0.201'
dotnetVersion: '6.0.300'
nodeVersion: '16.X'
innoVersion: '6.2.0'
windowsImage: 'windows-2022'
@@ -97,15 +97,14 @@ stages:
- bash: |
BUNDLEDVERSIONS=${AGENT_TOOLSDIRECTORY}/dotnet/sdk/${DOTNETVERSION}/Microsoft.NETCoreSdk.BundledVersions.props
echo $BUNDLEDVERSIONS
grep osx-x64 $BUNDLEDVERSIONS
if grep -q freebsd-x64 $BUNDLEDVERSIONS; then
echo "BSD already enabled"
echo "Extra platforms already enabled"
else
echo "Enabling BSD support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64/' $BUNDLEDVERSIONS
echo "Enabling extra platform support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS
fi
displayName: Enable FreeBSD Support
- bash: ./build.sh --backend --enable-bsd
displayName: Enable Extra Platform Support
- bash: ./build.sh --backend --enable-extra-platforms
displayName: Build Radarr Backend
- bash: |
find ${OUTPUTFOLDER} -type f ! -path "*/publish/*" -exec rm -rf {} \;
@@ -119,24 +118,28 @@ stages:
displayName: Publish Backend
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/win-x64/publish'
artifact: WindowsCoreTests
displayName: Publish Windows Test Package
artifact: win-x64-tests
displayName: Publish win-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-x64/publish'
artifact: LinuxCoreTests
displayName: Publish Linux Test Package
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'
artifact: LinuxMuslCoreTests
displayName: Publish Linux Musl Test Package
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'
artifact: FreebsdCoreTests
displayName: Publish FreeBSD Test Package
artifact: freebsd-x64-tests
displayName: Publish freebsd-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/osx-x64/publish'
artifact: MacCoreTests
displayName: Publish MacOS Test Package
artifact: osx-x64-tests
displayName: Publish osx-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- stage: Build_Frontend
@@ -240,7 +243,7 @@ stages:
artifactName: WindowsFrontend
targetPath: _output
displayName: Fetch Frontend
- bash: ./build.sh --packages --enable-bsd
- bash: ./build.sh --packages --enable-extra-platforms
displayName: Create Packages
- bash: |
find . -name "ffprobe" -exec chmod a+x {} \;
@@ -248,28 +251,28 @@ stages:
find . -name "Radarr.Update" -exec chmod a+x {} \;
displayName: Set executable bits
- task: ArchiveFiles@2
displayName: Create Windows Core zip
displayName: Create win-x64 zip
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).windows-core-x64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x64/net6.0
- task: ArchiveFiles@2
displayName: Create Windows x86 Core zip
displayName: Create win-x86 zip
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).windows-core-x86.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x86/net6.0
- task: ArchiveFiles@2
displayName: Create MacOS x64 Core app
displayName: Create osx-x64 app
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-app-core-x64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net6.0
- task: ArchiveFiles@2
displayName: Create MacOS x64 Core tar
displayName: Create osx-x64 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-core-x64.tar.gz'
archiveType: 'tar'
@@ -277,14 +280,14 @@ stages:
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64/net6.0
- task: ArchiveFiles@2
displayName: Create MacOS arm64 Core app
displayName: Create osx-arm64 app
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-app-core-arm64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net6.0
- task: ArchiveFiles@2
displayName: Create MacOS arm64 Core tar
displayName: Create osx-arm64 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-core-arm64.tar.gz'
archiveType: 'tar'
@@ -292,7 +295,7 @@ stages:
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net6.0
- task: ArchiveFiles@2
displayName: Create Linux Core tar
displayName: Create linux-x64 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-x64.tar.gz'
archiveType: 'tar'
@@ -300,7 +303,7 @@ stages:
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x64/net6.0
- task: ArchiveFiles@2
displayName: Create Linux Musl Core tar
displayName: Create linux-musl-x64 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-x64.tar.gz'
archiveType: 'tar'
@@ -308,7 +311,15 @@ stages:
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net6.0
- task: ArchiveFiles@2
displayName: Create ARM32 Linux Core tar
displayName: Create linux-x86 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-x86.tar.gz'
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x86/net6.0
- task: ArchiveFiles@2
displayName: Create linux-arm tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-arm.tar.gz'
archiveType: 'tar'
@@ -316,7 +327,7 @@ stages:
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm/net6.0
- task: ArchiveFiles@2
displayName: Create ARM32 Linux Musl Core tar
displayName: Create linux-musl-arm tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-arm.tar.gz'
archiveType: 'tar'
@@ -324,7 +335,7 @@ stages:
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net6.0
- task: ArchiveFiles@2
displayName: Create ARM64 Linux Core tar
displayName: Create linux-arm64 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-arm64.tar.gz'
archiveType: 'tar'
@@ -332,7 +343,7 @@ stages:
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net6.0
- task: ArchiveFiles@2
displayName: Create ARM64 Linux Musl Core tar
displayName: Create linux-musl-arm64 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-arm64.tar.gz'
archiveType: 'tar'
@@ -340,7 +351,7 @@ stages:
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net6.0
- task: ArchiveFiles@2
displayName: Create FreeBSD Core Core tar
displayName: Create freebsd-x64 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).freebsd-core-x64.tar.gz'
archiveType: 'tar'
@@ -407,22 +418,22 @@ stages:
matrix:
MacCore:
osName: 'Mac'
testName: 'MacCore'
testName: 'osx-x64'
poolName: 'Azure Pipelines'
imageName: ${{ variables.macImage }}
WindowsCore:
osName: 'Windows'
testName: 'WindowsCore'
testName: 'win-x64'
poolName: 'Azure Pipelines'
imageName: ${{ variables.windowsImage }}
LinuxCore:
osName: 'Linux'
testName: 'LinuxCore'
testName: 'linux-x64'
poolName: 'Azure Pipelines'
imageName: ${{ variables.linuxImage }}
FreebsdCore:
osName: 'Linux'
testName: 'FreebsdCore'
testName: 'freebsd-x64'
poolName: 'FreeBSD'
imageName:
@@ -441,7 +452,7 @@ stages:
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: '$(testName)Tests'
artifactName: '$(testName)-tests'
targetPath: $(testsFolder)
- powershell: Set-Service SCardSvr -StartupType Manual
displayName: Enable Windows Test Service
@@ -475,8 +486,12 @@ stages:
matrix:
alpine:
testName: 'Musl Net Core'
artifactName: LinuxMuslCoreTests
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 }}
@@ -487,9 +502,15 @@ stages:
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
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
@@ -522,7 +543,7 @@ stages:
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
variables:
pattern: 'Radarr.*.linux-core-x64.tar.gz'
artifactName: LinuxCoreTests
artifactName: linux-x64-tests
Radarr__Postgres__Host: 'localhost'
Radarr__Postgres__Port: '5432'
Radarr__Postgres__User: 'radarr'
@@ -597,17 +618,17 @@ stages:
matrix:
MacCore:
osName: 'Mac'
testName: 'MacCore'
testName: 'osx-x64'
imageName: ${{ variables.macImage }}
pattern: 'Radarr.*.osx-core-x64.tar.gz'
WindowsCore:
osName: 'Windows'
testName: 'WindowsCore'
testName: 'win-x64'
imageName: ${{ variables.windowsImage }}
pattern: 'Radarr.*.windows-core-x64.zip'
LinuxCore:
osName: 'Linux'
testName: 'LinuxCore'
testName: 'linux-x64'
imageName: ${{ variables.linuxImage }}
pattern: 'Radarr.*.linux-core-x64.tar.gz'
@@ -624,7 +645,7 @@ stages:
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: '$(testName)Tests'
artifactName: '$(testName)-tests'
targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2
displayName: Download Build Artifact
@@ -678,7 +699,7 @@ stages:
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: 'LinuxCoreTests'
artifactName: 'linux-x64-tests'
targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2
displayName: Download Build Artifact
@@ -732,7 +753,7 @@ stages:
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: 'FreebsdCoreTests'
artifactName: 'freebsd-x64-tests'
targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2
displayName: Download Build Artifact
@@ -768,10 +789,15 @@ stages:
strategy:
matrix:
alpine:
testName: 'Musl Net Core'
artifactName: LinuxMuslCoreTests
testName: 'linux-musl-x64'
artifactName: linux-musl-x64-tests
containerImage: ghcr.io/servarr/testimages:alpine
pattern: 'Radarr.*.linux-musl-core-x64.tar.gz'
linux-x86:
testName: 'linux-x86'
artifactName: linux-x86-tests
containerImage: ghcr.io/servarr/testimages:linux-x86
pattern: 'Radarr.*.linux-core-x86.tar.gz'
pool:
vmImage: ${{ variables.linuxImage }}
@@ -781,9 +807,15 @@ stages:
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
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
@@ -829,16 +861,19 @@ stages:
matrix:
Linux:
osName: 'Linux'
artifactName: 'linux-x64'
imageName: ${{ variables.linuxImage }}
pattern: 'Radarr.*.linux-core-x64.tar.gz'
failBuild: true
Mac:
osName: 'Mac'
artifactName: 'osx-x64'
imageName: ${{ variables.macImage }}
pattern: 'Radarr.*.osx-core-x64.tar.gz'
failBuild: true
Windows:
osName: 'Windows'
artifactName: 'win-x64'
imageName: ${{ variables.windowsImage }}
pattern: 'Radarr.*.windows-core-x64.zip'
failBuild: true
@@ -856,7 +891,7 @@ stages:
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: '$(osName)CoreTests'
artifactName: '$(artifactName)-tests'
targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2
displayName: Download Build Artifact

View File

@@ -25,14 +25,22 @@ UpdateVersionNumber()
fi
}
EnableBsdSupport()
EnableExtraPlatformsInSDK()
{
#todo enable sdk with
#SDK_PATH=$(dotnet --list-sdks | grep -P '5\.\d\.\d+' | head -1 | sed 's/\(5\.[0-9]*\.[0-9]*\).*\[\(.*\)\]/\2\/\1/g')
# BUNDLED_VERSIONS="${SDK_PATH}/Microsoft.NETCoreSdk.BundledVersions.props"
SDK_PATH=$(dotnet --list-sdks | grep -P '6\.\d\.\d+' | head -1 | sed 's/\(6\.[0-9]*\.[0-9]*\).*\[\(.*\)\]/\2\/\1/g')
BUNDLEDVERSIONS="${SDK_PATH}/Microsoft.NETCoreSdk.BundledVersions.props"
if grep -q freebsd-x64 $BUNDLEDVERSIONS; then
echo "Extra platforms already enabled"
else
echo "Enabling extra platform support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS
fi
}
EnableExtraPlatforms()
{
if grep -qv freebsd-x64 src/Directory.Build.props; then
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64</RuntimeIdentifiers>^g" src/Directory.Build.props
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64;linux-x86</RuntimeIdentifiers>^g" src/Directory.Build.props
fi
}
@@ -292,7 +300,8 @@ if [ $# -eq 0 ]; then
PACKAGES=YES
INSTALLER=NO
LINT=YES
ENABLE_BSD=NO
ENABLE_EXTRA_PLATFORMS=NO
ENABLE_EXTRA_PLATFORMS_IN_SDK=NO
fi
while [[ $# -gt 0 ]]
@@ -304,8 +313,12 @@ case $key in
BACKEND=YES
shift # past argument
;;
--enable-bsd)
ENABLE_BSD=YES
--enable-bsd|--enable-extra-platforms)
ENABLE_EXTRA_PLATFORMS=YES
shift # past argument
;;
--enable-extra-platforms-in-sdk)
ENABLE_EXTRA_PLATFORMS_IN_SDK=YES
shift # past argument
;;
-r|--runtime)
@@ -349,12 +362,17 @@ esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
if [ "$ENABLE_EXTRA_PLATFORMS_IN_SDK" = "YES" ];
then
EnableExtraPlatformsInSDK
fi
if [ "$BACKEND" = "YES" ];
then
UpdateVersionNumber
if [ "$ENABLE_BSD" = "YES" ];
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then
EnableBsdSupport
EnableExtraPlatforms
fi
Build
if [[ -z "$RID" || -z "$FRAMEWORK" ]];
@@ -364,9 +382,10 @@ then
PackageTests "net6.0" "linux-x64"
PackageTests "net6.0" "linux-musl-x64"
PackageTests "net6.0" "osx-x64"
if [ "$ENABLE_BSD" = "YES" ];
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then
PackageTests "net6.0" "freebsd-x64"
PackageTests "net6.0" "linux-x86"
fi
else
PackageTests "$FRAMEWORK" "$RID"
@@ -405,9 +424,10 @@ then
Package "net6.0" "linux-musl-arm"
Package "net6.0" "osx-x64"
Package "net6.0" "osx-arm64"
if [ "$ENABLE_BSD" = "YES" ];
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then
Package "net6.0" "freebsd-x64"
Package "net6.0" "linux-x86"
fi
else
Package "$FRAMEWORK" "$RID"

View File

@@ -179,6 +179,16 @@ class HistoryRow extends Component {
);
}
if (name === 'sourceTitle') {
return (
<TableRowCell
key={name}
>
{sourceTitle}
</TableRowCell>
);
}
if (name === 'details') {
return (
<TableRowCell

View File

@@ -8,7 +8,7 @@ import AppRoutes from './AppRoutes';
function App({ store, history }) {
return (
<DocumentTitle title="Radarr">
<DocumentTitle title={window.Radarr.instanceName}>
<Provider store={store}>
<ConnectedRouter history={history}>
<PageConnector>

View File

@@ -89,12 +89,12 @@ function AppUpdatedModalContent(props) {
<UpdateChanges
title={translate('New')}
changes={update.changes.new}
changes={Array.from(new Set(update.changes.new))}
/>
<UpdateChanges
title={translate('Fixed')}
changes={update.changes.fixed}
changes={Array.from(new Set(update.changes.fixed))}
/>
</div>
}

View File

@@ -86,7 +86,7 @@ class CollectionFooter extends Component {
} = this.state;
const monitoredOptions = [
{ key: NO_CHANGE, value: translate('No Change'), disabled: true },
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
{ key: 'monitored', value: translate('Monitored') },
{ key: 'unmonitored', value: translate('Unmonitored') }
];

View File

@@ -0,0 +1,50 @@
.movie {
display: flex;
align-items: stretch;
overflow: hidden;
margin: 2px 4px;
border: 1px solid $borderColor;
border-radius: 4px;
background-color: #eee;
cursor: default;
}
.movieTitle {
padding: 0 4px;
}
.movieStatus {
padding: 0 4px;
border-left: 4px;
border-left-style: solid;
background-color: $white;
color: $defaultColor;
}
.primary {
border-color: $primaryColor;
}
.danger {
border-color: $dangerColor;
}
.success {
border-color: $successColor;
}
.purple {
border-color: $purple;
}
.warning {
border-color: $warningColor;
}
.info {
border-color: $infoColor;
}
.queue {
border-color: $queueColor;
}

View File

@@ -0,0 +1,84 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import MonitorToggleButton from 'Components/MonitorToggleButton';
import getStatusStyle from 'Utilities/Movie/getStatusStyle';
import translate from 'Utilities/String/translate';
import styles from './CollectionMovieLabel.css';
class CollectionMovieLabel extends Component {
//
// Render
render() {
const {
id,
title,
status,
monitored,
isAvailable,
hasFile,
onMonitorTogglePress,
isSaving
} = this.props;
return (
<div className={styles.movie}>
<div className={styles.movieTitle}>
{
id &&
<MonitorToggleButton
monitored={monitored}
isSaving={isSaving}
onPress={onMonitorTogglePress}
/>
}
<span>
{
title
}
</span>
</div>
{
id &&
<div
className={classNames(
styles.movieStatus,
styles[getStatusStyle(status, monitored, hasFile, isAvailable, 'kinds')]
)}
>
{
hasFile ? translate('Downloaded') : translate('Missing')
}
</div>
}
</div>
);
}
}
CollectionMovieLabel.propTypes = {
id: PropTypes.number,
title: PropTypes.string.isRequired,
status: PropTypes.string,
isAvailable: PropTypes.bool,
monitored: PropTypes.bool,
hasFile: PropTypes.bool,
isSaving: PropTypes.bool.isRequired,
movieFile: PropTypes.object,
movieFileId: PropTypes.number,
onMonitorTogglePress: PropTypes.func.isRequired
};
CollectionMovieLabel.defaultProps = {
isSaving: false,
statistics: {
episodeFileCount: 0,
totalEpisodeCount: 0,
percentOfEpisodes: 0
}
};
export default CollectionMovieLabel;

View File

@@ -0,0 +1,59 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { toggleMovieMonitored } from 'Store/Actions/movieActions';
import createCollectionExistingMovieSelector from 'Store/Selectors/createCollectionExistingMovieSelector';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import CollectionMovieLabel from './CollectionMovieLabel';
function createMapStateToProps() {
return createSelector(
createDimensionsSelector(),
createCollectionExistingMovieSelector(),
(dimensions, existingMovie) => {
return {
isSmallScreen: dimensions.isSmallScreen,
isExistingMovie: !!existingMovie,
...existingMovie
};
}
);
}
const mapDispatchToProps = {
toggleMovieMonitored
};
class CollectionMovieLabelConnector extends Component {
//
// Listeners
onMonitorTogglePress = (monitored) => {
this.props.toggleMovieMonitored({
movieId: this.props.id,
monitored
});
};
//
// Render
render() {
return (
<CollectionMovieLabel
{...this.props}
onMonitorTogglePress={this.onMonitorTogglePress}
/>
);
}
}
CollectionMovieLabelConnector.propTypes = {
id: PropTypes.number,
monitored: PropTypes.bool,
toggleMovieMonitored: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(CollectionMovieLabelConnector);

View File

@@ -32,6 +32,11 @@ $hoverScale: 1.05;
display: block;
}
.labelsContainer {
display: flex;
flex-wrap: wrap;
}
.moviesContainer {
margin-bottom: 5px;
}

View File

@@ -1,8 +1,8 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Slider from 'react-slick';
import TextTruncate from 'react-text-truncate';
import EditCollectionModalConnector from 'Collection/Edit/EditCollectionModalConnector';
import Carousel from 'Components/Carousel';
import CheckInput from 'Components/Form/CheckInput';
import Icon from 'Components/Icon';
import Label from 'Components/Label';
@@ -14,8 +14,12 @@ import dimensions from 'Styles/Variables/dimensions';
import fonts from 'Styles/Variables/fonts';
import translate from 'Utilities/String/translate';
import CollectionMovieConnector from './CollectionMovieConnector';
import CollectionMovieLabelConnector from './CollectionMovieLabelConnector';
import styles from './CollectionOverview.css';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
const columnPadding = parseInt(dimensions.movieIndexColumnPadding);
const columnPaddingSmallScreen = parseInt(dimensions.movieIndexColumnPaddingSmallScreen);
const defaultFontSize = parseInt(fonts.defaultFontSize);
@@ -105,6 +109,7 @@ class CollectionOverview extends Component {
const {
showDetails,
showOverview,
showPosters,
detailedProgressBar
} = this.props.overviewOptions;
@@ -115,6 +120,15 @@ class CollectionOverview extends Component {
const contentHeight = getContentHeight(rowHeight, isSmallScreen);
const overviewHeight = contentHeight - titleRowHeight - posterHeight;
const sliderSettings = {
arrows: false,
dots: false,
infinite: false,
slidesToShow: 1,
slidesToScroll: 1,
variableWidth: true
};
return (
<div className={styles.container}>
<div className={styles.content}>
@@ -149,21 +163,25 @@ class CollectionOverview extends Component {
/>
</div>
<div className={styles.navigationButtons}>
<IconButton
name={icons.ARROW_LEFT}
title={translate('ScrollMovies')}
onPress={this.state.slider?.slickPrev}
size={20}
/>
{
showPosters &&
<div className={styles.navigationButtons}>
<IconButton
name={icons.ARROW_LEFT}
title={translate('ScrollMovies')}
onPress={this.state.slider?.slickPrev}
size={20}
/>
<IconButton
name={icons.ARROW_RIGHT}
title={translate('ScrollMovies')}
onPress={this.state.slider?.slickNext}
size={20}
/>
</div>
}
<IconButton
name={icons.ARROW_RIGHT}
title={translate('ScrollMovies')}
onPress={this.state.slider?.slickNext}
size={20}
/>
</div>
</div>
{
@@ -249,22 +267,35 @@ class CollectionOverview extends Component {
</div>
}
<div className={styles.sliderContainer}>
<Carousel setRef={this.setSliderRef}>
{movies.map((movie) => (
<div className={styles.movie} key={movie.tmdbId}>
<CollectionMovieConnector
{
showPosters ?
<div className={styles.sliderContainer}>
<Slider ref={this.setSliderRef} {...sliderSettings}>
{movies.map((movie) => (
<div className={styles.movie} key={movie.tmdbId}>
<CollectionMovieConnector
key={movie.tmdbId}
posterWidth={posterWidth}
posterHeight={posterHeight}
detailedProgressBar={detailedProgressBar}
collectionId={id}
{...movie}
/>
</div>
))}
</Slider>
</div> :
<div className={styles.labelsContainer}>
{movies.map((movie) => (
<CollectionMovieLabelConnector
key={movie.tmdbId}
posterWidth={posterWidth}
posterHeight={posterHeight}
detailedProgressBar={detailedProgressBar}
collectionId={id}
{...movie}
/>
</div>
))}
</Carousel>
</div>
))}
</div>
}
</div>
</div>

View File

@@ -30,7 +30,7 @@ function calculatePosterWidth(posterSize, isSmallScreen) {
function calculateRowHeight(posterHeight, sortKey, isSmallScreen, overviewOptions) {
const heights = [
posterHeight,
overviewOptions.showPosters ? posterHeight : 75,
isSmallScreen ? columnPaddingSmallScreen : columnPadding
];

View File

@@ -31,7 +31,8 @@ class CollectionOverviewOptionsModalContent extends Component {
detailedProgressBar: props.detailedProgressBar,
size: props.size,
showDetails: props.showDetails,
showOverview: props.showOverview
showOverview: props.showOverview,
showPosters: props.showPosters
};
}
@@ -40,7 +41,8 @@ class CollectionOverviewOptionsModalContent extends Component {
detailedProgressBar,
size,
showDetails,
showOverview
showOverview,
showPosters
} = this.props;
const state = {};
@@ -61,6 +63,10 @@ class CollectionOverviewOptionsModalContent extends Component {
state.showOverview = showOverview;
}
if (showPosters !== prevProps.showPosters) {
state.showPosters = showPosters;
}
if (!_.isEmpty(state)) {
this.setState(state);
}
@@ -99,13 +105,14 @@ class CollectionOverviewOptionsModalContent extends Component {
size,
detailedProgressBar,
showDetails,
showPosters,
showOverview
} = this.state;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
Overview Options
{translate('CollectionOptions')}
</ModalHeader>
<ModalBody>
@@ -141,6 +148,7 @@ class CollectionOverviewOptionsModalContent extends Component {
type={inputTypes.CHECK}
name="showDetails"
value={showDetails}
helpText={translate('CollectionShowDetailsHelpText')}
onChange={this.onChangeOverviewOption}
/>
</FormGroup>
@@ -152,6 +160,19 @@ class CollectionOverviewOptionsModalContent extends Component {
type={inputTypes.CHECK}
name="showOverview"
value={showOverview}
helpText={translate('CollectionShowOverviewsHelpText')}
onChange={this.onChangeOverviewOption}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('ShowPosters')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="showPosters"
value={showPosters}
helpText={translate('CollectionShowPostersHelpText')}
onChange={this.onChangeOverviewOption}
/>
</FormGroup>
@@ -175,6 +196,7 @@ CollectionOverviewOptionsModalContent.propTypes = {
size: PropTypes.string.isRequired,
showDetails: PropTypes.bool.isRequired,
showOverview: PropTypes.bool.isRequired,
showPosters: PropTypes.bool.isRequired,
onChangeOverviewOption: PropTypes.func.isRequired,
onChangeOption: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired

View File

@@ -1,37 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Slider from 'react-slick';
import styles from './Alert.css';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
function Carousel({ className, setRef, children, ...otherProps }) {
const sliderSettings = {
arrows: false,
dots: false,
infinite: false,
slidesToShow: 1,
slidesToScroll: 1,
variableWidth: true
};
return (
<Slider ref={setRef} {...sliderSettings}>
{children}
</Slider>
);
}
Carousel.propTypes = {
className: PropTypes.string.isRequired,
setRef: PropTypes.func.isRequired,
children: PropTypes.node.isRequired
};
Carousel.defaultProps = {
className: styles.alert
};
export default Carousel;

View File

@@ -14,7 +14,7 @@ function PageContent(props) {
return (
<ErrorBoundary errorComponent={PageContentError}>
<DocumentTitle title={title ? `${title} - Radarr` : 'Radarr'}>
<DocumentTitle title={title ? `${title} - ${window.Radarr.instanceName}` : window.Radarr.instanceName}>
<div className={className}>
{children}
</div>

View File

@@ -9,6 +9,7 @@ import SelectInput from 'Components/Form/SelectInput';
import SpinnerButton from 'Components/Link/SpinnerButton';
import PageContentFooter from 'Components/Page/PageContentFooter';
import { kinds } from 'Helpers/Props';
import monitorOptions from 'Utilities/Movie/monitorOptions';
import translate from 'Utilities/String/translate';
import DiscoverMovieFooterLabel from './DiscoverMovieFooterLabel';
import ExcludeMovieModal from './Exclusion/ExcludeMovieModal';
@@ -137,11 +138,6 @@ class DiscoverMovieFooter extends Component {
isExcludeMovieModalOpen
} = this.state;
const monitoredOptions = [
{ key: true, value: translate('Monitored') },
{ key: false, value: translate('Unmonitored') }
];
return (
<PageContentFooter>
<div className={styles.inputContainer}>
@@ -153,7 +149,7 @@ class DiscoverMovieFooter extends Component {
<SelectInput
name="monitor"
value={monitor}
values={monitoredOptions}
values={monitorOptions}
isDisabled={!selectedCount}
onChange={onInputChange}
/>

View File

@@ -81,6 +81,7 @@ const filterExistingFilesOptions = {
};
const importModeOptions = [
{ key: 'chooseImportMode', value: translate('ChooseImportMode'), disabled: true },
{ key: 'move', value: translate('MoveFiles') },
{ key: 'copy', value: translate('HardlinkCopyFiles') }
];

View File

@@ -1,4 +1,3 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -101,9 +100,18 @@ class InteractiveImportModalContentConnector extends Component {
};
onImportSelectedPress = (selected, importMode) => {
const {
items
} = this.props;
const files = [];
_.forEach(this.props.items, (item) => {
if (importMode === 'chooseImportMode') {
this.setState({ interactiveImportErrorMessage: 'An import mode must be selected' });
return;
}
items.forEach((item) => {
const isSelected = selected.indexOf(item.id) > -1;
if (isSelected) {

View File

@@ -7,3 +7,9 @@
.filteredMessage {
margin-top: 10px;
}
.blankpad {
padding-top: 10px;
padding-bottom: 10px;
padding-left: 2em;
}

View File

@@ -2,15 +2,12 @@ import PropTypes from 'prop-types';
import React from 'react';
import Icon from 'Components/Icon';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import FilterMenu from 'Components/Menu/FilterMenu';
import PageMenuButton from 'Components/Menu/PageMenuButton';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { align, icons, sortDirections } from 'Helpers/Props';
import { icons, sortDirections } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import InteractiveSearchFilterModalConnector from './InteractiveSearchFilterModalConnector';
import InteractiveSearchRowConnector from './InteractiveSearchRowConnector';
import styles from './InteractiveSearch.css';
import styles from './InteractiveSearchContent.css';
const columns = [
{
@@ -25,6 +22,20 @@ const columns = [
isSortable: true,
isVisible: true
},
{
name: 'releaseWeight',
label: React.createElement(Icon, { name: icons.DOWNLOAD }),
isSortable: true,
fixedSortDirection: sortDirections.ASCENDING,
isVisible: true
},
{
name: 'rejections',
label: React.createElement(Icon, { name: icons.DANGER }),
isSortable: true,
fixedSortDirection: sortDirections.ASCENDING,
isVisible: true
},
{
name: 'title',
label: translate('Title'),
@@ -88,24 +99,10 @@ const columns = [
label: React.createElement(Icon, { name: icons.FLAG }),
isSortable: true,
isVisible: true
},
{
name: 'rejections',
label: React.createElement(Icon, { name: icons.DANGER }),
isSortable: true,
fixedSortDirection: sortDirections.ASCENDING,
isVisible: true
},
{
name: 'releaseWeight',
label: React.createElement(Icon, { name: icons.DOWNLOAD }),
isSortable: true,
fixedSortDirection: sortDirections.ASCENDING,
isVisible: true
}
];
function InteractiveSearch(props) {
function InteractiveSearchContent(props) {
const {
searchPayload,
isFetching,
@@ -113,63 +110,44 @@ function InteractiveSearch(props) {
error,
totalReleasesCount,
items,
selectedFilterKey,
filters,
customFilters,
sortKey,
sortDirection,
longDateFormat,
timeFormat,
onSortPress,
onFilterSelect,
onGrabPress
} = props;
return (
<div>
<div className={styles.filterMenuContainer}>
<FilterMenu
alignMenu={align.RIGHT}
selectedFilterKey={selectedFilterKey}
filters={filters}
customFilters={customFilters}
buttonComponent={PageMenuButton}
filterModalConnectorComponent={InteractiveSearchFilterModalConnector}
filterModalConnectorComponentProps={'movies'}
onFilterSelect={onFilterSelect}
/>
</div>
{
isFetching ? <LoadingIndicator /> : null
isFetching &&
<LoadingIndicator />
}
{
!isFetching && error ?
<div>
!isFetching && !!error &&
<div className={styles.blankpad}>
{translate('UnableToLoadResultsIntSearch')}
</div> :
null
</div>
}
{
!isFetching && isPopulated && !totalReleasesCount ?
<div>
!isFetching && isPopulated && !totalReleasesCount &&
<div className={styles.blankpad}>
{translate('NoResultsFound')}
</div> :
null
</div>
}
{
!!totalReleasesCount && isPopulated && !items.length ?
<div>
!!totalReleasesCount && isPopulated && !items.length &&
<div className={styles.blankpad}>
{translate('AllResultsHiddenFilter')}
</div> :
null
</div>
}
{
isPopulated && !!items.length ?
isPopulated && !!items.length &&
<Table
columns={columns}
sortKey={sortKey}
@@ -181,7 +159,7 @@ function InteractiveSearch(props) {
items.map((item) => {
return (
<InteractiveSearchRowConnector
key={item.guid}
key={`${item.indexerId}-${item.guid}`}
{...item}
searchPayload={searchPayload}
longDateFormat={longDateFormat}
@@ -192,38 +170,32 @@ function InteractiveSearch(props) {
})
}
</TableBody>
</Table> :
null
</Table>
}
{
totalReleasesCount !== items.length && !!items.length ?
totalReleasesCount !== items.length && !!items.length &&
<div className={styles.filteredMessage}>
{translate('SomeResultsHiddenFilter')}
</div> :
null
</div>
}
</div>
);
}
InteractiveSearch.propTypes = {
InteractiveSearchContent.propTypes = {
searchPayload: PropTypes.object.isRequired,
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
totalReleasesCount: PropTypes.number.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
filters: PropTypes.arrayOf(PropTypes.object).isRequired,
customFilters: PropTypes.arrayOf(PropTypes.object).isRequired,
sortKey: PropTypes.string,
sortDirection: PropTypes.string,
longDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired,
onSortPress: PropTypes.func.isRequired,
onFilterSelect: PropTypes.func.isRequired,
onGrabPress: PropTypes.func.isRequired
};
export default InteractiveSearch;
export default InteractiveSearchContent;

View File

@@ -5,7 +5,7 @@ import { createSelector } from 'reselect';
import * as releaseActions from 'Store/Actions/releaseActions';
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import InteractiveSearch from './InteractiveSearch';
import InteractiveSearchContent from './InteractiveSearchContent';
function createMapStateToProps(appState) {
return createSelector(
@@ -48,7 +48,7 @@ function createMapDispatchToProps(dispatch, props) {
};
}
class InteractiveSearchConnector extends Component {
class InteractiveSearchContentConnector extends Component {
//
// Lifecycle
@@ -79,18 +79,18 @@ class InteractiveSearchConnector extends Component {
return (
<InteractiveSearch
<InteractiveSearchContent
{...otherProps}
/>
);
}
}
InteractiveSearchConnector.propTypes = {
InteractiveSearchContentConnector.propTypes = {
searchPayload: PropTypes.object.isRequired,
isPopulated: PropTypes.bool.isRequired,
dispatchFetchReleases: PropTypes.func.isRequired,
dispatchClearReleases: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, createMapDispatchToProps)(InteractiveSearchConnector);
export default connect(createMapStateToProps, createMapDispatchToProps)(InteractiveSearchContentConnector);

View File

@@ -1,20 +1,15 @@
.protocol {
.cell {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
}
.protocol {
composes: cell;
width: 80px;
}
.title {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
display: flex;
align-items: center;
justify-content: space-between;
word-break: break-all;
}
.indexer {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
composes: cell;
width: 85px;
}
@@ -22,9 +17,7 @@
.quality,
.customFormat,
.language {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
text-align: center;
composes: cell;
}
.language {
@@ -32,7 +25,7 @@
}
.customFormatScore {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
composes: cell;
width: 55px;
font-weight: bold;
@@ -42,26 +35,34 @@
.rejected,
.indexerFlags,
.download {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
composes: cell;
width: 50px;
}
.age,
.size {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
composes: cell;
white-space: nowrap;
}
.peers {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
composes: cell;
width: 75px;
}
.title {
composes: cell;
}
.title div {
overflow-wrap: break-word;
}
.history {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
composes: cell;
width: 75px;
}

View File

@@ -145,6 +145,46 @@ class InteractiveSearchRow extends Component {
{formatAge(age, ageHours, ageMinutes)}
</TableRowCell>
<TableRowCell className={styles.download}>
<SpinnerIconButton
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
kind={grabError ? kinds.DANGER : kinds.DEFAULT}
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
isDisabled={isGrabbed}
isSpinning={isGrabbing}
onPress={downloadAllowed ? this.onGrabPress : this.onConfirmGrabPress}
/>
</TableRowCell>
<TableRowCell className={styles.rejected}>
{
!!rejections.length &&
<Popover
anchor={
<Icon
name={icons.DANGER}
kind={kinds.DANGER}
/>
}
title={translate('ReleaseRejected')}
body={
<ul>
{
rejections.map((rejection, index) => {
return (
<li key={index}>
{rejection}
</li>
);
})
}
</ul>
}
position={tooltipPositions.BOTTOM}
/>
}
</TableRowCell>
<TableRowCell className={styles.title}>
<Link
to={infoUrl}
@@ -257,46 +297,6 @@ class InteractiveSearchRow extends Component {
}
</TableRowCell>
<TableRowCell className={styles.rejected}>
{
!!rejections.length &&
<Popover
anchor={
<Icon
name={icons.DANGER}
kind={kinds.DANGER}
/>
}
title={translate('ReleaseRejected')}
body={
<ul>
{
rejections.map((rejection, index) => {
return (
<li key={index}>
{rejection}
</li>
);
})
}
</ul>
}
position={tooltipPositions.LEFT}
/>
}
</TableRowCell>
<TableRowCell className={styles.download}>
<SpinnerIconButton
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
kind={grabError ? kinds.DANGER : kinds.DEFAULT}
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
isDisabled={isGrabbed}
isSpinning={isGrabbing}
onPress={downloadAllowed ? this.onGrabPress : this.onConfirmGrabPress}
/>
</TableRowCell>
<ConfirmModal
isOpen={this.state.isConfirmGrabModalOpen}
kind={kinds.WARNING}

View File

@@ -0,0 +1,16 @@
import React from 'react';
import InteractiveSearchContentConnector from './InteractiveSearchContentConnector';
function InteractiveSearchTable(props) {
return (
<InteractiveSearchContentConnector
searchPayload={props}
/>
);
}
InteractiveSearchTable.propTypes = {
};
export default InteractiveSearchTable;

View File

@@ -69,8 +69,7 @@ class MovieCastPoster extends Component {
const elementStyle = {
width: `${posterWidth}px`,
height: `${posterHeight}px`,
borderRadius: '5px'
height: `${posterHeight}px`
};
const contentStyle = {

View File

@@ -69,8 +69,7 @@ class MovieCrewPoster extends Component {
const elementStyle = {
width: `${posterWidth}px`,
height: `${posterHeight}px`,
borderRadius: '5px'
height: `${posterHeight}px`
};
const contentStyle = {

View File

@@ -1,7 +1,6 @@
$hoverScale: 1.05;
.content {
border-radius: 5px;
transition: all 200ms ease-in;
&:hover {

View File

@@ -2,10 +2,6 @@
flex: 1 0 auto;
}
.movie {
padding: 10px;
}
.container {
padding: 10px;
}

View File

@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Carousel from 'Components/Carousel';
import { Grid, WindowScroller } from 'react-virtualized';
import Measure from 'Components/Measure';
import dimensions from 'Styles/Variables/dimensions';
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
import MovieCreditPosterConnector from './MovieCreditPosterConnector';
@@ -168,36 +169,56 @@ class MovieCreditPosters extends Component {
render() {
const {
items,
itemComponent
items
} = this.props;
const {
posterWidth,
posterHeight
width,
columnWidth,
columnCount,
rowHeight
} = this.state;
return (
const rowCount = Math.ceil(items.length / columnCount);
<div className={styles.sliderContainer}>
<Carousel setRef={this.setSliderRef}>
{items.map((movie) => (
<div className={styles.movie} key={movie.tmdbId}>
<MovieCreditPosterConnector
key={movie.order}
component={itemComponent}
posterWidth={posterWidth}
posterHeight={posterHeight}
tmdbId={movie.personTmdbId}
personName={movie.personName}
job={movie.job}
character={movie.character}
images={movie.images}
/>
</div>
))}
</Carousel>
</div>
return (
<Measure
whitelist={['width']}
onMeasure={this.onMeasure}
>
<WindowScroller
scrollElement={undefined}
>
{({ height, registerChild, onChildScroll, scrollTop }) => {
if (!height) {
return <div />;
}
return (
<div ref={registerChild}>
<Grid
ref={this.setGridRef}
className={styles.grid}
autoHeight={true}
height={height}
columnCount={columnCount}
columnWidth={columnWidth}
rowCount={rowCount}
rowHeight={rowHeight}
width={width}
onScroll={onChildScroll}
scrollTop={scrollTop}
overscanRowCount={2}
cellRenderer={this.cellRenderer}
scrollToAlignment={'start'}
isScrollingOptOut={true}
/>
</div>
);
}
}
</WindowScroller>
</Measure>
);
}
}

View File

@@ -0,0 +1,3 @@
.alternateTitle {
white-space: nowrap;
}

View File

@@ -0,0 +1,28 @@
import PropTypes from 'prop-types';
import React from 'react';
import styles from './MovieAlternateTitles.css';
function MovieAlternateTitles({ alternateTitles }) {
return (
<ul>
{
alternateTitles.filter((x, i, a) => a.indexOf(x) === i).map((alternateTitle) => {
return (
<li
key={alternateTitle}
className={styles.alternateTitle}
>
{alternateTitle}
</li>
);
})
}
</ul>
);
}
MovieAlternateTitles.propTypes = {
alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired
};
export default MovieAlternateTitles;

View File

@@ -5,7 +5,7 @@
.header {
position: relative;
width: 100%;
height: 425px;
height: 375px;
}
.errorMessage {
@@ -39,11 +39,10 @@
}
.poster {
z-index: 2;
flex-shrink: 0;
margin-right: 35px;
width: 250px;
height: 368px;
width: 217px;
height: 319px;
}
.info {

View File

@@ -1,8 +1,8 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
import TextTruncate from 'react-text-truncate';
import FieldSet from 'Components/FieldSet';
import Icon from 'Components/Icon';
import ImdbRating from 'Components/ImdbRating';
import InfoLabel from 'Components/InfoLabel';
@@ -22,11 +22,12 @@ import Popover from 'Components/Tooltip/Popover';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props';
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector';
import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable';
import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal';
import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector';
import MovieHistoryTable from 'Movie/History/MovieHistoryTable';
import MoviePoster from 'Movie/MoviePoster';
import MovieInteractiveSearchModalConnector from 'Movie/Search/MovieInteractiveSearchModalConnector';
import MovieFileEditorTable from 'MovieFile/Editor/MovieFileEditorTable';
import ExtraFileTable from 'MovieFile/Extras/ExtraFileTable';
import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector';
@@ -80,10 +81,10 @@ class MovieDetails extends Component {
isEditMovieModalOpen: false,
isDeleteMovieModalOpen: false,
isInteractiveImportModalOpen: false,
isInteractiveSearchModalOpen: false,
allExpanded: false,
allCollapsed: false,
expandedState: {},
selectedTabIndex: 0,
overviewHeight: 0,
titleWidth: 0
};
@@ -136,14 +137,6 @@ class MovieDetails extends Component {
this.setState({ isEditMovieModalOpen: false });
};
onInteractiveSearchPress = () => {
this.setState({ isInteractiveSearchModalOpen: true });
};
onInteractiveSearchModalClose = () => {
this.setState({ isInteractiveSearchModalOpen: false });
};
onDeleteMoviePress = () => {
this.setState({
isEditMovieModalOpen: false,
@@ -305,9 +298,9 @@ class MovieDetails extends Component {
isEditMovieModalOpen,
isDeleteMovieModalOpen,
isInteractiveImportModalOpen,
isInteractiveSearchModalOpen,
overviewHeight,
titleWidth
titleWidth,
selectedTabIndex
} = this.state;
const marqueeWidth = isSmallScreen ? titleWidth : (titleWidth - 150);
@@ -333,14 +326,6 @@ class MovieDetails extends Component {
onPress={onSearchPress}
/>
<PageToolbarButton
label={translate('InteractiveSearch')}
iconName={icons.INTERACTIVE}
isSpinning={isSearching}
title={undefined}
onPress={this.onInteractiveSearchPress}
/>
<PageToolbarSeparator />
<PageToolbarButton
@@ -666,39 +651,101 @@ class MovieDetails extends Component {
</div>
}
<FieldSet legend={translate('History')}>
<MovieHistoryTable
movieId={id}
/>
</FieldSet>
<Tabs selectedIndex={this.state.tabIndex} onSelect={this.onTabSelect}>
<TabList
className={styles.tabList}
>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('History')}
</Tab>
<FieldSet legend={translate('Files')}>
<MovieFileEditorTable
movieId={id}
/>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Search')}
</Tab>
<ExtraFileTable
movieId={id}
/>
</FieldSet>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Files')}
</Tab>
<FieldSet legend={translate('Cast')}>
<MovieCastPostersConnector
isSmallScreen={isSmallScreen}
/>
</FieldSet>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Titles')}
</Tab>
<FieldSet legend={translate('Crew')}>
<MovieCrewPostersConnector
isSmallScreen={isSmallScreen}
/>
</FieldSet>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Cast')}
</Tab>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Crew')}
</Tab>
{
selectedTabIndex === 1 &&
<div className={styles.filterIcon}>
<InteractiveSearchFilterMenuConnector />
</div>
}
</TabList>
<TabPanel>
<MovieHistoryTable
movieId={id}
/>
</TabPanel>
<TabPanel>
<InteractiveSearchTable
movieId={id}
/>
</TabPanel>
<TabPanel>
<MovieFileEditorTable
movieId={id}
/>
<ExtraFileTable
movieId={id}
/>
</TabPanel>
<TabPanel>
<MovieTitlesTable
movieId={id}
/>
</TabPanel>
<TabPanel>
<MovieCastPostersConnector
isSmallScreen={isSmallScreen}
/>
</TabPanel>
<TabPanel>
<MovieCrewPostersConnector
isSmallScreen={isSmallScreen}
/>
</TabPanel>
</Tabs>
<FieldSet legend={translate('Titles')}>
<MovieTitlesTable
movieId={id}
/>
</FieldSet>
</div>
<OrganizePreviewModalConnector
@@ -730,12 +777,6 @@ class MovieDetails extends Component {
showImportMode={false}
onModalClose={this.onInteractiveImportModalClose}
/>
<MovieInteractiveSearchModalConnector
isOpen={isInteractiveSearchModalOpen}
movieId={id}
onModalClose={this.onInteractiveSearchModalClose}
/>
</PageContentBody>
</PageContent>
);

View File

@@ -1,9 +0,0 @@
.container {
border: 1px solid $borderColor;
border-radius: 4px;
background-color: $white;
&:last-of-type {
margin-bottom: 0;
}
}

View File

@@ -1,6 +1,5 @@
import React from 'react';
import MovieTitlesTableContentConnector from './MovieTitlesTableContentConnector';
import styles from './MovieTitlesTable.css';
function MovieTitlesTable(props) {
const {
@@ -8,11 +7,9 @@ function MovieTitlesTable(props) {
} = props;
return (
<div className={styles.container}>
<MovieTitlesTableContentConnector
{...otherProps}
/>
</div>
<MovieTitlesTableContentConnector
{...otherProps}
/>
);
}

View File

@@ -1,9 +0,0 @@
.container {
border: 1px solid $borderColor;
border-radius: 4px;
background-color: $white;
&:last-of-type {
margin-bottom: 0;
}
}

View File

@@ -1,6 +1,5 @@
import React from 'react';
import MovieHistoryTableContentConnector from './MovieHistoryTableContentConnector';
import styles from './MovieHistoryTable.css';
function MovieHistoryTable(props) {
const {
@@ -8,11 +7,9 @@ function MovieHistoryTable(props) {
} = props;
return (
<div className={styles.container}>
<MovieHistoryTableContentConnector
{...otherProps}
/>
</div>
<MovieHistoryTableContentConnector
{...otherProps}
/>
);
}

View File

@@ -1,35 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import MovieInteractiveSearchModalContent from './MovieInteractiveSearchModalContent';
function MovieInteractiveSearchModal(props) {
const {
isOpen,
movieId,
onModalClose
} = props;
return (
<Modal
isOpen={isOpen}
closeOnBackgroundClick={false}
onModalClose={onModalClose}
size={sizes.EXTRA_LARGE}
>
<MovieInteractiveSearchModalContent
movieId={movieId}
onModalClose={onModalClose}
/>
</Modal>
);
}
MovieInteractiveSearchModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
movieId: PropTypes.number.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default MovieInteractiveSearchModal;

View File

@@ -1,15 +0,0 @@
import { connect } from 'react-redux';
import { cancelFetchReleases, clearReleases } from 'Store/Actions/releaseActions';
import MovieInteractiveSearchModal from './MovieInteractiveSearchModal';
function createMapDispatchToProps(dispatch, props) {
return {
onModalClose() {
dispatch(cancelFetchReleases());
dispatch(clearReleases());
props.onModalClose();
}
};
}
export default connect(null, createMapDispatchToProps)(MovieInteractiveSearchModal);

View File

@@ -1,45 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Button from 'Components/Link/Button';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { scrollDirections } from 'Helpers/Props';
import InteractiveSearchConnector from 'InteractiveSearch/InteractiveSearchConnector';
function MovieInteractiveSearchModalContent(props) {
const {
movieId,
onModalClose
} = props;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
Interactive Search
</ModalHeader>
<ModalBody scrollDirection={scrollDirections.BOTH}>
<InteractiveSearchConnector
searchPayload={{
movieId
}}
/>
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
);
}
MovieInteractiveSearchModalContent.propTypes = {
movieId: PropTypes.number.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default MovieInteractiveSearchModalContent;

View File

@@ -1,4 +1,5 @@
.container {
margin-top: 20px;
border: 1px solid $borderColor;
border-radius: 4px;
background-color: $white;

View File

@@ -65,10 +65,10 @@ function DownloadClientOptions(props) {
<FormInputGroup
type={inputTypes.NUMBER}
name="checkForFinishedDownloadInterval"
min={0}
min={1}
max={120}
unit="minutes"
helpText={translate('HelpText')}
helpText={translate('RefreshMonitoredIntervalHelpText')}
onChange={onInputChange}
{...settings.checkForFinishedDownloadInterval}
/>

View File

@@ -20,6 +20,7 @@ function HostSettings(props) {
bindAddress,
port,
urlBase,
instanceName,
enableSsl,
sslPort,
sslCertPath,
@@ -73,6 +74,22 @@ function HostSettings(props) {
/>
</FormGroup>
<FormGroup
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>{translate('InstanceName')}</FormLabel>
<FormInputGroup
type={inputTypes.TEXT}
name="instanceName"
helpText={translate('InstanceNameHelpText')}
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
onChange={onInputChange}
{...instanceName}
/>
</FormGroup>
<FormGroup
advancedSettings={advancedSettings}
isAdvanced={true}

View File

@@ -116,7 +116,7 @@ function IndexerOptions(props) {
min={0}
max={120}
unit="minutes"
helpText={translate('HelpText')}
helpText={translate('RssSyncHelpText')}
helpTextWarning={translate('RSSSyncIntervalHelpTextWarning')}
helpLink="https://wiki.servarr.com/radarr/faq#how-does-radarr-work"
onChange={onInputChange}

View File

@@ -59,6 +59,7 @@ class Notification extends Component {
onDownload,
onUpgrade,
onRename,
onMovieAdded,
onMovieDelete,
onMovieFileDelete,
onMovieFileDeleteForUpgrade,
@@ -68,6 +69,7 @@ class Notification extends Component {
supportsOnDownload,
supportsOnUpgrade,
supportsOnRename,
supportsOnMovieAdded,
supportsOnMovieDelete,
supportsOnMovieFileDelete,
supportsOnMovieFileDeleteForUpgrade,
@@ -117,6 +119,14 @@ class Notification extends Component {
null
}
{
supportsOnMovieAdded && onMovieAdded ?
<Label kind={kinds.SUCCESS}>
{translate('OnMovieAdded')}
</Label> :
null
}
{
supportsOnHealthIssue && onHealthIssue ?
<Label kind={kinds.SUCCESS}>
@@ -196,6 +206,7 @@ Notification.propTypes = {
onDownload: PropTypes.bool.isRequired,
onUpgrade: PropTypes.bool.isRequired,
onRename: PropTypes.bool.isRequired,
onMovieAdded: PropTypes.bool.isRequired,
onMovieDelete: PropTypes.bool.isRequired,
onMovieFileDelete: PropTypes.bool.isRequired,
onMovieFileDeleteForUpgrade: PropTypes.bool.isRequired,
@@ -208,6 +219,7 @@ Notification.propTypes = {
supportsOnMovieFileDeleteForUpgrade: PropTypes.bool.isRequired,
supportsOnUpgrade: PropTypes.bool.isRequired,
supportsOnRename: PropTypes.bool.isRequired,
supportsOnMovieAdded: PropTypes.bool.isRequired,
supportsOnHealthIssue: PropTypes.bool.isRequired,
supportsOnApplicationUpdate: PropTypes.bool.isRequired,
onConfirmDeleteNotification: PropTypes.func.isRequired

View File

@@ -19,6 +19,7 @@ function NotificationEventItems(props) {
onDownload,
onUpgrade,
onRename,
onMovieAdded,
onMovieDelete,
onMovieFileDelete,
onMovieFileDeleteForUpgrade,
@@ -28,6 +29,7 @@ function NotificationEventItems(props) {
supportsOnDownload,
supportsOnUpgrade,
supportsOnRename,
supportsOnMovieAdded,
supportsOnMovieDelete,
supportsOnMovieFileDelete,
supportsOnMovieFileDeleteForUpgrade,
@@ -92,6 +94,17 @@ function NotificationEventItems(props) {
/>
</div>
<div>
<FormInputGroup
type={inputTypes.CHECK}
name="onMovieAdded"
helpText={translate('OnMovieAddedHelpText')}
isDisabled={!supportsOnMovieAdded.value}
{...onMovieAdded}
onChange={onInputChange}
/>
</div>
<div>
<FormInputGroup
type={inputTypes.CHECK}

View File

@@ -106,6 +106,7 @@ export default {
selectedSchema.onDownload = selectedSchema.supportsOnDownload;
selectedSchema.onUpgrade = selectedSchema.supportsOnUpgrade;
selectedSchema.onRename = selectedSchema.supportsOnRename;
selectedSchema.onMovieAdded = selectedSchema.supportsOnMovieAdded;
selectedSchema.onMovieDelete = selectedSchema.supportsOnMovieDelete;
selectedSchema.onMovieFileDelete = selectedSchema.supportsOnMovieFileDelete;
selectedSchema.onMovieFileDeleteForUpgrade = selectedSchema.supportsOnMovieFileDeleteForUpgrade;

View File

@@ -79,6 +79,11 @@ export const defaultState = {
label: translate('ReleaseGroup'),
isVisible: false
},
{
name: 'sourceTitle',
label: translate('SourceTitle'),
isVisible: false
},
{
name: 'details',
columnLabel: translate('Details'),

View File

@@ -30,7 +30,7 @@ export const defaultState = {
sortKey: 'quality',
sortDirection: sortDirections.DESCENDING,
recentFolders: [],
importMode: 'move',
importMode: 'chooseImportMode',
sortPredicates: {
relativePath: function(item, direction) {
const relativePath = item.relativePath;

View File

@@ -40,7 +40,8 @@ export const defaultState = {
detailedProgressBar: false,
size: 'medium',
showDetails: true,
showOverview: true
showOverview: true,
showPosters: true
},
defaults: {

View File

@@ -1,7 +1,9 @@
import migrateBlacklistToBlocklist from './migrateBlacklistToBlocklist';
import migrateMonitorToEnum from './migrateMonitorToEnum';
import migratePreDbToReleased from './migratePreDbToReleased';
export default function migrate(persistedState) {
migrateBlacklistToBlocklist(persistedState);
migratePreDbToReleased(persistedState);
migrateMonitorToEnum(persistedState);
}

View File

@@ -1,26 +1,26 @@
import get from 'lodash';
import _ from 'lodash';
export default function migrateMonitorToEnum(persistedState) {
const addMovie = get(persistedState, 'addMovie.defaults.monitor');
const discoverMovie = get(persistedState, 'discoverMovie.defaults.monitor');
const addMovie = _.get(persistedState, 'addMovie.defaults.monitor');
const discoverMovie = _.get(persistedState, 'discoverMovie.defaults.monitor');
if (!addMovie && !discoverMovie) {
return;
if (addMovie) {
if (addMovie === 'true') {
persistedState.addMovie.defaults.monitor = 'movieOnly';
}
if (addMovie === 'false') {
persistedState.addMovie.defaults.monitor = 'none';
}
}
if (addMovie === true) {
persistedState.addMovie.defaults.monitor = 'movieOnly';
}
if (discoverMovie) {
if (discoverMovie === 'true') {
persistedState.discoverMovie.defaults.monitor = 'movieOnly';
}
if (discoverMovie === true) {
persistedState.discoverMovie.defaults.monitor = 'movieOnly';
}
if (addMovie === false) {
persistedState.addMovie.defaults.minimumAvailability = 'none';
}
if (discoverMovie === false) {
persistedState.discoverMovie.defaults.minimumAvailability = 'none';
if (discoverMovie === 'false') {
persistedState.discoverMovie.defaults.monitor = 'none';
}
}
}

View File

@@ -1,8 +1,8 @@
import get from 'lodash';
import _ from 'lodash';
export default function migratePreDbToReleased(persistedState) {
const addMovie = get(persistedState, 'addMovie.defaults.minimumAvailability');
const discoverMovie = get(persistedState, 'discoverMovie.defaults.minimumAvailability');
const addMovie = _.get(persistedState, 'addMovie.defaults.minimumAvailability');
const discoverMovie = _.get(persistedState, 'discoverMovie.defaults.minimumAvailability');
if (!addMovie && !discoverMovie) {
return;

View File

@@ -44,7 +44,14 @@ function filter(items, state) {
const predicate = filterPredicates[key];
if (Array.isArray(value)) {
accepted = value.some((v) => predicate(item, v, type));
if (
type === filterTypes.NOT_CONTAINS ||
type === filterTypes.NOT_EQUAL
) {
accepted = value.every((v) => predicate(item, v, type));
} else {
accepted = value.some((v) => predicate(item, v, type));
}
} else {
accepted = predicate(item, value, type);
}

View File

@@ -30,7 +30,7 @@
"@fortawesome/free-regular-svg-icons": "6.1.0",
"@fortawesome/free-solid-svg-icons": "6.1.0",
"@fortawesome/react-fontawesome": "0.1.18",
"@microsoft/signalr": "6.0.3",
"@microsoft/signalr": "6.0.5",
"@sentry/browser": "6.18.2",
"@sentry/integrations": "6.18.2",
"classnames": "2.3.1",
@@ -45,7 +45,7 @@
"jquery": "3.6.0",
"lodash": "4.17.21",
"mobile-detect": "1.4.5",
"moment": "2.29.1",
"moment": "2.29.2",
"mousetrap": "1.6.5",
"normalize.css": "8.0.1",
"prop-types": "15.7.2",
@@ -101,8 +101,8 @@
"babel-loader": "8.2.3",
"babel-plugin-inline-classnames": "2.0.1",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
"core-js": "3.11.0",
"css-loader": "5.2.4",
"core-js": "3.12.1",
"css-loader": "6.5.1",
"eslint": "8.11.0",
"eslint-plugin-filenames": "1.3.2",
"eslint-plugin-import": "2.25.4",
@@ -117,22 +117,22 @@
"mini-css-extract-plugin": "1.5.0",
"postcss": "8.2.12",
"postcss-color-function": "4.1.0",
"postcss-loader": "5.2.0",
"postcss-mixins": "7.0.3",
"postcss-nested": "5.0.5",
"postcss-loader": "6.2.0",
"postcss-mixins": "8.1.0",
"postcss-nested": "5.0.6",
"postcss-simple-vars": "6.0.3",
"postcss-url": "10.1.3",
"require-nocache": "1.0.0",
"rimraf": "3.0.2",
"run-sequence": "2.2.1",
"streamqueue": "1.1.2",
"style-loader": "2.0.0",
"style-loader": "3.3.1",
"stylelint": "14.6.0",
"stylelint-order": "5.0.0",
"url-loader": "4.1.1",
"webpack": "5.35.1",
"webpack-cli": "4.6.0",
"webpack-livereload-plugin": "3.0.1",
"webpack": "5.64.2",
"webpack-cli": "4.9.1",
"webpack-livereload-plugin": "3.0.2",
"worker-loader": "3.0.8"
}
}

View File

@@ -90,7 +90,7 @@
<!-- Standard testing packages -->
<ItemGroup Condition="'$(TestProject)'=='true'">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageReference Include="NunitXml.TestLogger" Version="3.0.117" />

View File

@@ -1,5 +1,4 @@
using System;
using Microsoft.Win32;
namespace NzbDrone.Common.EnvironmentInfo
{
@@ -51,78 +50,5 @@ namespace NzbDrone.Common.EnvironmentInfo
{
return _version;
}
private static Version GetDotNetVersion()
{
try
{
const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
using (var ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
{
if (ndpKey == null)
{
return new Version(4, 0);
}
var releaseKey = (int)ndpKey.GetValue("Release");
if (releaseKey >= 528040)
{
return new Version(4, 8, 0);
}
if (releaseKey >= 461808)
{
return new Version(4, 7, 2);
}
if (releaseKey >= 461308)
{
return new Version(4, 7, 1);
}
if (releaseKey >= 460798)
{
return new Version(4, 7);
}
if (releaseKey >= 394802)
{
return new Version(4, 6, 2);
}
if (releaseKey >= 394254)
{
return new Version(4, 6, 1);
}
if (releaseKey >= 393295)
{
return new Version(4, 6);
}
if (releaseKey >= 379893)
{
return new Version(4, 5, 2);
}
if (releaseKey >= 378675)
{
return new Version(4, 5, 1);
}
if (releaseKey >= 378389)
{
return new Version(4, 5);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Couldnt get .NET framework version: " + ex.ToString());
}
return new Version(4, 0);
}
}
}

View File

@@ -13,14 +13,13 @@
<PackageReference Include="Sentry" Version="3.15.0" />
<PackageReference Include="NLog.Targets.Syslog" Version="6.0.3" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="System.Text.Json" Version="6.0.2" />
<PackageReference Include="System.Text.Json" Version="6.0.4" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
<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.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="EnsureThat\Resources\ExceptionMessages.Designer.cs">

View File

@@ -0,0 +1,347 @@
using System;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.Datastore.Migration
{
[TestFixture]
public class movie_metadataFixture : MigrationTest<movie_metadata>
{
[Test]
public void should_add_metadata_from_movie_and_link_back_to_movie()
{
var db = WithMigrationTestDb(c =>
{
c.Insert.IntoTable("Movies").Row(new
{
Monitored = true,
Title = "Title",
CleanTitle = "CleanTitle",
Status = 3,
MinimumAvailability = 4,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Recommendations = new[] { 1 }.ToJson(),
Runtime = 90,
OriginalLanguage = 1,
ProfileId = 1,
MovieFileId = 0,
Path = string.Format("/Movies/{0}", "Title"),
TitleSlug = 123456,
TmdbId = 132456,
Added = DateTime.UtcNow,
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
LastInfoSync = DateTime.UtcNow,
});
});
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
metadata.Should().HaveCount(1);
metadata.First().TmdbId.Should().Be(132456);
metadata.First().Title.Should().Be("Title");
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"Movies\"");
movies.Should().HaveCount(1);
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
}
[Test]
public void should_link_metadata_to_credits()
{
var db = WithMigrationTestDb(c =>
{
c.Insert.IntoTable("Movies").Row(new
{
Id = 5,
Monitored = true,
Title = "Title",
CleanTitle = "CleanTitle",
Status = 3,
MinimumAvailability = 4,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Recommendations = new[] { 1 }.ToJson(),
Runtime = 90,
OriginalLanguage = 1,
ProfileId = 1,
MovieFileId = 0,
Path = string.Format("/Movies/{0}", "Title"),
TitleSlug = 123456,
TmdbId = 132456,
Added = DateTime.UtcNow,
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
LastInfoSync = DateTime.UtcNow,
});
c.Insert.IntoTable("Credits").Row(new
{
MovieId = 5,
CreditTmdbId = 123,
PersonTmdbId = 456,
Order = 1,
Type = 1,
Name = "Some Person",
Images = new[] { new { CoverType = "Poster" } }.ToJson()
});
});
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
metadata.Should().HaveCount(1);
metadata.First().TmdbId.Should().Be(132456);
metadata.First().Title.Should().Be("Title");
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"Credits\"");
movies.Should().HaveCount(1);
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
}
[Test]
public void should_link_metadata_to_alt_title()
{
var db = WithMigrationTestDb(c =>
{
c.Insert.IntoTable("Movies").Row(new
{
Id = 5,
Monitored = true,
Title = "Title",
CleanTitle = "CleanTitle",
Status = 3,
MinimumAvailability = 4,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Recommendations = new[] { 1 }.ToJson(),
Runtime = 90,
OriginalLanguage = 1,
ProfileId = 1,
MovieFileId = 0,
Path = string.Format("/Movies/{0}", "Title"),
TitleSlug = 123456,
TmdbId = 132456,
Added = DateTime.UtcNow,
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
LastInfoSync = DateTime.UtcNow,
});
c.Insert.IntoTable("AlternativeTitles").Row(new
{
MovieId = 5,
Title = "Some Alt",
CleanTitle = "somealt",
SourceType = 1,
SourceId = 1,
Votes = 0,
VoteCount = 0,
Language = 1
});
});
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
metadata.Should().HaveCount(1);
metadata.First().TmdbId.Should().Be(132456);
metadata.First().Title.Should().Be("Title");
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"AlternativeTitles\"");
movies.Should().HaveCount(1);
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
}
[Test]
public void should_link_metadata_to_translation()
{
var db = WithMigrationTestDb(c =>
{
c.Insert.IntoTable("Movies").Row(new
{
Id = 5,
Monitored = true,
Title = "Title",
CleanTitle = "CleanTitle",
Status = 3,
MinimumAvailability = 4,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Recommendations = new[] { 1 }.ToJson(),
Runtime = 90,
OriginalLanguage = 1,
ProfileId = 1,
MovieFileId = 0,
Path = string.Format("/Movies/{0}", "Title"),
TitleSlug = 123456,
TmdbId = 132456,
Added = DateTime.UtcNow,
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
LastInfoSync = DateTime.UtcNow,
});
c.Insert.IntoTable("MovieTranslations").Row(new
{
MovieId = 5,
Title = "Some Trans",
Language = 1
});
});
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
metadata.Should().HaveCount(1);
metadata.First().TmdbId.Should().Be(132456);
metadata.First().Title.Should().Be("Title");
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"MovieTranslations\"");
movies.Should().HaveCount(1);
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
}
[Test]
public void should_add_metadata_from_list_and_link_back()
{
var db = WithMigrationTestDb(c =>
{
c.Insert.IntoTable("ImportListMovies").Row(new
{
Title = "Title",
Status = 3,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Runtime = 90,
TmdbId = 123456,
ListId = 4,
Translations = new[] { new { } }.ToJson(),
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
});
});
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
metadata.Should().HaveCount(1);
metadata.First().TmdbId.Should().Be(123456);
metadata.First().Title.Should().Be("Title");
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"ImportListMovies\"");
movies.Should().HaveCount(1);
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
}
[Test]
public void should_not_duplicate_metadata()
{
var db = WithMigrationTestDb(c =>
{
c.Insert.IntoTable("Movies").Row(new
{
Monitored = true,
Title = "Title",
CleanTitle = "CleanTitle",
Status = 3,
MinimumAvailability = 4,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Recommendations = new[] { 1 }.ToJson(),
Runtime = 90,
OriginalLanguage = 1,
ProfileId = 1,
MovieFileId = 0,
Path = string.Format("/Movies/{0}", "Title"),
TitleSlug = 123456,
TmdbId = 123456,
Added = DateTime.UtcNow,
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
LastInfoSync = DateTime.UtcNow,
});
c.Insert.IntoTable("ImportListMovies").Row(new
{
Title = "Title",
Status = 3,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Runtime = 90,
TmdbId = 123456,
ListId = 4,
Translations = new[] { new { } }.ToJson(),
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
});
});
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
metadata.Should().HaveCount(1);
metadata.First().TmdbId.Should().Be(123456);
metadata.First().Title.Should().Be("Title");
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"Movies\"");
movies.Should().HaveCount(1);
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
var listMovies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"ImportListMovies\"");
listMovies.Should().HaveCount(1);
listMovies.First().MovieMetadataId.Should().Be(metadata.First().Id);
}
[Test]
public void should_not_duplicate_metadata_from_lists()
{
var db = WithMigrationTestDb(c =>
{
c.Insert.IntoTable("ImportListMovies").Row(new
{
Title = "Title",
Overview = "Overview 1",
Status = 3,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Runtime = 90,
TmdbId = 123456,
ListId = 4,
Translations = new[] { new { } }.ToJson(),
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
});
c.Insert.IntoTable("ImportListMovies").Row(new
{
Title = "Title",
Overview = "Overview 2",
Status = 3,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Runtime = 90,
TmdbId = 123456,
ListId = 5,
Translations = new[] { new { } }.ToJson(),
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
});
});
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
metadata.Should().HaveCount(1);
metadata.First().TmdbId.Should().Be(123456);
metadata.First().Title.Should().Be("Title");
var listMovies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"ImportListMovies\"");
listMovies.Should().HaveCount(2);
listMovies.First().MovieMetadataId.Should().Be(metadata.First().Id);
}
}
public class MovieMetadata207
{
public int Id { get; set; }
public int TmdbId { get; set; }
public string Title { get; set; }
public bool Monitored { get; set; }
}
public class Movie207
{
public int Id { get; set; }
public int MovieMetadataId { get; set; }
}
}

View File

@@ -0,0 +1,66 @@
<rss xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:nyaa="https://nyaa.si/xmlns/nyaa" version="2.0">
<channel>
<title>Nyaa - Home - Torrent File RSS</title>
<description>RSS Feed for Home</description>
<link>https://nyaa.si/</link>
<atom:link href="https://nyaa.si/?page=rss" rel="self" type="application/rss+xml"/>
<item>
<title>[Foxy-Subs] Mahouka Koukou no Yuutousei - 08 [720p] [3194D881].mkv</title>
<link>https://nyaa.si/download/1424896.torrent</link>
<guid isPermaLink="true">https://nyaa.si/view/1424896</guid>
<pubDate>Tue, 24 Aug 2021 22:18:46 -0000</pubDate>
<nyaa:seeders>4</nyaa:seeders>
<nyaa:leechers>3</nyaa:leechers>
<nyaa:downloads>2</nyaa:downloads>
<nyaa:infoHash>e8ca5e20eca876339f41c3d9e95ea66c1d7caaee</nyaa:infoHash>
<nyaa:categoryId>1_3</nyaa:categoryId>
<nyaa:category>Anime - Non-English-translated</nyaa:category>
<nyaa:size>609.6 MiB</nyaa:size>
<nyaa:comments>0</nyaa:comments>
<nyaa:trusted>No</nyaa:trusted>
<nyaa:remake>No</nyaa:remake>
<description>
<![CDATA[ <a href="https://nyaa.si/view/1424896">#1424896 | [Foxy-Subs] Mahouka Koukou no Yuutousei - 08 [720p] [3194D881].mkv</a> | 609.6 MiB | Anime - Non-English-translated | E8CA5E20ECA876339F41C3D9E95EA66C1D7CAAEE ]]>
</description>
</item>
<item>
<title>Macross Zero (BDRip 1920x1080p x265 HEVC TrueHD, FLAC 5.1+2.0)[sxales]</title>
<link>https://nyaa.si/download/1424895.torrent</link>
<guid isPermaLink="true">https://nyaa.si/view/1424895</guid>
<pubDate>Tue, 24 Aug 2021 22:03:11 -0000</pubDate>
<nyaa:seeders>23</nyaa:seeders>
<nyaa:leechers>32</nyaa:leechers>
<nyaa:downloads>17</nyaa:downloads>
<nyaa:infoHash>26f37f26d5b3475b41a98dc575fabfa6f8d32a76</nyaa:infoHash>
<nyaa:categoryId>1_2</nyaa:categoryId>
<nyaa:category>Anime - English-translated</nyaa:category>
<nyaa:size>5.7 GiB</nyaa:size>
<nyaa:comments>2</nyaa:comments>
<nyaa:trusted>No</nyaa:trusted>
<nyaa:remake>No</nyaa:remake>
<description>
<![CDATA[ <a href="https://nyaa.si/view/1424895">#1424895 | Macross Zero (BDRip 1920x1080p x265 HEVC TrueHD, FLAC 5.1+2.0)[sxales]</a> | 5.7 GiB | Anime - English-translated | 26F37F26D5B3475B41A98DC575FABFA6F8D32A76 ]]>
</description>
</item>
<item>
<title>Fumetsu no Anata e - 19 [WEBDL 1080p] Ukr DVO</title>
<link>https://nyaa.si/download/1424887.torrent</link>
<guid isPermaLink="true">https://nyaa.si/view/1424887</guid>
<pubDate>Tue, 24 Aug 2021 21:23:06 -0000</pubDate>
<nyaa:seeders>5</nyaa:seeders>
<nyaa:leechers>4</nyaa:leechers>
<nyaa:downloads>4</nyaa:downloads>
<nyaa:infoHash>3e4300e24b39983802162877755aab4380bd137a</nyaa:infoHash>
<nyaa:categoryId>1_3</nyaa:categoryId>
<nyaa:category>Anime - Non-English-translated</nyaa:category>
<nyaa:size>1.4 GiB</nyaa:size>
<nyaa:comments>0</nyaa:comments>
<nyaa:trusted>No</nyaa:trusted>
<nyaa:remake>No</nyaa:remake>
<description>
<![CDATA[ <a href="https://nyaa.si/view/1424887">#1424887 | Fumetsu no Anata e - 19 [WEBDL 1080p] Ukr DVO</a> | 1.4 GiB | Anime - Non-English-translated | 3E4300E24B39983802162877755AAB4380BD137A ]]>
</description>
</item>
</channel>
</rss>

View File

@@ -35,6 +35,11 @@
"title": "Avengers: Endgame",
"year": 2019,
"Guid": []
},
{
"type": "movie",
"title": "Avengers",
"year": 2005
}
]
}

View File

@@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
}
[Test]
public void should_not_delete_unorphaned_credit_items()
public void should_not_delete_unorphaned_collection_items()
{
var collection = Builder<MovieCollection>.CreateNew()
.With(h => h.Id = 3)

View File

@@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
.Returns(_movie);
Mocker.GetMock<IMovieTranslationService>()
.Setup(s => s.GetAllTranslationsForMovie(It.IsAny<int>()))
.Setup(s => s.GetAllTranslationsForMovieMetadata(It.IsAny<int>()))
.Returns(new List<MovieTranslation>());
}

View File

@@ -25,7 +25,9 @@ namespace NzbDrone.Core.Test.IndexerTests.NyaaTests
};
}
[Test]
/* [Test]
// Legacy Nyaa feed test
public void should_parse_recent_feed_from_Nyaa()
{
var recentFeed = ReadAllText(@"Files/Indexers/Nyaa/Nyaa.xml");
@@ -53,6 +55,35 @@ namespace NzbDrone.Core.Test.IndexerTests.NyaaTests
torrentInfo.MagnetUrl.Should().Be(null);
torrentInfo.Peers.Should().Be(2 + 1);
torrentInfo.Seeders.Should().Be(1);
}*/
[Test]
public void should_parse_2021_recent_feed_from_Nyaa()
{
var recentFeed = ReadAllText(@"Files/Indexers/Nyaa/Nyaa2021.xml");
Mocker.GetMock<IHttpClient>()
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
var releases = Subject.FetchRecent();
releases.Should().HaveCount(3);
releases.First().Should().BeOfType<TorrentInfo>();
var torrentInfo = releases.First() as TorrentInfo;
torrentInfo.Title.Should().Be("[Foxy-Subs] Mahouka Koukou no Yuutousei - 08 [720p] [3194D881].mkv");
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
torrentInfo.DownloadUrl.Should().Be("https://nyaa.si/download/1424896.torrent");
torrentInfo.InfoUrl.Should().Be("https://nyaa.si/view/1424896");
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
torrentInfo.PublishDate.Should().Be(DateTime.Parse("Tue, 24 Aug 2021 22:18:46"));
torrentInfo.Size.Should().Be(639211930); //609.6 MiB
torrentInfo.MagnetUrl.Should().Be(null);
torrentInfo.Seeders.Should().Be(4);
torrentInfo.Peers.Should().Be(3 + 4);
}
}
}

View File

@@ -8,6 +8,7 @@ using NzbDrone.Common.Extensions;
using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Commands;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.Test.Framework;
@@ -19,6 +20,7 @@ namespace NzbDrone.Core.Test.MovieTests
public class RefreshMovieServiceFixture : CoreTest<RefreshMovieService>
{
private MovieMetadata _movie;
private MovieCollection _movieCollection;
private Movie _existingMovie;
[SetUp]
@@ -28,6 +30,9 @@ namespace NzbDrone.Core.Test.MovieTests
.With(s => s.Status = MovieStatusType.Released)
.Build();
_movieCollection = Builder<MovieCollection>.CreateNew()
.Build();
_existingMovie = Builder<Movie>.CreateNew()
.With(s => s.MovieMetadata.Value.Status = MovieStatusType.Released)
.Build();
@@ -40,6 +45,10 @@ namespace NzbDrone.Core.Test.MovieTests
.Setup(s => s.Get(_movie.Id))
.Returns(_movie);
Mocker.GetMock<IAddMovieCollectionService>()
.Setup(v => v.AddMovieCollection(It.IsAny<MovieCollection>()))
.Returns(_movieCollection);
Mocker.GetMock<IProvideMovieInfo>()
.Setup(s => s.GetMovieInfo(It.IsAny<int>()))
.Callback<int>((i) => { throw new MovieNotFoundException(i); });

View File

@@ -64,6 +64,11 @@ namespace NzbDrone.Core.Test.NotificationTests
TestLogger.Info("OnRename was called");
}
public override void OnMovieAdded(Movie movie)
{
TestLogger.Info("OnMovieAdded was called");
}
public override void OnMovieFileDelete(MovieFileDeleteMessage message)
{
TestLogger.Info("OnMovieFileDelete was called");
@@ -117,6 +122,7 @@ namespace NzbDrone.Core.Test.NotificationTests
notification.SupportsOnDownload.Should().BeTrue();
notification.SupportsOnUpgrade.Should().BeTrue();
notification.SupportsOnRename.Should().BeTrue();
notification.SupportsOnMovieAdded.Should().BeTrue();
notification.SupportsOnMovieDelete.Should().BeTrue();
notification.SupportsOnMovieFileDelete.Should().BeTrue();
notification.SupportsOnMovieFileDeleteForUpgrade.Should().BeTrue();
@@ -133,6 +139,7 @@ namespace NzbDrone.Core.Test.NotificationTests
notification.SupportsOnDownload.Should().BeFalse();
notification.SupportsOnUpgrade.Should().BeFalse();
notification.SupportsOnRename.Should().BeFalse();
notification.SupportsOnMovieAdded.Should().BeFalse();
notification.SupportsOnMovieDelete.Should().BeFalse();
notification.SupportsOnMovieFileDelete.Should().BeFalse();
notification.SupportsOnMovieFileDeleteForUpgrade.Should().BeFalse();

View File

@@ -71,7 +71,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
.Returns(new List<CustomFormat>());
Mocker.GetMock<IMovieTranslationService>()
.Setup(v => v.GetAllTranslationsForMovie(It.IsAny<int>()))
.Setup(v => v.GetAllTranslationsForMovieMetadata(It.IsAny<int>()))
.Returns(_movieTranslations);
}

View File

@@ -163,6 +163,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Movie.Title.1994.Dublado.1080p.XviD-LOL")]
[TestCase("Movie.Title.2.2019.1080p.Bluray.Dublado.WWW.TPF.GRATIS")]
[TestCase("Movie.Title.2014.1080p.Bluray.Brazilian.WWW.TPF.GRATIS")]
public void should_parse_language_brazilian_portuguese(string postTitle)
{
var result = Parser.Parser.ParseMovieTitle(postTitle, true);

View File

@@ -261,6 +261,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Movie.Name.2016.German.DTS.DL.1080p.UHDBD.x265-TDO.mkv", false)]
[TestCase("Movie.Name.2021.1080p.BDLight.x265-AVCDVD", false)]
[TestCase("Random.Title.2010.1080p.HD.DVD.AVC.DDP.5.1-GRouP", false)]
[TestCase("Movie.Title.2012.German.DL.1080p.UHD2BD.x264-QfG", false)]
public void should_parse_bluray1080p_quality(string title, bool proper)
{
ParseAndVerifyQuality(title, Source.BLURAY, proper, Resolution.R1080p);

View File

@@ -99,6 +99,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Crappy Anime Movie Name 2017 [RH] [Blu-ray][MKV][h264 10-bit][1080p][FLAC 5.1][Dual Audio][Softsubs (RH)]", "RH")]
[TestCase("Yet Another Anime Movie 2012 [Kametsu] [Blu-ray][MKV][h264 10-bit][1080p][FLAC 5.1][Dual Audio][Softsubs (Kametsu)]", "Kametsu")]
[TestCase("Another.Anime.Film.Name.2016.JPN.Blu-Ray.Remux.AVC.DTS-MA.BluDragon", "BluDragon")]
[TestCase("A Movie in the Name (1964) (1080p BluRay x265 r00t)", "r00t")]
public void should_parse_exception_release_group(string title, string expected)
{
Parser.Parser.ParseReleaseGroup(title).Should().Be(expected);

View File

@@ -24,6 +24,7 @@ namespace NzbDrone.Core.Test.UpdateTests
Subject.GetLatestUpdate("develop", new Version(10, 0)).Should().BeNull();
}
[Ignore("Pending linux-x86 release")]
[Test]
public void finds_update_when_version_lower()
{
@@ -39,6 +40,7 @@ namespace NzbDrone.Core.Test.UpdateTests
Subject.GetLatestUpdate("invalid_branch", new Version(0, 2)).Should().NotBeNull();
}
[Ignore("Pending linux-x86 release")]
[Test]
public void should_get_recent_updates()
{

View File

@@ -45,11 +45,13 @@ namespace NzbDrone.Core.Configuration
string SslCertPassword { get; }
string UrlBase { get; }
string UiFolder { get; }
string InstanceName { get; }
bool UpdateAutomatically { get; }
UpdateMechanism UpdateMechanism { get; }
string UpdateScriptPath { get; }
string SyslogServer { get; }
int SyslogPort { get; }
string SyslogLevel { get; }
string PostgresHost { get; }
int PostgresPort { get; }
string PostgresUser { get; }
@@ -223,6 +225,7 @@ namespace NzbDrone.Core.Configuration
}
public string UiFolder => BuildInfo.IsDebug ? Path.Combine("..", "UI") : "UI";
public string InstanceName => GetValue("InstanceName", BuildInfo.AppName);
public bool UpdateAutomatically => GetValueBoolean("UpdateAutomatically", false, false);
@@ -231,8 +234,11 @@ namespace NzbDrone.Core.Configuration
public string UpdateScriptPath => GetValue("UpdateScriptPath", "", false);
public string SyslogServer => GetValue("SyslogServer", "", persist: false);
public int SyslogPort => GetValueInt("SyslogPort", 514, persist: false);
public string SyslogLevel => GetValue("SyslogLevel", LogLevel, false).ToLowerInvariant();
public int GetValueInt(string key, int defaultValue, bool persist = true)
{
return Convert.ToInt32(GetValue(key, defaultValue, persist));

View File

@@ -0,0 +1,16 @@
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class ReleaseGroupSpecification : RegexSpecificationBase
{
public override int Order => 9;
public override string ImplementationName => "Release Group";
public override string InfoLink => "https://wiki.servarr.com/radarr/settings#custom-formats-2";
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return MatchString(movieInfo?.ReleaseGroup);
}
}
}

View File

@@ -15,9 +15,9 @@ namespace NzbDrone.Core.Datastore.Migration
.WithColumn("Genres").AsString().Nullable()
.WithColumn("Title").AsString()
.WithColumn("SortTitle").AsString().Nullable()
.WithColumn("CleanTitle").AsString().Indexed()
.WithColumn("OriginalTitle").AsString()
.WithColumn("CleanOriginalTitle").AsString().Indexed()
.WithColumn("CleanTitle").AsString().Nullable().Indexed()
.WithColumn("OriginalTitle").AsString().Nullable()
.WithColumn("CleanOriginalTitle").AsString().Nullable().Indexed()
.WithColumn("OriginalLanguage").AsInt32()
.WithColumn("Status").AsInt32()
.WithColumn("LastInfoSync").AsDateTime().Nullable()
@@ -28,7 +28,7 @@ namespace NzbDrone.Core.Datastore.Migration
.WithColumn("Year").AsInt32().Nullable()
.WithColumn("SecondaryYear").AsInt32().Nullable()
.WithColumn("Ratings").AsString().Nullable()
.WithColumn("Recommendations").AsString().Nullable()
.WithColumn("Recommendations").AsString()
.WithColumn("Certification").AsString().Nullable()
.WithColumn("YouTubeTrailerId").AsString().Nullable()
.WithColumn("Collection").AsString().Nullable()
@@ -43,10 +43,11 @@ namespace NzbDrone.Core.Datastore.Migration
FROM ""Movies""");
// Transfer metadata from ImportListMovies to MovieMetadata if not already in
Execute.Sql(@"INSERT INTO ""MovieMetadata"" (""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""CleanTitle"", ""OriginalTitle"", ""CleanOriginalTitle"", ""OriginalLanguage"", ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website"")
SELECT ""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""Title"", ""OriginalTitle"", ""OriginalTitle"", 1, ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website""
Execute.Sql(@"INSERT INTO ""MovieMetadata"" (""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""CleanTitle"", ""OriginalTitle"", ""CleanOriginalTitle"", ""OriginalLanguage"", ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""Recommendations"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website"")
SELECT ""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""Title"", ""OriginalTitle"", ""OriginalTitle"", 1, ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", '[]', ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website""
FROM ""ImportListMovies""
WHERE ""ImportListMovies"".""TmdbId"" NOT IN ( SELECT ""MovieMetadata"".""TmdbId"" FROM ""MovieMetadata"" )");
WHERE ""ImportListMovies"".""TmdbId"" NOT IN ( SELECT ""MovieMetadata"".""TmdbId"" FROM ""MovieMetadata"" )
AND ""ImportListMovies"".""Id"" IN ( SELECT MIN(""Id"") FROM ""ImportListMovies"" GROUP BY ""TmdbId"" )");
// Add an MovieMetadataId column to Movies
Alter.Table("Movies").AddColumn("MovieMetadataId").AsInt32().WithDefaultValue(0);

View File

@@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(209)]
public class movie_meta_collection_index : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Create.Index("IX_MovieMetadata_CollectionTmdbId").OnTable("MovieMetadata").OnColumn("CollectionTmdbId");
Create.Index("IX_MovieTranslations_MovieMetadataId").OnTable("MovieTranslations").OnColumn("MovieMetadataId");
}
}
}

View File

@@ -0,0 +1,14 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(210)]
public class movie_added_notifications : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Notifications").AddColumn("OnMovieAdded").AsBoolean().WithDefaultValue(false);
}
}
}

View File

@@ -88,6 +88,7 @@ namespace NzbDrone.Core.Datastore
.Ignore(i => i.SupportsOnDownload)
.Ignore(i => i.SupportsOnUpgrade)
.Ignore(i => i.SupportsOnRename)
.Ignore(i => i.SupportsOnMovieAdded)
.Ignore(i => i.SupportsOnMovieDelete)
.Ignore(i => i.SupportsOnMovieFileDelete)
.Ignore(i => i.SupportsOnMovieFileDeleteForUpgrade)

View File

@@ -288,7 +288,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
break;
case "forcedDL": //torrent is being downloaded, and was forced started
case "forcedDL": // torrent is being downloaded, and was forced started
case "forcedMetaDL": // torrent metadata is being forcibly downloaded
case "moving": // torrent is being moved from a folder
case "downloading": // torrent is being downloaded and data is being transferred
item.Status = DownloadItemStatus.Downloading;

View File

@@ -120,7 +120,7 @@ namespace NzbDrone.Core.Download
return;
}
var importResults = _downloadedMovieImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteMovie.Movie, trackedDownload.DownloadItem);
var importResults = _downloadedMovieImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteMovie.Movie, trackedDownload.ImportItem);
if (VerifyImport(trackedDownload, importResults))
{

View File

@@ -126,11 +126,11 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
(int)movie.MovieMetadata.Value.OriginalLanguage :
Settings.MovieMetadataLanguage;
var movieTranslations = _movieTranslationsService.GetAllTranslationsForMovie(movie.Id);
var movieTranslations = _movieTranslationsService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId);
var selectedSettingsLanguage = Language.FindById(movieMetadataLanguage);
var movieTranslation = movieTranslations.FirstOrDefault(mt => mt.Language == selectedSettingsLanguage);
var credits = _creditService.GetAllCreditsForMovie(movie.MovieMetadataId);
var credits = _creditService.GetAllCreditsForMovieMetadata(movie.MovieMetadataId);
var watched = GetExistingWatchedStatus(movie, movieFile.RelativePath);

View File

@@ -20,8 +20,9 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
WHERE ""Id"" IN (
SELECT ""MovieMetadata"".""Id"" FROM ""MovieMetadata""
LEFT OUTER JOIN ""Movies"" ON ""Movies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
LEFT OUTER JOIN ""Collections"" ON ""Collections"".""TmdbId"" = ""MovieMetadata"".""CollectionTmdbId""
LEFT OUTER JOIN ""ImportListMovies"" ON ""ImportListMovies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
WHERE ""Movies"".""Id"" IS NULL AND ""ImportListMovies"".""Id"" IS NULL)");
WHERE ""Movies"".""Id"" IS NULL AND ""ImportListMovies"".""Id"" IS NULL AND ""Collections"".""Id"" IS NULL)");
}
}
}

View File

@@ -177,12 +177,12 @@ namespace NzbDrone.Core.ImportLists
{
var mappedMovie = _movieSearch.MapMovieToTmdbMovie(new MovieMetadata { Title = report.Title, TmdbId = report.TmdbId, ImdbId = report.ImdbId, Year = report.Year });
_movieMetadataService.Upsert(mappedMovie);
var mappedListMovie = new ImportListMovie { ListId = report.ListId };
if (mappedMovie != null)
{
_movieMetadataService.Upsert(mappedMovie);
mappedListMovie.MovieMetadata = mappedMovie;
mappedListMovie.MovieMetadataId = mappedMovie.Id;
}

View File

@@ -107,7 +107,8 @@ namespace NzbDrone.Core.ImportLists
AddOptions = new AddMovieOptions
{
SearchForMovie = monitorType != MonitorTypes.None && importList.SearchOnAdd,
Monitor = monitorType
Monitor = monitorType,
AddMethod = AddMovieMethod.List
}
});
}

View File

@@ -73,7 +73,7 @@ namespace NzbDrone.Core.ImportLists.Plex
{
var scheme = $"{prefix}://";
return guids.FirstOrDefault((guid) => guid.Id.StartsWith(scheme))?.Id.Replace(scheme, "");
return guids?.FirstOrDefault((guid) => guid.Id.StartsWith(scheme))?.Id.Replace(scheme, "");
}
}
}

View File

@@ -49,7 +49,7 @@ namespace NzbDrone.Core.IndexerSearch
public List<DownloadDecision> MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch)
{
var movie = _movieService.GetMovie(movieId);
movie.MovieMetadata.Value.Translations = _movieTranslationService.GetAllTranslationsForMovie(movie.Id);
movie.MovieMetadata.Value.Translations = _movieTranslationService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId);
return MovieSearch(movie, userInvokedSearch, interactiveSearch);
}
@@ -77,7 +77,7 @@ namespace NzbDrone.Core.IndexerSearch
};
var wantedLanguages = _profileService.GetAcceptableLanguages(movie.ProfileId);
var translations = _movieTranslationService.GetAllTranslationsForMovie(movie.Id);
var translations = _movieTranslationService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId);
var queryTranlations = new List<string>
{

View File

@@ -12,6 +12,10 @@ namespace NzbDrone.Core.Indexers
UseGuidInfoUrl = true;
UseEnclosureLength = false;
UseEnclosureUrl = true;
SeedsElementName = "seeds";
InfoHashElementName = "infoHash";
SizeElementName = "contentLength";
MagnetElementName = "magnetURI";
}
protected override bool PreProcess(IndexerResponse indexerResponse)
@@ -26,51 +30,5 @@ namespace NzbDrone.Core.Indexers
return base.PreProcess(indexerResponse);
}
protected override long GetSize(XElement item)
{
var contentLength = item.FindDecendants("contentLength").SingleOrDefault();
if (contentLength != null)
{
return (long)contentLength;
}
return base.GetSize(item);
}
protected override string GetInfoHash(XElement item)
{
var infoHash = item.FindDecendants("infoHash").SingleOrDefault();
return (string)infoHash;
}
protected override string GetMagnetUrl(XElement item)
{
var magnetURI = item.FindDecendants("magnetURI").SingleOrDefault();
return (string)magnetURI;
}
protected override int? GetSeeders(XElement item)
{
var seeds = item.FindDecendants("seeds").SingleOrDefault();
if (seeds != null)
{
return (int)seeds;
}
return base.GetSeeders(item);
}
protected override int? GetPeers(XElement item)
{
var peers = item.FindDecendants("peers").SingleOrDefault();
if (peers != null)
{
return (int)peers;
}
return base.GetPeers(item);
}
}
}

View File

@@ -24,7 +24,7 @@ namespace NzbDrone.Core.Indexers.Nyaa
public override IParseIndexerResponse GetParser()
{
return new TorrentRssParser() { UseGuidInfoUrl = true, ParseSizeInDescription = true, ParseSeedersInDescription = true };
return new TorrentRssParser() { UseGuidInfoUrl = true, SizeElementName = "size", InfoHashElementName = "infoHash", PeersElementName = "leechers", CalculatePeersAsSum = true, SeedsElementName = "seeders" };
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using MonoTorrent;
@@ -9,12 +10,27 @@ namespace NzbDrone.Core.Indexers
{
public class TorrentRssParser : RssParser
{
// Use to sum/calculate Peers as Leechers+Seeders
public bool CalculatePeersAsSum { get; set; } = false;
// Use the specified element name to determine the Infohash
public string InfoHashElementName { get; set; }
// Parse various seeder/leecher/peers formats in the description element to determine number of seeders.
public bool ParseSeedersInDescription { get; set; }
// Use the specified element name to determine the size
// Use the specified element name to determine the Peers
public string PeersElementName { get; set; }
// Use the specified element name to determine the Seeds
public string SeedsElementName { get; set; }
// Use the specified element name to determine the Size
public string SizeElementName { get; set; }
// Use the specified element name to determine the Magnet link
public string MagnetElementName { get; set; }
public TorrentRssParser()
{
PreferredEnclosureMimeTypes = TorrentEnclosureMimeTypes;
@@ -40,14 +56,28 @@ namespace NzbDrone.Core.Indexers
result.InfoHash = GetInfoHash(item);
result.MagnetUrl = GetMagnetUrl(item);
result.Seeders = GetSeeders(item);
result.Peers = GetPeers(item);
if (CalculatePeersAsSum)
{
result.Peers = GetPeers(item) + result.Seeders;
}
else
{
result.Peers = GetPeers(item);
}
return result;
}
protected virtual string GetInfoHash(XElement item)
{
if (InfoHashElementName.IsNotNullOrWhiteSpace())
{
return item.FindDecendants(InfoHashElementName).FirstOrDefault().Value;
}
var magnetUrl = GetMagnetUrl(item);
if (magnetUrl.IsNotNullOrWhiteSpace())
{
try
@@ -64,10 +94,21 @@ namespace NzbDrone.Core.Indexers
protected virtual string GetMagnetUrl(XElement item)
{
var downloadUrl = GetDownloadUrl(item);
if (downloadUrl.IsNotNullOrWhiteSpace() && downloadUrl.StartsWith("magnet:"))
if (MagnetElementName.IsNotNullOrWhiteSpace())
{
return downloadUrl;
var magnetURL = item.FindDecendants(MagnetElementName).FirstOrDefault().Value;
if (magnetURL.IsNotNullOrWhiteSpace() && magnetURL.StartsWith("magnet:"))
{
return magnetURL;
}
}
else
{
var downloadUrl = GetDownloadUrl(item);
if (downloadUrl.IsNotNullOrWhiteSpace() && downloadUrl.StartsWith("magnet:"))
{
return downloadUrl;
}
}
return null;
@@ -75,6 +116,8 @@ namespace NzbDrone.Core.Indexers
protected virtual int? GetSeeders(XElement item)
{
// safe to always use the element if it's present (and valid)
// fall back to description if ParseSeedersInDescription is enabled
if (ParseSeedersInDescription && item.Element("description") != null)
{
var matchSeeders = ParseSeedersRegex.Match(item.Element("description").Value);
@@ -93,6 +136,12 @@ namespace NzbDrone.Core.Indexers
}
}
var seeds = item.FindDecendants(SeedsElementName).SingleOrDefault();
if (seeds != null)
{
return (int)seeds;
}
return null;
}
@@ -116,6 +165,12 @@ namespace NzbDrone.Core.Indexers
}
}
if (PeersElementName.IsNotNullOrWhiteSpace())
{
var itempeers = item.FindDecendants(PeersElementName).SingleOrDefault();
return int.Parse(itempeers.Value);
}
return null;
}
@@ -124,9 +179,10 @@ namespace NzbDrone.Core.Indexers
var size = base.GetSize(item);
if (size == 0 && SizeElementName.IsNotNullOrWhiteSpace())
{
if (item.Element(SizeElementName) != null)
var itemsize = item.FindDecendants(SizeElementName).SingleOrDefault();
if (itemsize != null)
{
size = ParseSize(item.Element(SizeElementName).Value, true);
size = ParseSize(itemsize.Value, true);
}
}

View File

@@ -44,7 +44,8 @@ namespace NzbDrone.Core.Instrumentation
if (_configFileProvider.SyslogServer.IsNotNullOrWhiteSpace())
{
SetSyslogParameters(_configFileProvider.SyslogServer, _configFileProvider.SyslogPort, minimumLogLevel);
var syslogLevel = LogLevel.FromString(_configFileProvider.SyslogLevel);
SetSyslogParameters(_configFileProvider.SyslogServer, _configFileProvider.SyslogPort, syslogLevel);
}
var rules = LogManager.Configuration.LoggingRules;
@@ -118,7 +119,7 @@ namespace NzbDrone.Core.Instrumentation
syslogTarget.MessageSend.Udp.Server = syslogServer;
syslogTarget.MessageSend.Udp.ReconnectInterval = 500;
syslogTarget.MessageCreation.Rfc = RfcNumber.Rfc5424;
syslogTarget.MessageCreation.Rfc5424.AppName = BuildInfo.AppName;
syslogTarget.MessageCreation.Rfc5424.AppName = _configFileProvider.InstanceName;
var loggingRule = new LoggingRule("*", minimumLogLevel, syslogTarget);

View File

@@ -127,7 +127,7 @@ namespace NzbDrone.Core.Jobs
new ScheduledTask
{
Interval = Math.Max(_configService.CheckForFinishedDownloadInterval, 1),
Interval = GetRefreshMonitoredInterval(),
TypeName = typeof(RefreshMonitoredDownloadsCommand).FullName,
Priority = CommandPriority.High
}
@@ -198,6 +198,18 @@ namespace NzbDrone.Core.Jobs
return interval;
}
private int GetRefreshMonitoredInterval()
{
var interval = _configService.CheckForFinishedDownloadInterval;
if (interval < 1)
{
return 1;
}
return interval;
}
private int GetImportListSyncInterval()
{
//Enforce 6 hour min on list sync
@@ -218,6 +230,7 @@ namespace NzbDrone.Core.Jobs
_scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, lastExecution, message.Command.StartedAt.Value);
_cache.Find(scheduledTask.TypeName).LastExecution = lastExecution;
_cache.Find(scheduledTask.TypeName).LastStartTime = message.Command.StartedAt.Value;
}
}
@@ -233,13 +246,14 @@ namespace NzbDrone.Core.Jobs
backup.Interval = GetBackupInterval();
var refreshMonitoredDownloads = _scheduledTaskRepository.GetDefinition(typeof(RefreshMonitoredDownloadsCommand));
refreshMonitoredDownloads.Interval = _configService.CheckForFinishedDownloadInterval;
refreshMonitoredDownloads.Interval = GetRefreshMonitoredInterval();
_scheduledTaskRepository.UpdateMany(new List<ScheduledTask> { rss, importList, refreshMonitoredDownloads, backup });
_cache.Find(rss.TypeName).Interval = rss.Interval;
_cache.Find(importList.TypeName).Interval = importList.Interval;
_cache.Find(backup.TypeName).Interval = backup.Interval;
_cache.Find(refreshMonitoredDownloads.TypeName).Interval = refreshMonitoredDownloads.Interval;
}
}
}

View File

@@ -3,7 +3,6 @@
"Yesterday": "في الامس",
"YesMoveFiles": "نعم ، انقل الملفات",
"YesCancel": "نعم إلغاء",
"Yes": "نعم",
"Year": "عام",
"WouldYouLikeToRestoreBackup": "هل ترغب في استعادة النسخة الاحتياطية {0}؟",
"Wiki": "ويكي",
@@ -294,7 +293,6 @@
"NoChange": "لا تغيير",
"NoBackupsAreAvailable": "لا توجد نسخ احتياطية متاحة",
"NoAltTitle": "لا توجد عناوين بديلة.",
"No": "لا",
"NextExecution": "التنفيذ القادم",
"New": "جديد",
"NetCore": ".شبكة",
@@ -437,7 +435,6 @@
"History": "التاريخ",
"HideAdvanced": "إخفاء الإعدادات المتقدمة",
"HiddenClickToShow": "مخفي ، انقر للعرض",
"HelpText": "الفاصل بالدقائق. اضبط على صفر للتعطيل (سيؤدي هذا إلى إيقاف كل عمليات الاستيلاء على التحرير التلقائي)",
"HealthNoIssues": "لا مشاكل مع التكوين الخاص بك",
"Health": "الصحة",
"HaveNotAddedMovies": "لم تقم بإضافة أي أفلام بعد ، هل تريد استيراد بعض أو كل أفلامك أولاً؟",
@@ -1016,7 +1013,6 @@
"DownloadClientCheckNoneAvailableMessage": "لا يوجد عميل تنزيل متاح",
"AddNewMessage": "من السهل إضافة فيلم جديد ، فقط ابدأ بكتابة اسم الفيلم الذي تريد إضافته",
"AddNew": "اضف جديد",
"AddMoviesMonitored": "إضافة أفلام مراقبتها",
"AddMovies": "اضافة افلام",
"AddMovie": "اضافة فيلم",
"AddListExclusion": "إضافة استبعاد قائمة",
@@ -1062,5 +1058,10 @@
"Rating": "التقييمات",
"RemotePath": "مسار بعيد",
"Filters": "منقي",
"LocalPath": "مسار محلي"
"LocalPath": "مسار محلي",
"MonitorMovies": "مراقبة الفيلم",
"NoCollections": "لم يتم العثور على أفلام ، للبدء ، ستحتاج إلى إضافة فيلم جديد أو استيراد بعض الأفلام الموجودة.",
"RssSyncHelpText": "الفاصل بالدقائق. اضبط على صفر للتعطيل (سيؤدي هذا إلى إيقاف كل عمليات الاستيلاء على التحرير التلقائي)",
"AllCollectionsHiddenDueToFilter": "جميع الأفلام مخفية بسبب الفلتر المطبق.",
"Collections": "مجموعة"
}

View File

@@ -285,7 +285,6 @@
"HardlinkCopyFiles": "Твърда връзка / копиране на файлове",
"Health": "Здраве",
"HealthNoIssues": "Няма проблеми с вашата конфигурация",
"HelpText": "Интервал за минути. Задайте на нула, за да деактивирате (това ще спре всички автоматично хващане на освобождаване)",
"HiddenClickToShow": "Скрито, кликнете за показване",
"ImportExtraFiles": "Импортиране на допълнителни файлове",
"ImportFailed": "Неуспешно импортиране: {0}",
@@ -712,7 +711,6 @@
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Искате ли да възстановите архива {0}?",
"Year": "Година",
"Yes": "Да",
"YesCancel": "Да, Отказ",
"YesMoveFiles": "Да, премести файловете",
"Yesterday": "Вчера",
@@ -769,7 +767,6 @@
"MovieIsMonitored": "Филмът се следи",
"RadarrUpdated": "Радар актуализиран",
"AddListExclusion": "Добавяне на изключване от списъка",
"AddMoviesMonitored": "Добавяне на контролирани филми",
"AddNewMovie": "Добавяне на нов филм",
"AddNewTmdbIdMessage": "Можете също да търсите с помощта на TMDb Id на филм. напр. 'tmdb: 71663'",
"AddRemotePathMapping": "Добавете отдалечено картографиране на пътя",
@@ -964,7 +961,6 @@
"MustNotContain": "Не трябва да съдържа",
"NamingSettings": "Настройки за именуване",
"NetCore": ".NET Core",
"No": "Не",
"NoBackupsAreAvailable": "Няма налични резервни копия",
"NoChange": "Няма промяна",
"NoHistory": "Няма история",
@@ -1061,5 +1057,10 @@
"RemotePath": "Отдалечен път",
"List": "Списъци",
"LocalPath": "Местен път",
"SelectLanguages": "Избери език"
"SelectLanguages": "Избери език",
"MonitorMovies": "Монитор на филм",
"AllCollectionsHiddenDueToFilter": "Всички филми са скрити поради приложен филтър.",
"Collections": "колекция",
"NoCollections": "Не са намерени филми, за да започнете, ще искате да добавите нов филм или да импортирате някои съществуващи.",
"RssSyncHelpText": "Интервал за минути. Задайте на нула, за да деактивирате (това ще спре всички автоматично хващане на освобождаване)"
}

View File

@@ -292,7 +292,6 @@
"ImportNotForDownloads": "Nepoužívejte k importu souborů ke stažení z vašeho klienta pro stahování, toto je pouze pro existující organizované knihovny, nikoli pro netříděné soubory.",
"GrabReleaseMessageText": "Radarr nebyl schopen určit, pro který film je toto vydání určeno. Radarr nemusí být schopen toto vydání automaticky importovat. Chcete chytit „{0}“?",
"GrabSelected": "Chyťte vybrané",
"HelpText": "Interval v minutách. Nastavením na nulu deaktivujete (tím se zastaví veškeré automatické uvolnění uvolnění)",
"HiddenClickToShow": "Skryté, kliknutím zobrazíte",
"ImportMechanismHealthCheckMessage": "Povolit zpracování dokončeného stahování",
"NoResultsFound": "Nebyly nalezeny žádné výsledky",
@@ -421,7 +420,6 @@
"MustNotContain": "Nesmí obsahovat",
"NamingSettings": "Nastavení pojmenování",
"NetCore": ".NET Core",
"No": "Ne",
"NoBackupsAreAvailable": "Nejsou k dispozici žádné zálohy",
"NoChange": "Žádná změna",
"NoHistory": "Žádná historie",
@@ -438,7 +436,6 @@
"Overview": "Přehled",
"Failed": "Selhalo",
"AddMovies": "Přidat filmy",
"AddMoviesMonitored": "Přidat sledované filmy",
"AddingTag": "Přidávání značky",
"AlternativeTitle": "Alternativní název",
"AnalyseVideoFiles": "Analyzujte video soubory",
@@ -1016,7 +1013,6 @@
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Chcete obnovit zálohu {0}?",
"Year": "Rok",
"Yes": "Ano",
"YesCancel": "Ano, zrušit",
"YesMoveFiles": "Ano, přesuňte soubory",
"Yesterday": "Včera",
@@ -1061,5 +1057,10 @@
"RemotePath": "Vzdálená cesta",
"Rating": "Hodnocení",
"List": "Seznamy",
"SelectLanguages": "Zvolte jazyk"
"SelectLanguages": "Zvolte jazyk",
"AllCollectionsHiddenDueToFilter": "Všechny filmy jsou skryty kvůli použitému filtru.",
"Collections": "Sbírka",
"MonitorMovies": "Monitorujte film",
"NoCollections": "Nebyly nalezeny žádné filmy. Chcete-li začít, budete chtít přidat nový film nebo importovat některé stávající.",
"RssSyncHelpText": "Interval v minutách. Nastavením na nulu deaktivujete (tím se zastaví veškeré automatické uvolnění uvolnění)"
}

View File

@@ -408,7 +408,6 @@
"MovieIsUnmonitored": "Filmen overvåges ikke",
"Movies": "Film",
"NetCore": ".NET Core",
"No": "Ingen",
"OnHealthIssueHelpText": "Om sundhedsspørgsmål",
"OnRenameHelpText": "Om omdøb",
"OnUpgradeHelpText": "Ved opgradering",
@@ -457,7 +456,6 @@
"AlreadyInYourLibrary": "Allerede i dit bibliotek",
"RecycleBinCleanupDaysHelpTextWarning": "Filer i papirkurven, der er ældre end det valgte antal dage, renses automatisk",
"AddListExclusion": "Tilføj ekskludering af liste",
"AddMoviesMonitored": "Tilføj overvågede film",
"AddingTag": "Tilføjer tag",
"AgeWhenGrabbed": "Alder (når grebet)",
"RefreshAndScan": "Opdater & Scan",
@@ -641,7 +639,6 @@
"GrabRelease": "Grab Release",
"GrabReleaseMessageText": "Radarr var ikke i stand til at bestemme, hvilken film denne udgivelse var til. Radarr kan muligvis ikke automatisk importere denne udgivelse. Vil du hente '{0}'?",
"Group": "Gruppe",
"HelpText": "Interval på få minutter. Sæt til nul for at deaktivere (dette stopper al automatisk frigivelse)",
"HiddenClickToShow": "Skjult, klik for at vise",
"Host": "Vært",
"iCalLink": "iCal Link",
@@ -1016,7 +1013,6 @@
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Vil du gendanne sikkerhedskopien {0}?",
"Year": "År",
"Yes": "Ja",
"YesCancel": "Ja, Annuller",
"YesMoveFiles": "Ja, flyt filerne",
"Yesterday": "I går",
@@ -1061,5 +1057,10 @@
"RemotePath": "Fjern sti",
"SelectLanguages": "Vælg sprog",
"List": "Lister",
"Rating": "Bedømmelser"
"Rating": "Bedømmelser",
"RssSyncHelpText": "Interval på få minutter. Sæt til nul for at deaktivere (dette stopper al automatisk frigivelse)",
"MonitorMovies": "Overvåg film",
"NoCollections": "Ingen film fundet. For at komme i gang vil du tilføje en ny film eller importere nogle eksisterende.",
"AllCollectionsHiddenDueToFilter": "Alle film er gemt på grund af aktivt filter.",
"Collections": "Samling"
}

View File

@@ -572,8 +572,6 @@
"EnableMediaInfoHelpText": "Videoinformationen wie Auflösung, Laufzeit und Codec aus Datien erkennen. Dazu ist es erforderlich, dass Radarr Teile der Datei liest, was zu hoher Festplatten- oder Netzwerkaktivität während der Scans führen kann.",
"ImportListSyncIntervalHelpText": "Wie oft die Listen synchronisiert werden sollen. Minimum 6 Stunden",
"AddListExclusion": "Listenausschluss hinzufügen",
"AddMoviesMonitored": "Filme beobachtet hinzufügen",
"HelpText": "Intervall in Minuten. Zum deaktivieren auf 0 setzen ( Dies wird das automatische Release erfassen deaktivieren )",
"RequiredHelpText": "Diese {0} Bedingungen müsen zutreffen damit das eigene Format zutrifft. Ansonsten reicht ein einzelner {1} Treffer.",
"AllowHardcodedSubsHelpText": "Filme mit hartcodierten Untertiteln werden auch automatisch heruntergeladen",
"ICalHttpUrlHelpText": "Füge diese URL in deinen Client ein oder klicke auf abonnieren wenn dein Browser Webcal untertützt",
@@ -823,8 +821,6 @@
"ListSyncLevelHelpTextWarning": "Filmdateien werden dauerhaft gelöcht, dies kann deine ganze Mediathek leeren wenn deine Listen leer sind",
"ConsideredAvailable": "Verfügbarkeit angenommen",
"Announced": "Angekündigt",
"Yes": "Ja",
"No": "Nein",
"MappedDrivesRunningAsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Radarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen",
"CouldNotConnectSignalR": "Es konnte keine Verbindung zu SignalR hergestellt werden, die Benutzeroberfläche wird nicht aktualisiert",
"ChmodGroupHelpTextWarning": "Dies funktioniert nur, wenn der Benutzer, der Radarr ausführt, der Eigentümer der Datei ist. Es ist besser, sicherzustellen, dass der Download-Client die gleiche Gruppe wie Radarr verwendet.",
@@ -1115,5 +1111,10 @@
"Waiting": "warten",
"OriginalTitle": "Originaler Titel",
"OriginalLanguage": "Originale Sprache",
"Database": "Datenbank"
"Database": "Datenbank",
"AllCollectionsHiddenDueToFilter": "Alle Filme sind wegen dem Filter ausgeblendet.",
"Collections": "Sammlung",
"MonitorMovies": "Film beobachten",
"NoCollections": "Keine Filme gefunden. Zum Starten solltest du einen Film hinzufügen oder vorhandene Importieren.",
"RssSyncHelpText": "Intervall in Minuten. Zum deaktivieren auf 0 setzen ( Dies wird das automatische Release erfassen deaktivieren )"
}

View File

@@ -115,7 +115,6 @@
"ForMoreInformationOnTheIndividualDownloadClients": "Για περισσότερες πληροφορίες σχετικά με τους μεμονωμένους πελάτες λήψης, κάντε κλικ στα κουμπιά πληροφοριών.",
"GrabReleaseMessageText": "Ο Radarr δεν μπόρεσε να προσδιορίσει ποια ταινία ήταν αυτή η κυκλοφορία. Το Radarr ενδέχεται να μην μπορεί να εισαγάγει αυτόματα αυτήν την κυκλοφορία. Θέλετε να τραβήξετε το \"{0}\";",
"HardlinkCopyFiles": "Hardlink / Αντιγραφή αρχείων",
"HelpText": "Διάστημα σε λεπτά. Ρυθμίστε στο μηδέν για απενεργοποίηση (αυτό θα σταματήσει όλες τις αυτόματες αρπάξεις απελευθέρωσης)",
"ImportRootPath": "Τοποθετήστε το Radarr στο φάκελο που περιέχει όλες τις ταινίες σας και όχι μια συγκεκριμένη ταινία. π.χ. {0} και όχι {1}. Επιπλέον, κάθε ταινία πρέπει να βρίσκεται στον δικό της φάκελο στον φάκελο root / library.",
"InCinemasDate": "Στους κινηματογράφους Ημερομηνία",
"IncludeRadarrRecommendations": "Συμπεριλάβετε τις προτάσεις Radarr",
@@ -416,7 +415,6 @@
"MustNotContain": "Δεν πρέπει να περιέχει",
"NamingSettings": "Ρυθμίσεις ονομάτων",
"NetCore": ".NET Core",
"No": "Οχι",
"NoBackupsAreAvailable": "Δεν υπάρχουν διαθέσιμα αντίγραφα ασφαλείας",
"NoChange": "Καμία αλλαγή",
"NoHistory": "Χωρίς ιστορία",
@@ -425,7 +423,6 @@
"OAuthPopupMessage": "Τα αναδυόμενα παράθυρα αποκλείονται από το πρόγραμμα περιήγησής σας",
"Ok": "Εντάξει",
"AddListExclusion": "Προσθήκη εξαίρεσης λίστας",
"AddMoviesMonitored": "Προσθήκη ταινιών που παρακολουθούνται",
"AgeWhenGrabbed": "Ηλικία (όταν αρπαχτεί)",
"OrganizeAndRename": "Οργάνωση & Μετονομασία",
"AllowHardcodedSubs": "Να επιτρέπονται οι συνδρομητές με κωδικοποίηση",
@@ -1016,7 +1013,6 @@
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Θέλετε να επαναφέρετε το αντίγραφο ασφαλείας {0};",
"Year": "Ετος",
"Yes": "Ναί",
"YesCancel": "Ναι, Ακύρωση",
"YesMoveFiles": "Ναι, Μετακινήστε τα αρχεία",
"Yesterday": "Εχθές",
@@ -1061,5 +1057,10 @@
"SelectLanguages": "Επιλέξτε γλώσσα",
"List": "Τόπος αγώνων",
"Rating": "Ακροαματικότητα",
"Filters": "Φίλτρο"
"Filters": "Φίλτρο",
"AllCollectionsHiddenDueToFilter": "Όλες οι ταινίες έχουν κρυφτεί λόγω εφαρμογής φίλτρου",
"Collections": "Συλλογή",
"MonitorMovies": "Παρακολούθηση ταινίας",
"NoCollections": "Δεν βρέθηκαν ταινίες, για να ξεκινήσετε θα θέλετε να προσθέσετε μια νέα ταινία ή να εισαγάγετε ορισμένες υπάρχουσες.",
"RssSyncHelpText": "Διάστημα σε λεπτά. Ρυθμίστε στο μηδέν για απενεργοποίηση (αυτό θα σταματήσει όλες τις αυτόματες αρπάξεις απελευθέρωσης)"
}

View File

@@ -15,10 +15,8 @@
"AddingTag": "Adding tag",
"AddList": "Add List",
"AddListExclusion": "Add List Exclusion",
"AddMissingMovies": "Add Missing Movies",
"AddMovie": "Add Movie",
"AddMovies": "Add Movies",
"AddMoviesMonitored": "Add Movies Monitored",
"AddNew": "Add New",
"AddNewMessage": "It's easy to add a new movie, just start typing the name of the movie you want to add",
"AddNewMovie": "Add New Movie",
@@ -125,6 +123,7 @@
"ChmodGroupHelpText": "Group name or gid. Use gid for remote file systems.",
"ChmodGroupHelpTextWarning": "This only works if the user running Radarr is the owner of the file. It's better to ensure the download client uses the same group as Radarr.",
"ChooseAnotherFolder": "Choose Another Folder",
"ChooseImportMode": "Choose Import Mode",
"CleanLibraryLevel": "Clean Library Level",
"Clear": "Clear",
"ClickToChangeLanguage": "Click to change language",
@@ -139,6 +138,11 @@
"Close": "Close",
"CloseCurrentModal": "Close Current Modal",
"Collection": "Collection",
"CollectionOptions": "Collection Options",
"Collections": "Collections",
"CollectionShowDetailsHelpText": "Show collection status and properties",
"CollectionShowOverviewsHelpText": "Show collection overviews",
"CollectionShowPostersHelpText": "Show Collection item posters",
"CollectionsSelectedInterp": "{0} Collections(s) Selected",
"ColonReplacement": "Colon Replacement",
"ColonReplacementFormatHelpText": "Change how Radarr handles colon replacement",
@@ -269,6 +273,7 @@
"DownloadWarningCheckDownloadClientForMoreDetails": "Download warning: check download client for more details",
"Duration": "Duration",
"Edit": "Edit",
"EditCollection": "Edit Collection",
"EditCustomFormat": "Edit Custom Format",
"EditDelayProfile": "Edit Delay Profile",
"EditGroups": "Edit Groups",
@@ -367,7 +372,6 @@
"HaveNotAddedMovies": "You haven't added any movies yet, do you want to import some or all of your movies first?",
"Health": "Health",
"HealthNoIssues": "No issues with your configuration",
"HelpText": "Interval in minutes. Set to zero to disable (this will stop all automatic release grabbing)",
"HiddenClickToShow": "Hidden, click to show",
"HideAdvanced": "Hide Advanced",
"History": "History",
@@ -445,6 +449,8 @@
"IndexerTagHelpText": "Only use this indexer for movies with at least one matching tag. Leave blank to use with all movies.",
"Info": "Info",
"InstallLatest": "Install Latest",
"InstanceName": "Instance Name",
"InstanceNameHelpText": "Instance name in tab and for Syslog app name",
"InteractiveImport": "Interactive Import",
"InteractiveImportErrLanguage": "Language must be chosen for each selected file",
"InteractiveImportErrMovie": "Movie must be chosen for each selected file",
@@ -604,7 +610,6 @@
"Never": "Never",
"New": "New",
"NextExecution": "Next Execution",
"No": "No",
"NoAltTitle": "No alternative titles.",
"NoBackupsAreAvailable": "No backups are available",
"NoChange": "No Change",
@@ -643,6 +648,8 @@
"OnLatestVersion": "The latest version of Radarr is already installed",
"OnlyTorrent": "Only Torrent",
"OnlyUsenet": "Only Usenet",
"OnMovieAdded": "On Movie Added",
"OnMovieAddedHelpText": "On Movie Added",
"OnMovieDelete": "On Movie Delete",
"OnMovieDeleteHelpText": "On Movie Delete",
"OnMovieFileDelete": "On Movie File Delete",
@@ -762,6 +769,7 @@
"RefreshCollections": "Refresh Collections",
"RefreshInformationAndScanDisk": "Refresh information and scan disk",
"RefreshLists": "Refresh Lists",
"RefreshMonitoredIntervalHelpText": "How often to refresh monitored downloads from download clients, minimum 1 minute",
"RefreshMovie": "Refresh movie",
"RegularExpressionsCanBeTested": "Regular expressions can be tested ",
"RejectionCount": "Rejection Count",
@@ -854,6 +862,7 @@
"RSS": "RSS",
"RSSIsNotSupportedWithThisIndexer": "RSS is not supported with this indexer",
"RSSSync": "RSS Sync",
"RssSyncHelpText": "Interval in minutes. Set to zero to disable (this will stop all automatic release grabbing)",
"RSSSyncInterval": "RSS Sync Interval",
"RSSSyncIntervalHelpTextWarning": "This will apply to all indexers, please follow the rules set forth by them",
"Runtime": "Runtime",
@@ -864,6 +873,7 @@
"Score": "Score",
"Script": "Script",
"ScriptPath": "Script Path",
"ScrollMovies": "Scroll Movies",
"Search": "Search",
"SearchAll": "Search All",
"SearchCutoffUnmet": "Search Cutoff Unmet",
@@ -928,6 +938,7 @@
"ShownClickToHide": "Shown, click to hide",
"ShowOverview": "Show Overview",
"ShowPath": "Show Path",
"ShowPosters": "Show Posters",
"ShowQualityProfile": "Show Quality Profile",
"ShowQualityProfileHelpText": "Show quality profile under poster",
"ShowRatings": "Show Ratings",
@@ -1127,7 +1138,6 @@
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Would you like to restore the backup {0} ?",
"Year": "Year",
"Yes": "Yes",
"YesCancel": "Yes, Cancel",
"YesMoveFiles": "Yes, Move the Files",
"Yesterday": "Yesterday",

View File

@@ -396,7 +396,6 @@
"AllowHardcodedSubs": "Permitir Hardcoded Subs",
"AgeWhenGrabbed": "Edad (cuando capturada)",
"AddImportExclusionHelpText": "Prevenir que la película sea añadida a Radarr mediante listas",
"AddMoviesMonitored": "Añadir Películas Monitoreadas",
"AddListExclusion": "Añadir Exclusión De Lista",
"YesCancel": "Si, cancelar",
"WhitelistedSubtitleTags": "Etiquetas de Subtítulos Permitidas",
@@ -596,7 +595,6 @@
"ICalHttpUrlHelpText": "Copia esta URL a tu gestor(es) o haz click en subscribir si tu navegador soporta webcal",
"ICalFeed": "iCal Feed",
"Hostname": "Nombre del Host",
"HelpText": "Intervalo en minutos. Ajustar a cero para inhabilitar (esto dentendrá toda captura de estrenos automática)",
"EnableSSL": "Habilitar SSL",
"EnableRSS": "Habilitar RSS",
"EnableInteractiveSearch": "Habilitar Búsqueda Interactiva",
@@ -907,7 +905,6 @@
"InCinemasMsg": "La película está en los cines",
"ListSyncLevelHelpTextWarning": "Los archivos de películas se eliminarán permanentemente, esto puede resultar en borrar su biblioteca si sus listas están vacías",
"RSS": "RSS",
"No": "No",
"EditDelayProfile": "Editar perfil de retraso",
"Connection": "Conexiones",
"ConsideredAvailable": "Considerado disponible",
@@ -924,7 +921,7 @@
"DeleteMovieFolderHelpText": "Eliminar la carpeta de películas y su contenido",
"DeleteSelectedMovie": "Eliminar película (s) seleccionada (s)",
"DeleteTheMovieFolder": "Se eliminará la carpeta de películas '{0}' y todo su contenido.",
"Discord": "Discordia",
"Discord": "Discord",
"Donations": "Donaciones",
"DoneEditingGroups": "Terminado de editar grupos",
"DoNotPrefer": "No prefiero",
@@ -1026,7 +1023,6 @@
"Weeks": "Semanas",
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "¿Le gustaría restaurar la copia de seguridad {0}?",
"Yes": "si",
"YesMoveFiles": "Sí, mover los archivos",
"Yesterday": "Ayer",
"MoveFolders2": "¿Le gustaría mover los archivos de película de '{0}' a '{1}'?",
@@ -1114,5 +1110,10 @@
"RemoveSelectedItems": "Eliminar los elementos seleccionados",
"SelectReleaseGroup": "Seleccionar el grupo de lanzamiento",
"SetReleaseGroup": "Configurar el grupo de lanzamiento",
"TaskUserAgentTooltip": "User-Agent proporcionado por la aplicación llamó a la API"
"TaskUserAgentTooltip": "User-Agent proporcionado por la aplicación llamó a la API",
"RssSyncHelpText": "Intervalo en minutos. Ajustar a cero para inhabilitar (esto dentendrá toda captura de estrenos automática)",
"AllCollectionsHiddenDueToFilter": "Todas las películas están ocultas debido al filtro aplicado.",
"Collections": "Colección",
"MonitorMovies": "Monitorear Película",
"NoCollections": "No se encontraron películas, para comenzar, querrá agregar una nueva película o importar algunas existentes."
}

View File

@@ -51,7 +51,7 @@
"LinkHere": "tässä",
"ListSyncLevelHelpText": "Kirjaston elokuvat poistetaan tai niiden valvonta lopetetaan, jollei niitä ole tuontilistallasi.",
"ManualImportSelectMovie": "Manuaalinen tuonti - Valitse elokuva",
"MappedDrivesRunningAsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä, kun niitä käytetään Windows-palveluna. Katso lisätietoja UKK: sta",
"MappedDrivesRunningAsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä, kun sovellus suoritetaan Windows-palveluna. Lisätietoja löydät UKK:stä.",
"MinimumAgeHelpText": "Vain Usenet: NZB: n vähimmäisikä minuutteina, ennen kuin heidät napataan. Käytä tätä antaaksesi uusille julkaisuille aikaa levittää usenet-palveluntarjoajallesi.",
"MinimumFreeSpaceWhenImportingHelpText": "Estä tuonti, jos vapaan levytilan määrä sen jälkeen jää tässä määritetyn arvon alle.",
"MonitoredHelpText": "Elokuvaa etsitään ja se ladataan, jos se on saatavilla.",
@@ -60,7 +60,7 @@
"MultiLanguage": "Monikielinen",
"OrganizeModalNamingPattern": "Nimimalli:",
"PosterOptions": "Julistevaihtoehdot",
"PreviewRenameHelpText": "Vinkki: Jos haluat esikatsella uudelleennimeä ..., valitse Peruuta, napsauta mitä tahansa elokuvan otsikkoa ja käytä",
"PreviewRenameHelpText": "Vihje: Esikatsellaksesi uudelleennimeämistä, valitse 'Peruuta' ja paina jonkin elokuvan otsikkoa ja käytä",
"ProxyCheckResolveIpMessage": "Määritetyn välityspalvelimen '{0}' IP-osoitteen selvitys epäonnistui.",
"ProxyUsernameHelpText": "Käyttäjätunnus ja salasana tulee syöttää vain tarvittaessa. Muussa tapauksessa jätä kentät tyhjiksi.",
"QualityOrLangCutoffHasNotBeenMet": "Laadun tai kielen raja-arvoa ei ole saavutettu",
@@ -87,12 +87,12 @@
"AddNew": "Lisää uusi",
"AudioInfo": "Äänitiedot",
"BeforeUpdate": "Ennen päivitystä",
"DownloadPropersAndRepacksHelpText2": "Käytä 'Älä suosi' -valintaa lajitellaksesi proper- ja repack-julkaisut mukautetun muodon pisteytytyksen perusteella.",
"DownloadPropersAndRepacksHelpText2": "Käytä 'Älä suosi' -valintaa suosiaksesi mukautettujen muotojen pisteytystä Proper- ja Repack-merkintöjä enemmän.",
"Day": "Päivä",
"DBMigration": "Tietokannan siirto",
"ApiKey": "API-avain",
"AcceptConfirmationModal": "Hyväksy vahvistus",
"ApplyTagsHelpTexts1": "Tunnisteisiin kohdistettavat toimenpiteet:",
"ApplyTagsHelpTexts1": "Miten tunnisteita sovelletaan valittuihin elokuviin",
"ApplyTagsHelpTexts2": " 'Lisää' syötetyt tunnisteet aiempiin tunnisteisiin",
"ApplyTagsHelpTexts3": " 'Poista' ainoastaan syötetyt tunnisteet",
"AvailabilityDelay": "Saatavuusviive",
@@ -210,7 +210,7 @@
"EnableInteractiveSearchHelpText": "Profiilia käytetään vuorovaikutteisen haun yhteydessä.",
"EnableSslHelpText": " Käyttöönotto edellyttää uudelleenkäynnistystä järjestelmänvalvojan oikeuksilla.",
"Medium": "Keskitaso",
"MinFormatScoreHelpText": "Mukautetun muodon vähimmäispisteet voidaan ladata",
"MinFormatScoreHelpText": "Mukautetun muodon vähimmäispisteytys, jonka perusteella ladataan.",
"MinimumAge": "Vähimmäisikä",
"MinimumFreeSpace": "Vapaan tallennustilan vähimmäismäärä",
"MinimumLimits": "Vähimmäismäärät",
@@ -226,7 +226,7 @@
"NoLinks": "Ei linkkejä",
"NoMinimumForAnyRuntime": "Ei toistoajan vähimmäiskestoa",
"NoMoveFilesSelf": " Ei, siirrän tiedostot itse",
"NoMoviesExist": "Elokuvia ei löytynyt. Aloittaaksesi sinun kannattaa lisätä uusi elokuva tai tuoda joitain olemassa olevia.",
"NoMoviesExist": "Elokuvia ei löytynyt. Aloita lisäämällä uusi elokuva tai tuo joitakin olemassa olevia.",
"NoResultsFound": "Ei tuloksia",
"BranchUpdate": "Sovelluksen versiopäivityksiin käytettävä kehityshaara.",
"BranchUpdateMechanism": "Ulkoisen päivitysratkaisun käyttämä kehityshaara.",
@@ -269,7 +269,7 @@
"Size": "Koko",
"SuggestTranslationChange": "Ehdota käännösmuutosta",
"Queued": "Jonossa",
"TMDb": "TMDb",
"TMDb": "TMDB",
"UnableToLoadAltTitle": "Vaihtoehtoisten nimikkeiden lataus epäonnistui.",
"Released": "Julkaistu",
"ReleasedMsg": "Elokuva julkaistaan",
@@ -286,7 +286,7 @@
"DetailedProgressBarHelpText": "Näytä teksti edistymispalkissa.",
"Failed": "Epäonnistui",
"InCinemas": "Teatterijulkaisu",
"IncludeCustomFormatWhenRenaming": "Uudelleen nimeäminen",
"IncludeCustomFormatWhenRenaming": "Sisällytä mukautetut muodot uudelleennimetessä",
"IndexerFlags": "Tietolähteen liput",
"IndexerLongTermStatusCheckSingleClientMessage": "Tietolähteet eivät ole käytettävissä yli 6 tuntia kestäneiden virheiden vuoksi: {0}",
"IndexerStatusCheckAllClientMessage": "Tietolähteet eivät ole käytettävissä virheiden vuoksi",
@@ -329,7 +329,6 @@
"Updates": "Päivitykset",
"AddListExclusion": "Lisää tuontilistojen poikkeussääntö",
"AddMovies": "Lisää elokuvia",
"AddMoviesMonitored": "Lisää elokuvat valvottuina",
"ChangeHasNotBeenSavedYet": "Muutosta ei ole vielä tallennettu",
"CreateEmptyMovieFoldersHelpText": "Luo puuttuvat elokuvakansiot levyn tarkistuksen yhteydessä.",
"DeleteDownloadClient": "Poista lataustyökalu",
@@ -372,7 +371,6 @@
"PendingChangesMessage": "On tallentamattomia muutoksia. Haluatko varmasti poistua sivulta?",
"PendingChangesStayReview": "Älä poistu ja tarkista muutokset",
"NetCore": ".NET",
"No": "Ei",
"NoBackupsAreAvailable": "Varmuuskopioita ei ole saatavilla",
"NoChange": "Ei muutosta",
"NoHistory": "Ei historiaa.",
@@ -385,7 +383,7 @@
"Ok": "Ok",
"OrganizeAndRename": "Järjestä ja nimeä uudelleen",
"OrganizeModalAllPathsRelative": "Kaikki polut ovat suhteessa:",
"OrganizeModalDisabled": "Nimeäminen uudelleen on poistettu käytöstä, mitään ei voi nimetä uudelleen",
"OrganizeModalDisabled": "Uudelleennimeäminen on poistettu käytöstä, eikä uudelleennimettävää ole",
"Events": "Tapahtumat",
"IncludeCustomFormatWhenRenamingHelpText": "Mahdollista tämän muodon käyttö {Custom Formats} -nimeämissäännön kanssa.",
"Overview": "Yleiskatsaus",
@@ -421,7 +419,7 @@
"RecycleBinCleanupDaysHelpTextWarning": "Tässä määritettyä aikaa vanhemmat tiedostot poistetaan roskakorista pysyvästi automaattisesti.",
"RecycleBinHelpText": "Pysyvän poiston sijaan elokuvatiedostot siirretään tähän kansioon.",
"RefreshAndScan": "Päivitä ja tarkista",
"RequiredHelpText": "Tämän {0} ehdon on vastattava muokattua muotoa. Muuten yksi {1} ottelu riittää.",
"RequiredHelpText": "Ehdon '{0}' on vastattava mukautettua muotoa sen soveltamiseksi. Muutoin yksi '{1}' vastaavuus on riittävä.",
"RequiredRestrictionPlaceHolder": "Lisää rajoitus",
"AppDataLocationHealthCheckMessage": "Päivitystä ei sallita, jotta AppData-kansion poisto päivityksen yhteydessä voidaan estää.",
"RestartRequiredHelpTextWarning": "Käyttöönotto vaatii uudelleenkäynnistyksen.",
@@ -484,7 +482,7 @@
"ConsideredAvailable": "Tulkitaan olevan saatavilla",
"CopyUsingHardlinksHelpText": "Käytä hardlink-kytköksiä, kun kopioit tiedostoja torrenteista, joita jaetaan vielä.",
"Local": "Paikalliset",
"CouldNotFindResults": "Haku '{0}' ei tuottanut yhtään tuloksia.",
"CouldNotFindResults": "Haku '{0}' ei tuottanut tuloksia.",
"CreateEmptyMovieFolders": "Luo tyhjät kansiot",
"CreateGroup": "Luo ryhmä",
"Crew": "Ryhmä",
@@ -495,12 +493,12 @@
"CustomFormatHelpText": "Radarr pisteyttää jokaisen julkaisun käyttäen pisteiden summaa täsmääville mukautetuille muodoille. Jos uusi julkaisu parantaisi pisteitä samalla tai paremmalla laadulla, Radarr sieppaa sen.",
"CustomFormatJSON": "Mukautettu muoto JSON",
"CustomFormats": "Mukautetut muodot",
"CustomFormatScore": "Mukautetun muodon pisteet",
"CustomFormatScore": "Mukautetun muodon pisteytys",
"CustomFormatsSettings": "Mukautettujen muotojen asetukset",
"CustomFormatsSettingsSummary": "Mukautetut muodot ja niiden asetukset.",
"CustomFormatUnknownConditionOption": "Tuntematon vaihtoehto '{0}' ehdolle '{1}'",
"CustomFormatUnknownConditionOption": "Tuntematon valinta '{0}' ehdolle '{1}'",
"Cutoff": "Katkaisu",
"CutoffFormatScoreHelpText": "Kun tämä mukautetun muodon pisteytys saavutetaan, Radarr ei enää lataa elokuvia.",
"CutoffFormatScoreHelpText": "Kun tämä mukautetun muodon pisteytys saavutetaan, ei elokuvia enää ladata.",
"CutoffUnmet": "Katkaisutasoa ei saavutettu",
"Days": "Päivää",
"Debug": "Virheenkorjaus",
@@ -562,7 +560,7 @@
"Downloading": "Ladataan",
"DownloadPropersAndRepacks": "Proper- ja repack-julkaisut",
"DownloadPropersAndRepacksHelpText1": "Määrittää päivitetäänkö tiedostot automaattisesti proper- ja repack-julkaisuihin (kunnollinen/uudelleenpaketoitu).",
"DownloadPropersAndRepacksHelpTextWarning": "Käytä mukautettuja muotoja automaattisiin päivityksiin potkureille / uudelleenpakkauksille",
"DownloadPropersAndRepacksHelpTextWarning": "Käytä mukautettuja muotoja automaattisiin Proper/Repack-päivityksiin",
"DownloadWarning": "Latausvaroitus: {0}",
"DownloadWarningCheckDownloadClientForMoreDetails": "Latausvaroitus: Katso tarkempia tietoja lataustyökalusta",
"Edition": "Painos",
@@ -600,7 +598,7 @@
"FailedLoadingSearchResults": "Hakutulosten lataus epäonnistui. Yritä uudelleen.",
"FailedToLoadMovieFromAPI": "Elokuvan lataus API:n kautta epäonnistui",
"FeatureRequests": "Kehitysehdotukset",
"FileDateHelpText": "Tiedoston päiväyksen muutos tuonnin ja uudellentarkistuksen yhteydessä.",
"FileDateHelpText": "Muuta tiedoston päiväys tuonnin ja uudelleentarkistuksen yhteydessä.",
"FileManagement": "Tiedostojen hallinta",
"Filename": "Tiedostonimi",
"FileNames": "Tiedostonimet",
@@ -631,7 +629,6 @@
"Group": "Ryhmä",
"Health": "Kunto",
"HealthNoIssues": "Kokoonpanossasi ei ole ongelmia.",
"HelpText": "Aikaväli minuutteina. Poista käytöstä asettamalla arvoksi '0' (tämä lopettaa julkaisujen automaattisen sieppauksen).",
"HiddenClickToShow": "Piilotettu, näytä painalla",
"History": "Historia",
"Host": "Osoite",
@@ -786,8 +783,8 @@
"RemoveSelected": "Poista valitut",
"RemovingTag": "Tunniste poistetaan",
"Renamed": "Nimetty uudelleen",
"RenameFiles": "Nimeä uudelleen",
"RenameMovies": "Nimeä elokuvat uudelleen",
"RenameFiles": "Uudelleennimeä tiedostot",
"RenameMovies": "Uudelleennimeä elokuvat",
"RenameMoviesHelpText": "Jos uudelleennimeäminen ei ole käytössä, käytetään olemassa olevaa tiedostonimeä.",
"Reorder": "Järjestä uudelleen",
"Replace": "Korvata",
@@ -796,8 +793,8 @@
"ReplaceWithSpaceDashSpace": "Korvus: välilyönti-väliviiva-välilyönti",
"Required": "Vaaditaan",
"RequiredRestrictionHelpText": "Julkaisun tulee sisältää ainakin yksi näistä termeistä (kirjainkokoa ei huomioida).",
"RescanAfterRefreshHelpText": "Tarkista elokuvakansion sisältö uudelleen elokuvan päivityksen jälkeen.",
"RescanAfterRefreshHelpTextWarning": "Radarr ei tunnista tiedostomuutoksia automaattisesti, jollei asetuksena ole 'Aina'.",
"RescanAfterRefreshHelpText": "Tutki elokuvakansio uudelleen elokuvan päivityksen jälkeen.",
"RescanAfterRefreshHelpTextWarning": "Tiedostomuutoksia ei tunnisteta automaattisesti, jollei asetuksena ole 'Aina'.",
"RescanMovieFolderAfterRefresh": "Elokuvakansion uudelleentarkistus",
"ResetAPIKey": "Uudista API-avain",
"Restart": "Käynnistä uudelleen",
@@ -829,7 +826,7 @@
"SearchMissing": "Haku puuttuu",
"SearchMovie": "Etsi elokuvaa",
"SearchOnAdd": "Etsi lisättäessä",
"SearchOnAddHelpText": "Elokuvia etsitään tältä tuostilistalta, kun ne lisätään Radarriin.",
"SearchOnAddHelpText": "Etsi tuostilistan elokuvia, kun ne lisätään kirjastoon.",
"SearchSelected": "Haku valittu",
"Seconds": "Sekuntia",
"Security": "Suojaus",
@@ -856,7 +853,7 @@
"SettingsTimeFormat": "Kellonajan esitystapa",
"SettingsWeekColumnHeader": "Viikkosarakkeen otsikko",
"SettingsWeekColumnHeaderHelpText": "Näkyy jokaisen sarakkeen yläpuolella käytettäessä viikkonäkymää.",
"ShouldMonitorHelpText": "Tältä tuontilistalta lisätyt elokuvat lisätään ja niitä valvotaan.",
"ShouldMonitorHelpText": "Lisää listan elokuvat valvottuina.",
"ShowAdvanced": "Näytä edistyneet",
"ShowAsAllDayEvents": "Näytä koko päivän tapahtumina",
"ShowCutoffUnmetIconHelpText": "Näytä kuvake elokuville, joiden tiedostot eivät vastaa vielä määritettyä katkaisutasoa.",
@@ -881,7 +878,7 @@
"Shutdown": "Sammuta",
"SizeOnDisk": "Koko levyllä",
"SkipFreeSpaceCheck": "Ohita vapaan levytilan tarkistus",
"SkipFreeSpaceCheckWhenImportingHelpText": "Käytä, kun vaapaata tilaa ei tunnisteta elokuviesi pääkansiosta",
"SkipFreeSpaceCheckWhenImportingHelpText": "Käytä, kun vapaata tallennustilaa ei tunnisteta elokuvien juurikansiosta.",
"Small": "Pieni",
"Socks4": "Sukat 4",
"Socks5": "Sukat5 (tuki TOR)",
@@ -948,7 +945,7 @@
"UnableToAddANewRemotePathMappingPleaseTryAgain": "Etäsijainnin kartoituksen lisäys epäonnistui. Yritä uudelleen.",
"UnableToImportCheckLogs": "Ladattu - Tuonti epäonnistui: tarkasta lokitiedot",
"UnableToLoadBackups": "Varmuuskopioiden lataus epäonnistui.",
"UnableToLoadCustomFormats": "Muokattujen muotojen lataus epäonnistui.",
"UnableToLoadCustomFormats": "Muokattuja muotoja ei voitu ladata.",
"UnableToLoadDelayProfiles": "Viiveprofiilien lataus epäonnistui.",
"Unlimited": "Rajoittamaton",
"UnableToLoadDownloadClientOptions": "Lataustyökalun asetuksien lataus epäonnistui.",
@@ -956,7 +953,7 @@
"UnableToLoadGeneralSettings": "Yleisten asetusten lataus epäonnistui.",
"UnableToLoadHistory": "Historian lataus epäonnistui.",
"UnableToLoadIndexerOptions": "Tietolähteiden asetuksien lataus epäonnistui.",
"UnableToLoadIndexers": "Tietolähteiden lataus epäonnistui.",
"UnableToLoadIndexers": "Tietolähteiden lataus epäonnistui",
"UnableToLoadLanguages": "Kielien lataus epäonnistui.",
"UnableToLoadListExclusions": "Tuontilistojen poikkeussääntöjen lataus epäonnistui.",
"UnableToLoadListOptions": "Tuontilistojen asetuksien lataus epäonnistui.",
@@ -989,7 +986,7 @@
"UpdateAutomaticallyHelpText": "Lataa ja asenna päivitykset automaattisesti. Voit edelleen asentaa ne myös lähteestä System:Updates.",
"UpdateCheckStartupTranslocationMessage": "Päivitystä ei voi asentaa, koska käynnistyskansio '{0}' sijaitsee 'App Translocation' -kansiossa.",
"UpdateMechanismHelpText": "Käytä Radarrin sisäänrakennettua päivitystoimintoa tai omaa komentosarjaasi.",
"UpdateSelected": "Päivitä valittu",
"UpdateSelected": "Päivitä valitut",
"UpgradeUntilCustomFormatScore": "Päivitä mukautetun muodon pistetytykseen saakka",
"UpgradeUntilQuality": "Päivitä laatuun asti",
"UpgradeUntilThisQualityIsMetOrExceeded": "Päivitä, kunnes tämä laatu saavutetaan tai ylitetään",
@@ -1016,7 +1013,6 @@
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Haluatko palauttaa varmuuskopion {0}?",
"Year": "Vuosi",
"Yes": "Kyllä",
"YesCancel": "Kyllä, peruuta",
"YesMoveFiles": "Kyllä, siirrä tiedostot",
"Yesterday": "Eilen",
@@ -1074,7 +1070,7 @@
"RemotePathMappingCheckFileRemoved": "Tiedosto '{0}' poistettiin kesken käsittelyn.",
"RemotePathMappingCheckFilesLocalWrongOSPath": "Paikallinen lataustyökalu '{0}' ilmoitti tiedostosijainniksi '{1}', mutta se ei ole kelvollinen '{2}' -sijainti. Tarkista lataustyökalusi asetukset.",
"RemotePathMappingCheckFolderPermissions": "Radarr näkee, muttei voi käyttää latauskansiota '{0}'. Todennäköinen syy on sijainnin käyttöoikeusvirhe.",
"RemotePathMappingCheckGenericPermissions": "Lataustyökalu '{0}' sijoittaa lataukset kansioon '{1}', mutta Radarr ei näe sitä. Saata joutua muokkaamaan kansion käyttöoikeuksia.",
"RemotePathMappingCheckGenericPermissions": "Lataustyökalu '{0}' sijoittaa lataukset kansioon '{1}', mutta Radarr ei näe sitä. Saatat joutua muokkaamaan kansion käyttöoikeuksia.",
"RemotePathMappingCheckDockerFolderMissing": "Käytät Dockeria ja lataustyökalu '{0}' sijoittaa lataukset kohteeseen '{1}', mutta kansiota ei näytä olevan olemassa containerissa. Tarkista etäsijaintiesi kartoitukset ja containerin tallennusmedia-asetukset.",
"RemotePathMappingCheckFilesBadDockerPath": "Käytät Dockeria ja lataustyökalu '{0}' ilmoitti latauskohteeksi '{1}', mutta se ei ole kelvollinen '{2}' -sijainti. Tarkista etäsijaintiesi kartoitukset ja lataustyökalun asetukset.",
"RemotePathMappingCheckRemoteDownloadClient": "Etälataustyökalu '{0}' ilmoitti tiedostosijainniksi '{1}', mutta kansiota ei näytä olevan olemassa. Todennäköinen syy on puuttuva tai virheellinen etäsijainnin kartoitus.",
@@ -1115,5 +1111,28 @@
"Waiting": "Odottaa",
"OriginalTitle": "Alkuperäinen nimi",
"OriginalLanguage": "Alkuperäinen kieli",
"Database": "Tietokanta"
"Database": "Tietokanta",
"RefreshMonitoredIntervalHelpText": "Miten usein valvottujen latausten tiedot päivitetään lataustyökaluilta (vähimmäisaika on 1 minuutti).",
"RssSyncHelpText": "Aikaväli minuutteina. Arvo nolla kytkee toiminnon pois käytöstä ja lopettaen samalla automaattisen julkaisujen kaappauksen täysin.",
"InstanceName": "Instanssin nimi",
"InstanceNameHelpText": "Instanssin nimi välilehdellä ja sovelluksen Syslog-nimeksi",
"AllCollectionsHiddenDueToFilter": "Käytössä oleva suodatin on piilottanut kaikki kokoelmat.",
"Collections": "Kokoelmat",
"MonitorMovies": "Valvo elokuvia",
"NoCollections": "Kokoelmia ei löytynyt. Aloita lisäämällä uusi elokuva tai tuo joitakin olemassa olevia.",
"EditCollection": "Muokkaa kokoelmaa",
"SearchOnAddCollectionHelpText": "Etsi kokoelman elokuvia, kun ne lisätään kirjastoon.",
"ChooseImportMode": "Valitse tuontitila",
"CollectionsSelectedInterp": "{0} kokoelmaa valittu",
"MonitorCollection": "Valvo kokoelmaa",
"MonitoredCollectionHelpText": "Valvonta lisää kokoelman elokuvat automaattisesti kirjastoon.",
"MovieAndCollection": "Elokuva ja kokoelma",
"MovieCollectionMissingRoot": "Elokuvakokoelman juurikansio puuttuu: {0}",
"MovieCollectionMultipleMissingRoots": "Useita elokuvakokoelmien juurikansioita puuttuu: {0}",
"MovieOnly": "Vain elokuva",
"RefreshCollections": "Päivitä kokoelmat",
"ScrollMovies": "Vieritä elokuvia",
"ShowCollectionDetails": "Näytä kokoelman tila",
"ShowOverview": "Näytä yleiskatsaus",
"UnableToLoadCollections": "Kokoelmia ei voitu ladata"
}

View File

@@ -1,6 +1,6 @@
{
"IndexerStatusCheckAllClientMessage": "Tous les indexeurs sont indisponibles en raison d'échecs",
"IndexerSearchCheckNoInteractiveMessage": "Aucun indexeur disponible avec la recherche interactive activée, Radarr ne fournira aucun résultat de recherche interactif",
"IndexerSearchCheckNoInteractiveMessage": "Aucun indexeur disponible avec la recherche interactive activée, Radarr ne fournira aucun résultat de recherche interactive",
"IndexerSearchCheckNoAvailableIndexersMessage": "Tous les indexeurs compatibles avec la recherche sont temporairement indisponibles en raison d'erreurs d'indexation récentes",
"IndexerSearchCheckNoAutomaticMessage": "Aucun indexeur disponible avec la recherche automatique activée, Radarr ne fournira aucun résultat de recherche automatique",
"Indexers": "Indexeurs",
@@ -26,7 +26,7 @@
"Edit": "Éditer",
"Downloaded": "Téléchargé",
"DownloadClientStatusCheckAllClientMessage": "Aucun client de téléchargement n'est disponible en raison d'échecs",
"DownloadClients": "Clients Télécharg.",
"DownloadClients": "Clients de téléchargement",
"DownloadClientCheckNoneAvailableMessage": "Aucun client de téléchargement n'est disponible",
"Dates": "Dates",
"Date": "Date",
@@ -36,7 +36,7 @@
"Delete": "Supprimer",
"DelayProfiles": "Profils de retard",
"Day": "Jour",
"CustomFormats": "Formats Persos",
"CustomFormats": "Formats personnalisés",
"CustomFilters": "Filtres personnalisés",
"Crew": "Équipe",
"Connections": "Connexions",
@@ -48,7 +48,7 @@
"Calendar": "Calendrier",
"BackupNow": "Sauvegarder maintenant",
"Backup": "Sauvegarde",
"AppDataLocationHealthCheckMessage": "Mettre à jour ne sera pas possible pour éviter la suppression AppData lors de la mise à jour",
"AppDataLocationHealthCheckMessage": "Mettre à jour ne sera pas possible afin d'éviter de supprimer le dossier AppData lors de la mise à jour",
"Analytics": "Analytique",
"All": "Tout",
"AddNewTmdbIdMessage": "Vous pouvez également effectuer une recherche à l'aide de l'identifiant TMDb d'un film. exemple. tmdb:71663",
@@ -59,7 +59,7 @@
"Activity": "Activité",
"About": "À propos",
"CustomFormatsSettingsSummary": "Paramètres et Formats personnalisés",
"IndexerStatusCheckSingleClientMessage": "Indexeurs indisponibles en raison d'échecs: {0}",
"IndexerStatusCheckSingleClientMessage": "Indexeurs indisponibles en raison d'échecs : {0}",
"DownloadClientStatusCheckSingleClientMessage": "Clients de Téléchargement indisponibles en raison d'échecs: {0}",
"SetTags": "Définir Tags",
"ReleaseTitle": "Titre de la version",
@@ -292,7 +292,7 @@
"RecentFolders": "Dossiers récents",
"QuickImport": "Déplacer automatiquement",
"PosterSize": "Taille des posters",
"Posters": "Posters",
"Posters": "Affiches",
"PosterOptions": "Options des posters",
"PendingChangesStayReview": "Rester et vérifier les changements",
"PendingChangesMessage": "Vous avez effectué des changements non sauvegardés, souhaitez vous quitter cette page?",
@@ -322,7 +322,7 @@
"CertificateValidation": "Validation du certificat",
"BypassProxyForLocalAddresses": "Contourner le proxy pour les adresses locales",
"Branch": "Branche",
"BindAddressHelpText": "Adresse IP4 valide ou '*' pour toutes les interfaces",
"BindAddressHelpText": "Adresse IPv4 valide ou '*' pour toutes les interfaces",
"BindAddress": "Adresse d'attache",
"Backups": "Sauvegardes",
"BackupRetentionHelpText": "Les sauvegardes automatiques plus anciennes que la période de conservation seront automatiquement effacées",
@@ -347,7 +347,6 @@
"AllowHardcodedSubsHelpText": "Les sous-titres incrustés détectés seront automatiquement téléchargés",
"AllowHardcodedSubs": "Autoriser les sous-titres incrustés",
"AgeWhenGrabbed": "Age (au moment du téléchargement)",
"AddMoviesMonitored": "Ajouter des films en mode surveillé",
"AddListExclusion": "Ajouter une exclusion de liste",
"IgnoreDeletedMovies": "Annuler la surveillance des films supprimés",
"IgnoredAddresses": "Adresses ignorées",
@@ -355,7 +354,6 @@
"ICalHttpUrlHelpText": "Copiez cette URL dans votre client ou cliquez pour souscrire si votre navigateur est compatible avec webcal",
"ICalFeed": "Flux iCal",
"Hostname": "Nom d'hôte",
"HelpText": "Intervalle en minutes. Mettre à zéro pour désactiver (cela arrêtera tous les téléchargements automatiques)",
"Group": "Groupe",
"GrabRelease": "Télécharger la version",
"GrabID": "ID du grab",
@@ -385,7 +383,7 @@
"Enable": "Activer",
"EditPerson": "Éditer la personne",
"EditMovie": "Éditer le film",
"Edition": "Edition",
"Edition": "Édition",
"DownloadWarningCheckDownloadClientForMoreDetails": "Avertissement téléchargement : voir le client de téléchargement pour plus de détails",
"DownloadFailedCheckDownloadClientForMoreDetails": "Téléchargement échoué : voir le client de téléchargement pour plus de détails",
"DownloadClientSettings": "Réglages Clients de téléchargement",
@@ -455,7 +453,7 @@
"CopyToClipboard": "Copier dans le presse-papier",
"GoToInterp": "Aller à {0}",
"ForMoreInformationOnTheIndividualImportListsClinkOnTheInfoButtons": "Pour plus d'informations sur les listes d'importation individuelles, cliquez sur les boutons d'information.",
"ForMoreInformationOnTheIndividualDownloadClients": "Pour plus d'informations sur les clients de téléchargement individuels, cliquez sur les boutons d'information.",
"ForMoreInformationOnTheIndividualDownloadClients": "Pour plus d'informations sur chaque client de téléchargement, cliquez sur les boutons plus d'information.",
"FilterPlaceHolder": "Chercher les films",
"FailedLoadingSearchResults": "Échec du chargement des résultats de la recherche, veuillez réessayer.",
"Excluded": "Exclu",
@@ -573,7 +571,7 @@
"ProxyBypassFilterHelpText": "Utiliser ',' comme séparateur et '*.' comme caractère générique pour les sous-domaines",
"OnGrabHelpText": "À la Récupération",
"NegateHelpText": "Si coché, le format personnalisé ne s'appliquera pas si cette condition {0} correspond.",
"LastDuration": "dernière Durée",
"LastDuration": "Dernière durée",
"IncludeCustomFormatWhenRenamingHelpText": "Inclus dans {Custom Formats} renommer le format",
"GrabReleaseMessageText": "Radarr n'a pas été en mesure de déterminer à quel film cette version était destinée. Radarr peut être incapable d'importer automatiquement cette version. Voulez-vous récupérer '{0}' ?",
"ExtraFileExtensionsHelpTexts1": "Liste séparée par des virgules des fichiers supplémentaires à importer (.nfo sera importé en tant que .nfo-orig)",
@@ -586,7 +584,7 @@
"UpgradeUntilThisQualityIsMetOrExceeded": "Mettre à niveau jusqu'à ce que cette qualité soit atteinte ou dépassée",
"UpgradeAllowedHelpText": "Ne sera pas mis à jour si la qualité est désactivée",
"UpdateScriptPathHelpText": "Chemin vers un script personnalisé qui prend un package de mise à jour extraite et gère le reste du processus de mise à jour",
"UpdateMechanismHelpText": "Utiliser le programme de mise à jour intégré dans Radarr ou un script",
"UpdateMechanismHelpText": "Utiliser le programme de mise à jour intégré de Radarr ou un script",
"UpdateAutomaticallyHelpText": "Télécharger et installer automatiquement les mises à jour. Vous pourrez toujours installer à partir de System : Updates",
"Unreleased": "Indisponible",
"UnmonitoredHelpText": "Inclure les films non surveillés dans le flux iCal",
@@ -828,7 +826,7 @@
"EditQualityProfile": "Modifier les profils",
"ErrorRestoringBackup": "Erreur lors de la restauration de la sauvegarde",
"ExternalUpdater": "Radarr est configuré pour utiliser un système de mise à jour ad-hoc",
"FileWasDeletedByViaUI": "Le fichier à été supprimé via l'interface",
"FileWasDeletedByViaUI": "Le fichier a été supprimé via l'interface",
"Announced": "Annoncé",
"ChmodFolder": "chmod Dossier",
"ChmodFolderHelpText": "Nombre, appliqué durant l'import/renommage vers les dossiers et fichiers multimédias (sans exécuter les bits)",
@@ -848,7 +846,7 @@
"AllResultsHiddenFilter": "Tous les résultats ont été dissimulés par le filtre actuellement appliqué",
"Always": "Toujours",
"AptUpdater": "Utiliser apt pour installer la mise à jour",
"AreYouSureYouWantToRemoveSelectedItemsFromQueue": "Êtes-vous sûr de vouloir désinstaller {0} objet{1} de la file d'attente ?",
"AreYouSureYouWantToRemoveSelectedItemsFromQueue": "Êtes-vous sûr de vouloir supprimer {0} objet(s) de la file d'attente ?",
"AuthBasic": "Authentification de base (popup)",
"AuthForm": "Authentification par formulaire (page de connexion)",
"AreYouSureYouWantToDeleteFormat": "Êtes-vous sûr de vouloir supprimer le tag {0} ?",
@@ -894,7 +892,7 @@
"HomePage": "Page d'accueil",
"HttpHttps": "HTTP(S)",
"ImportLibrary": "Import bibliothèque",
"MissingFromDisk": "Radarr n'a pas pu trouver le fichier sur le disque, il a donc été supprimé",
"MissingFromDisk": "Radarr n'a pas pu trouver le fichier sur le disque, il a donc été supprimé dans la base de donnée",
"MovieIsRecommend": "Le film est recommandé en fonction de l'ajout récent",
"NoAltTitle": "Pas de titres alternatifs.",
"NoLinks": "Aucun liens",
@@ -912,7 +910,7 @@
"InteractiveImportErrQuality": "La qualité doit être choisie pour chaque fichier sélectionné",
"LowerCase": "Minuscules",
"ManualImportSelectMovie": "Importation manuelle - Sélectionnez un film",
"MappedDrivesRunningAsService": "Les lecteurs réseau mappés ne sont pas disponibles lorsqu'ils sont exécutés en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations",
"MappedDrivesRunningAsService": "Les lecteurs réseau mappés ne sont pas disponibles en fonctionnement en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations",
"RequiredRestrictionHelpText": "La version doit contenir au moins un de ces termes (insensible à la casse)",
"InvalidFormat": "Format invalide",
"LastExecution": "Dernière exécution",
@@ -944,7 +942,6 @@
"ImportNotForDownloads": "Ne pas utiliser pour importer des téléchargements à partir de votre client de téléchargement, cela concerne uniquement les bibliothèques organisées existantes, pas les fichiers non triés.",
"PreferUsenet": "Préférez Usenet",
"ReplaceWithDash": "Remplacer par Dash",
"No": "Non",
"InCinemasDate": "Dans les cinémas Date",
"InstallLatest": "Installer le dernier",
"KeepAndUnmonitorMovie": "Conserver et annuler la surveillance du film",
@@ -994,7 +991,7 @@
"SearchCutoffUnmet": "Limite de recherche non satisfaite",
"SearchMissing": "Recherche manquante",
"Seconds": "Secondes",
"SelectDotDot": "'Sélectionner...",
"SelectDotDot": "Sélectionner...",
"SelectLanguage": "Choisir la langue",
"SelectMovie": "Sélectionnez un film",
"SelectQuality": "Sélectionnez la qualité",
@@ -1005,7 +1002,7 @@
"Sunday": "dimanche",
"TagDetails": "Détails du tag - {0}",
"TheLogLevelDefault": "Le niveau de journalisation est par défaut «Info» et peut être modifié dans",
"ThisCannotBeCancelled": "Cela ne peut pas être annulé une fois démarré sans redémarrer Radarr.",
"ThisCannotBeCancelled": "Cela ne peut pas être annulé une fois démarré sans désactiver tous vos indexeurs.",
"TorrentDelayTime": "Retard du torrent : {0}",
"TorrentsDisabled": "Torrents désactivés",
"Trace": "Trace",
@@ -1027,7 +1024,6 @@
"Weeks": "Semaines",
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Souhaitez-vous restaurer la sauvegarde {0} ?",
"Yes": "Oui",
"YesMoveFiles": "Oui, déplacez les fichiers",
"MoveFolders2": "Souhaitez-vous déplacer les fichiers vidéo de «{0}» vers «{1}» ?",
"SqliteVersionCheckUpgradeRequiredMessage": "La version {0} de SQLite actuellement installée n'est plus prise en charge. Veuillez mettre à niveau SQLite vers au moins la version {1}.",
@@ -1048,7 +1044,7 @@
"DownloadClientCheckDownloadingToRoot": "Le client de téléchargement {0} place les téléchargements dans le dossier racine {1}. Vous ne devez pas télécharger dans un dossier racine.",
"DeleteFileLabel": "Supprimer {0} fichiers",
"NotificationTriggersHelpText": "Sélectionnez les événements qui doivent déclencher cette notification",
"From": "De",
"From": "de",
"UpdateAvailable": "Une nouvelle mise à jour est disponible",
"RemotePathMappingCheckImportFailed": "Radarr a échoué en important un Film. Vérifier vos logs pour plus de détails.",
"RemotePathMappingCheckDownloadPermissions": "Radarr peut voir mais ne peut accéder au film téléchargé {0}. Il s'agit probablement d'une erreur de permissions.",
@@ -1074,22 +1070,22 @@
"RemotePathMappingCheckFilesGenericPermissions": "Le client de téléchargement {0} met les téléchargements dans {1} mais Radarr ne peut voir ce répertoire. Il est possible que vous ayez besoin d'ajuster les permissions de ce dossier.",
"RemotePathMappingCheckFilesLocalWrongOSPath": "Le client de téléchargement {0} met les téléchargements dans {1} mais il ne s'agit pas d'un chemin {2} valide. Vérifiez les paramètres de votre client de téléchargement.",
"BypassDelayIfHighestQualityHelpText": "Outrepasser le délai quand la version a la plus haute qualité activée dans le profil de qualité avec le protocole préféré",
"ClickToChangeReleaseGroup": "Cliquez pour changer de release group",
"ClickToChangeReleaseGroup": "Cliquer pour changer le groupe de publication",
"AnnouncedMsg": "Le film est annoncé",
"Filters": "Filtres",
"IndexerDownloadClientHelpText": "Précisez quel client de téléchargement est utilisé pour cet indexer",
"IndexerDownloadClientHelpText": "Spécifiez quel client de téléchargement est utilisé pour cet indexeur",
"TmdbRating": "Note TMDb",
"IndexerTagHelpText": "Utiliser seulement cet indexeur pour les films avec au moins un tag correspondant. Laissez vide pour l'utiliser avec tous les films.",
"IndexerJackettAll": "Les indexeurs utilisant le endpoint 'all' de Jackett: {0}",
"IndexerJackettAll": "Indexeurs utilisant le endpoint non supporté 'all' de Jackett : {0}",
"ManualImportSetReleaseGroup": "Import manuel - Spécifier le groupe de Release",
"TmdbVotes": "Votes TMDb",
"ImdbRating": "Note IMDb",
"ImdbVotes": "Votes IMDb",
"LocalPath": "Chemin local",
"DiscordUrlInSlackNotification": "Vous avez une configuration de notification Discord en tant que notification Slack. Configurez cela comme une notification Discord pour une meilleure fonctionnalité. Les notifications affectées sont: {0}",
"RemotePathMappingCheckDockerFolderMissing": "Vous utilisez docker; {0} enregistre les téléchargements dans {1} mais ce dossier n'est pas présent dans ce conteneur. Vérifiez vos paramètres de dossier distant et les paramètres de votre conteneur docker.",
"DiscordUrlInSlackNotification": "Vous avez une configuration de notification Discord en tant que notification Slack. Configurez cela comme une notification Discord pour un meilleur fonctionnement. Les notifications affectées sont : {0}",
"RemotePathMappingCheckDockerFolderMissing": "Vous utilisez docker; {0} enregistre les téléchargements dans {1} mais ce dossier n'est pas présent dans ce conteneur. Vérifiez vos paramètres de dossier distant et les paramètres de votre conteneur docker.",
"RemotePathMappingCheckRemoteDownloadClient": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
"RemotePathMappingCheckBadDockerPath": "Vous utilisez docker; {0} enregistre les téléchargements dans {1} mais ce n'est pas un dossier valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckBadDockerPath": "Vous utilisez docker ; le client de téléchargement {0} enregistre les téléchargements dans {1} mais ce n'est pas un chemin valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckFilesWrongOSPath": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais il ne s'agit pas d'un chemin {2} valide. Vérifiez les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckLocalFolderMissing": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
"OnApplicationUpdate": "Lors de la mise à jour de l'app",
@@ -1102,9 +1098,26 @@
"OriginalLanguage": "Langue d'origine",
"Rating": "Note",
"RemotePath": "Dossier distant",
"RemotePathMappingCheckFilesBadDockerPath": "Vous utilisez docker; {0} signifie les téléchargement dans {1} mais ce n'est pas un dossier valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckFilesBadDockerPath": "Vous utilisez docker; {0} signifie les téléchargement dans {1} mais ce n'est pas un dossier valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckWrongOSPath": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin {2} est invalide. Vérifiez vos paramètres de chemins distants et les paramètres de votre client de téléchargement.",
"RemoveCompleted": "Supprimer les complétés",
"Database": "Base de données",
"SelectLanguages": "Choisir la langue"
"SelectLanguages": "Choisir la/les langue(s)",
"RemoveDownloadsAlert": "Les paramètres de suppression ont été déplacés dans les réglages de chaque client de téléchargement dans le tableau ci-dessus.",
"SizeLimit": "Limite de taille",
"Started": "Démarré",
"Waiting": "En attente",
"RemoveFailed": "Echec de la suppression",
"RemoveSelectedItem": "Supprimer l'élément sélectionné",
"RemoveSelectedItems": "Supprimer les éléments sélectionnés",
"SelectReleaseGroup": "Sélectionner le groupe de publication",
"SetReleaseGroup": "Régler le groupe de publication",
"RefreshMonitoredIntervalHelpText": "Intervalle en minutes entre chaque vérification des téléchargements, minimum 1 minute",
"AllCollectionsHiddenDueToFilter": "Tous les films sont masqués en raison du filtre appliqué.",
"Collections": "Collection",
"MonitorMovies": "Surveiller le film",
"NoCollections": "Aucun film trouvé, pour commencer, vous voudrez ajouter un nouveau film ou importer des films existants.",
"RssSyncHelpText": "Intervalle en minutes. Mettre à zéro pour désactiver (cela arrêtera tous les téléchargements automatiques)",
"CollectionsSelectedInterp": "{0} Collections(s) Sélectionnée(s)",
"ChooseImportMode": "Mode d'importation"
}

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