1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-05 13:21:25 -05:00

Compare commits

...

50 Commits

Author SHA1 Message Date
bogdan
4c1b3a7b82 Bump MailKit and Microsoft.Data.SqlClient 2025-09-07 10:45:27 -05:00
Mark McDowall
6396d83fa7 Change authentication to Forms if set to Basic
(cherry picked from commit dfb6fdfbeb7ce85b287b41fed80f2511727353e5)
2025-09-07 10:44:48 -05:00
Bogdan
bd203d841a Fixed: Validation for tags label 2025-09-07 10:44:48 -05:00
Bogdan
e96d7580f4 Fixed: Removed support for movie file tokens in Movie Folder Format 2025-09-07 10:44:48 -05:00
Bogdan
eb0f7c62b6 New: Validation for movie file tokens in Movie Folder Format 2025-09-07 10:44:48 -05:00
Mark McDowall
41fa0de230 New: Remove Basic Auth
(cherry picked from commit 0f9e063e2146812f6e963363eee70a524612f354)
2025-09-07 10:44:48 -05:00
bakerboy448
cdc6a6dd27 New: Default wanted language for quality profiles changed to Original 2025-09-07 10:44:48 -05:00
Bogdan
1891ac1536 Bump Swashbuckle to 8.1.4 2025-09-07 10:44:48 -05:00
Bogdan
2539d46f7c Bump version to 6.0.0 2025-09-07 10:44:43 -05:00
Bogdan
32fe345144 New: Support removed for linux-x86 2025-09-07 10:44:20 -05:00
Bogdan
9d2193636e New: Migrate appdata folder for .NET 8 on OSX 2025-09-07 10:44:20 -05:00
Bogdan
1e898c2647 New: Bump to .NET 8
Co-authored-by: Qstick <qstick@gmail.com>
2025-09-07 10:44:20 -05:00
bakerboy448
a00ee08750 Bump to 5.28.1 2025-09-07 00:31:28 -05:00
Michon van Dooren
54cbbe05d9 New: (NFO Metadata) Include the TMDB Collection ID (#11164) 2025-09-06 05:58:07 -05:00
Mark McDowall
57f602eb02 New: Changing icon during import to blue 2025-09-03 17:02:22 -05:00
bakerboy448
e841c9b764 Bump to 5.28.0 2025-09-03 07:07:57 -05:00
bakerboy448
81bbaf8946 Fixed: Add missing translation keys 2025-09-01 11:29:59 -05:00
bakerboy448
8b4288fa18 New: UI Note that Filters are for movie properties only
Co-authored-by: PearsonFlyer <john@theediguy.com>

Closes #11200
2025-09-01 11:29:59 -05:00
Weblate
9aa3061e8e Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Gallyam Biktashev <gallyamb@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Xoores <servarr-35466@xoores.cz>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr
2025-08-30 12:09:23 -05:00
Weblate
308c58f729 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: ReDFiRe <wwsoft@abv.bg>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: rtme <pps.kmg@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translation: Servarr/Radarr
2025-08-21 21:39:34 +01:00
grapexy
d38492188a New: Georgian language support (#11209) 2025-08-17 22:11:49 -05:00
bakerboy448
50e75e1362 Bump to 5.27.5 2025-08-17 14:44:46 -04:00
bakerboy448
f36845c251 Fixed: Parse UHDBDRip as BluRay quality 2025-08-16 10:35:25 -05:00
bakerboy448
110a338fb6 Fixed: TMDb List Paging (#11201) 2025-08-16 09:20:34 -05:00
Mark McDowall
3fcbaf9259 New: Move auth success logging to debug
Closes #7978

(cherry picked from commit 9ebe043bd94d036fe2ab45f3bb3f882cda48e211)
2025-08-12 12:20:36 -05:00
Luigi
576eff1890 New: Select with poster click in movie selection (#11187) 2025-08-12 11:49:58 -05:00
jkhsjdhjs
b0284bda07 Fixed: Parse HDDVDRip as BluRay 2025-08-11 18:53:36 -05:00
Bwaffles
c78666009d New: Add Year sorting to Discover page 2025-08-11 18:52:56 -05:00
Mark McDowall
b51d1beaaa Don't log debug messages for API key validation
(cherry picked from commit 78ca30d1f81361a2dabaddd0036b764859b858af)
2025-08-11 18:32:42 -05:00
Weblate
4d22bf1ceb Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: ArLab1 <arnaud.laberge@hotmail.com>
Co-authored-by: Ethan Francois <ethanfrancois0@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: adri1m64 <adrien.melle@laposte.net>
Co-authored-by: deamok <deamok@gmail.com>
Co-authored-by: dtorner <dtorner@gmail.com>
Co-authored-by: scdani <csonkadancsi@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
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/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
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/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2025-08-11 18:31:56 -05:00
bakerboy448
f9562b9b76 Bump version to 5.27.4 2025-08-03 01:10:22 -05:00
bakerboy448
6851c26328 Bump SixLabors.ImageSharp to 3.1.11 2025-07-31 21:52:59 -05:00
bakerboy448
e29be26fc9 Fixed: Prevent using Original names with other movie file tokens (#11175)
Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com>
2025-07-25 08:16:18 -05:00
bakerboy448
f6bd2f52d5 Bump version to 5.27.3 2025-07-23 08:51:28 -05:00
Denis Gheorghescu
8bef9b4da7 New:(Pushcut) Improved Notification Details (#10897) 2025-07-19 10:43:18 -04:00
Mark McDowall
787c387036 Return error if Manual Import called without items
(cherry picked from commit 4bdb0408f1bafa38b777a41babb1a775f99a94c1)
2025-07-09 16:19:57 -05:00
bakerboy448
0525256115 Bump version to 5.27.2 2025-07-08 18:37:58 -05:00
bakerboy448
5767e181b7 New: Improve Reject for Unknown Movie Messaging (#11063) 2025-07-08 18:25:51 -05:00
Mark McDowall
1cf3ef5dff New: Improve stored UI settings for multiple instances under the same host
Closes #10671
Fixes #11146

(cherry picked from commit 6677fd11168de6dbf78d03bfedf67b89dfe1df53)
2025-07-08 18:07:52 -05:00
Weblate
b6bad2398c Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: ACHN SYPS <achn.syps@gmail.com>
Co-authored-by: EdiTurn <yyxstter@gmail.com>
Co-authored-by: Hugoren Martinako <aumpfbahn@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: josef <josef.holzapfel@proton.me>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2025-07-08 18:06:46 -05:00
nuxen
16308e4b1c Fixed: xvid not always detected correctly (#11138) 2025-07-07 20:00:13 -05:00
bakerboy448
bd7465fae4 Fixed: Allow Discover Exclusions of Movies without Year (Year 0)
Fixes #11135
2025-06-28 09:07:26 -05:00
Weblate
c0d70485c3 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Gallyam Biktashev <gallyamb@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: HanaO00 <lwin24452@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr
2025-06-19 18:20:22 -05:00
Bogdan
c743383912 Fixed: Deleting tags from UI
Fixes #11131
2025-06-16 20:34:00 +03:00
Servarr
d93c1d7808 Automated API Docs update 2025-06-16 20:22:31 +03:00
nuxen
0e2e7e4259 New: Support for multiple movieIds in Rename API endpoint 2025-06-16 19:09:19 +03:00
Bogdan
e6b27512c9 Bump version to 5.27.1 2025-06-15 09:20:29 +03:00
Bogdan
dae5e86b2c Fixed: Skip title searches for Newznab/Torznab indexers when movie year is missing
Prevents useless text searches of `Movie Title 0` when year is missing.

Fixes #10569
2025-06-14 13:20:11 +03:00
Bogdan
71f032d175 Bump Polly to 8.6.0 2025-06-11 23:13:54 +03:00
Bogdan
5a6db29dbd Bump version to 5.27.0 2025-06-11 23:11:20 +03:00
130 changed files with 835 additions and 451 deletions

View File

@@ -2,7 +2,7 @@
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{
"name": "Radarr",
"image": "mcr.microsoft.com/devcontainers/dotnet:1-6.0",
"image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true,

2
.vscode/launch.json vendored
View File

@@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build dotnet",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/_output/net6.0/Radarr",
"program": "${workspaceFolder}/_output/net8.0/Radarr",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console

View File

@@ -9,13 +9,13 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '5.26.2'
majorVersion: '6.0.0'
minorVersion: $[counter('minorVersion', 2000)]
radarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
sentryOrg: 'servarr'
sentryUrl: 'https://sentry.servarr.com'
dotnetVersion: '6.0.427'
dotnetVersion: '8.0.405'
nodeVersion: '20.X'
innoVersion: '6.2.2'
windowsImage: 'windows-2022'
@@ -106,7 +106,7 @@ stages:
echo "Extra platforms already enabled"
else
echo "Enabling extra platform support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64/' "$BUNDLEDVERSIONS"
fi
displayName: Enable Extra Platform Support
- bash: ./build.sh --backend --enable-extra-platforms
@@ -122,27 +122,23 @@ stages:
artifact: '$(osName)Backend'
displayName: Publish Backend
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/win-x64/publish'
- publish: '$(testsFolder)/net8.0/win-x64/publish'
artifact: win-x64-tests
displayName: Publish win-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-x64/publish'
- publish: '$(testsFolder)/net8.0/linux-x64/publish'
artifact: linux-x64-tests
displayName: Publish linux-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-x86/publish'
artifact: linux-x86-tests
displayName: Publish linux-x86 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-musl-x64/publish'
- publish: '$(testsFolder)/net8.0/linux-musl-x64/publish'
artifact: linux-musl-x64-tests
displayName: Publish linux-musl-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/freebsd-x64/publish'
- publish: '$(testsFolder)/net8.0/freebsd-x64/publish'
artifact: freebsd-x64-tests
displayName: Publish freebsd-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/osx-x64/publish'
- publish: '$(testsFolder)/net8.0/osx-x64/publish'
artifact: osx-x64-tests
displayName: Publish osx-x64 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
@@ -189,7 +185,7 @@ stages:
artifact: '$(osName)Frontend'
displayName: Publish Frontend
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- stage: Installer
dependsOn:
- Build_Backend
@@ -260,21 +256,21 @@ stages:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).windows-core-x64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x64/net6.0
rootFolderOrFile: $(artifactsFolder)/win-x64/net8.0
- task: ArchiveFiles@2
displayName: Create win-x86 zip
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).windows-core-x86.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x86/net6.0
rootFolderOrFile: $(artifactsFolder)/win-x86/net8.0
- task: ArchiveFiles@2
displayName: Create osx-x64 app
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-app-core-x64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net6.0
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net8.0
- task: ArchiveFiles@2
displayName: Create osx-x64 tar
inputs:
@@ -282,14 +278,14 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64/net6.0
rootFolderOrFile: $(artifactsFolder)/osx-x64/net8.0
- task: ArchiveFiles@2
displayName: Create osx-arm64 app
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-app-core-arm64.zip'
archiveType: 'zip'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net6.0
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net8.0
- task: ArchiveFiles@2
displayName: Create osx-arm64 tar
inputs:
@@ -297,7 +293,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net6.0
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-x64 tar
inputs:
@@ -305,7 +301,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x64/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-x64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-musl-x64 tar
inputs:
@@ -313,15 +309,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net6.0
- task: ArchiveFiles@2
displayName: Create linux-x86 tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-x86.tar.gz'
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x86/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-arm tar
inputs:
@@ -329,7 +317,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-arm/net8.0
- task: ArchiveFiles@2
displayName: Create linux-musl-arm tar
inputs:
@@ -337,7 +325,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net8.0
- task: ArchiveFiles@2
displayName: Create linux-arm64 tar
inputs:
@@ -345,7 +333,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net8.0
- task: ArchiveFiles@2
displayName: Create linux-musl-arm64 tar
inputs:
@@ -353,7 +341,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net6.0
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net8.0
- task: ArchiveFiles@2
displayName: Create freebsd-x64 tar
inputs:
@@ -361,7 +349,7 @@ stages:
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/freebsd-x64/net6.0
rootFolderOrFile: $(artifactsFolder)/freebsd-x64/net8.0
- publish: $(Build.ArtifactStagingDirectory)
artifact: 'Packages'
displayName: Publish Packages
@@ -392,7 +380,7 @@ stages:
SENTRY_AUTH_TOKEN: $(sentryAuthTokenServarr)
SENTRY_ORG: $(sentryOrg)
SENTRY_URL: $(sentryUrl)
- stage: Unit_Test
displayName: Unit Tests
dependsOn: Build_Backend
@@ -493,29 +481,19 @@ stages:
testName: 'Musl Net Core'
artifactName: linux-musl-x64-tests
containerImage: ghcr.io/servarr/testimages:alpine
linux-x86:
testName: 'linux-x86'
artifactName: linux-x86-tests
containerImage: ghcr.io/servarr/testimages:linux-x86
pool:
vmImage: ${{ variables.linuxImage }}
container: $[ variables['containerImage'] ]
timeoutInMinutes: 10
steps:
- task: UseDotNet@2
displayName: 'Install .NET'
inputs:
version: $(dotnetVersion)
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
- bash: |
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
displayName: 'Install .NET'
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
- checkout: none
- task: DownloadPipelineArtifact@2
displayName: Download Test Artifact
@@ -559,7 +537,7 @@ stages:
vmImage: ${{ variables.linuxImage }}
timeoutInMinutes: 10
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
@@ -611,12 +589,12 @@ stages:
Radarr__Postgres__Port: '5432'
Radarr__Postgres__User: 'radarr'
Radarr__Postgres__Password: 'radarr'
pool:
vmImage: ${{ variables.linuxImage }}
timeoutInMinutes: 10
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
@@ -699,7 +677,7 @@ stages:
pool:
vmImage: $(imageName)
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
@@ -721,7 +699,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -776,7 +754,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -840,7 +818,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -926,29 +904,18 @@ stages:
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 }}
container: $[ variables['containerImage'] ]
timeoutInMinutes: 15
steps:
- task: UseDotNet@2
displayName: 'Install .NET'
inputs:
version: $(dotnetVersion)
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
- bash: |
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
displayName: 'Install .NET'
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
- checkout: none
- task: DownloadPipelineArtifact@2
displayName: Download Test Artifact
@@ -965,7 +932,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -988,7 +955,7 @@ stages:
- stage: Automation
displayName: Automation
dependsOn: Packages
jobs:
- job: Automation
strategy:
@@ -1014,7 +981,7 @@ stages:
pool:
vmImage: $(imageName)
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
@@ -1036,7 +1003,7 @@ stages:
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
@@ -1161,7 +1128,7 @@ stages:
- checkout: self
submodules: true
persistCredentials: true
fetchDepth: 1
fetchDepth: 1
- bash: ./docs.sh Windows
displayName: Create openapi.json
- bash: |
@@ -1230,13 +1197,13 @@ stages:
sonar.cs.opencover.reportsPaths=$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml
sonar.cs.nunit.reportsPaths=$(Build.SourcesDirectory)/TestResult.xml
- bash: |
./build.sh --backend -f net6.0 -r win-x64
TEST_DIR=_tests/net6.0/win-x64/publish/ ./test.sh Windows Unit Coverage
./build.sh --backend -f net8.0 -r win-x64
TEST_DIR=_tests/net8.0/win-x64/publish/ ./test.sh Windows Unit Coverage
displayName: Coverage Unit Tests
- task: SonarCloudAnalyze@3
condition: eq(variables['System.PullRequest.IsFork'], 'False')
displayName: Publish SonarCloud Results
- task: reportgenerator@5.3.11
- task: reportgenerator@5
displayName: Generate Coverage Report
inputs:
reports: '$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml'
@@ -1274,4 +1241,3 @@ stages:
DISCORDCHANNELID: $(discordChannelId)
DISCORDWEBHOOKKEY: $(discordWebhookKey)
DISCORDTHREADID: $(discordThreadId)

View File

@@ -33,14 +33,14 @@ EnableExtraPlatformsInSDK()
echo "Extra platforms already enabled"
else
echo "Enabling extra platform support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64/' "$BUNDLEDVERSIONS"
fi
}
EnableExtraPlatforms()
{
if grep -qv freebsd-x64 src/Directory.Build.props; then
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64;linux-x86</RuntimeIdentifiers>^g" src/Directory.Build.props
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64</RuntimeIdentifiers>^g" src/Directory.Build.props
fi
}
@@ -79,9 +79,9 @@ Build()
if [[ -z "$RID" || -z "$FRAMEWORK" ]];
then
dotnet msbuild -restore $slnFile -p:Configuration=Release -p:Platform=$platform -t:PublishAllRids
dotnet msbuild -restore $slnFile -p:SelfContained=True -p:Configuration=Release -p:Platform=$platform -t:PublishAllRids
else
dotnet msbuild -restore $slnFile -p:Configuration=Release -p:Platform=$platform -p:RuntimeIdentifiers=$RID -t:PublishAllRids
dotnet msbuild -restore $slnFile -p:SelfContained=True -p:Configuration=Release -p:Platform=$platform -p:RuntimeIdentifiers=$RID -t:PublishAllRids
fi
ProgressEnd 'Build'
@@ -137,7 +137,7 @@ PackageLinux()
echo "Adding Radarr.Mono to UpdatePackage"
cp $folder/Radarr.Mono.* $folder/Radarr.Update
if [ "$framework" = "net6.0" ]; then
if [ "$framework" = "net8.0" ]; then
cp $folder/Mono.Posix.NETStandard.* $folder/Radarr.Update
cp $folder/libMonoPosixHelper.* $folder/Radarr.Update
fi
@@ -165,7 +165,7 @@ PackageMacOS()
echo "Adding Radarr.Mono to UpdatePackage"
cp $folder/Radarr.Mono.* $folder/Radarr.Update
if [ "$framework" = "net6.0" ]; then
if [ "$framework" = "net8.0" ]; then
cp $folder/Mono.Posix.NETStandard.* $folder/Radarr.Update
cp $folder/libMonoPosixHelper.* $folder/Radarr.Update
fi
@@ -377,15 +377,14 @@ then
Build
if [[ -z "$RID" || -z "$FRAMEWORK" ]];
then
PackageTests "net6.0" "win-x64"
PackageTests "net6.0" "win-x86"
PackageTests "net6.0" "linux-x64"
PackageTests "net6.0" "linux-musl-x64"
PackageTests "net6.0" "osx-x64"
PackageTests "net8.0" "win-x64"
PackageTests "net8.0" "win-x86"
PackageTests "net8.0" "linux-x64"
PackageTests "net8.0" "linux-musl-x64"
PackageTests "net8.0" "osx-x64"
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then
PackageTests "net6.0" "freebsd-x64"
PackageTests "net6.0" "linux-x86"
PackageTests "net8.0" "freebsd-x64"
fi
else
PackageTests "$FRAMEWORK" "$RID"
@@ -413,20 +412,19 @@ then
if [[ -z "$RID" || -z "$FRAMEWORK" ]];
then
Package "net6.0" "win-x64"
Package "net6.0" "win-x86"
Package "net6.0" "linux-x64"
Package "net6.0" "linux-musl-x64"
Package "net6.0" "linux-arm64"
Package "net6.0" "linux-musl-arm64"
Package "net6.0" "linux-arm"
Package "net6.0" "linux-musl-arm"
Package "net6.0" "osx-x64"
Package "net6.0" "osx-arm64"
Package "net8.0" "win-x64"
Package "net8.0" "win-x86"
Package "net8.0" "linux-x64"
Package "net8.0" "linux-musl-x64"
Package "net8.0" "linux-arm64"
Package "net8.0" "linux-musl-arm64"
Package "net8.0" "linux-arm"
Package "net8.0" "linux-musl-arm"
Package "net8.0" "osx-x64"
Package "net8.0" "osx-arm64"
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
then
Package "net6.0" "freebsd-x64"
Package "net6.0" "linux-x86"
Package "net8.0" "freebsd-x64"
fi
else
Package "$FRAMEWORK" "$RID"
@@ -436,7 +434,7 @@ fi
if [ "$INSTALLER" = "YES" ];
then
InstallInno
BuildInstaller "net6.0" "win-x64"
BuildInstaller "net6.0" "win-x86"
BuildInstaller "net8.0" "win-x64"
BuildInstaller "net8.0" "win-x86"
RemoveInno
fi

View File

@@ -1,7 +1,7 @@
#!/bin/bash
set -e
FRAMEWORK="net6.0"
FRAMEWORK="net8.0"
PLATFORM=$1
ARCHITECTURE="${2:-x64}"
@@ -38,7 +38,7 @@ dotnet clean $slnFile -c Release
dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids
dotnet new tool-manifest
dotnet tool install --version 6.6.2 Swashbuckle.AspNetCore.Cli
dotnet tool install --version 8.1.4 Swashbuckle.AspNetCore.Cli
dotnet tool run swagger tofile --output ./src/Radarr.Api.V3/openapi.json "$outputFolder/$FRAMEWORK/$RUNTIME/$application" v3 &

View File

@@ -26,7 +26,7 @@ function BlocklistDetailsModal(props: BlocklistDetailsModalProps) {
return (
<Modal isOpen={isOpen} onModalClose={onModalClose}>
<ModalContent onModalClose={onModalClose}>
<ModalHeader>Details</ModalHeader>
<ModalHeader>{translate('Details')}</ModalHeader>
<ModalBody>
<DescriptionList>

View File

@@ -304,7 +304,7 @@ function Queue() {
<PageToolbar>
<PageToolbarSection>
<PageToolbarButton
label="Refresh"
label={translate('Refresh')}
iconName={icons.REFRESH}
isSpinning={isRefreshing}
onPress={handleRefreshPress}

View File

@@ -90,7 +90,7 @@ function QueueStatus(props: QueueStatusProps) {
if (trackedDownloadState === 'importing') {
title += ` - ${translate('Importing')}`;
iconKind = kinds.PURPLE;
iconKind = kinds.PRIMARY;
}
if (trackedDownloadState === 'failedPending') {

View File

@@ -56,6 +56,8 @@ function CustomFiltersModalContent(props) {
{translate('AddCustomFilter')}
</Button>
</div>
<br />
{translate('FilterMoviePropertiesOnlyNotFileWarning')}
</ModalBody>
<ModalFooter>

View File

@@ -26,6 +26,10 @@
color: var(--warningColor);
}
.primary {
color: var(--primaryColor);
}
.purple {
color: var(--purple);
}

View File

@@ -6,6 +6,7 @@ interface CssExports {
'disabled': string;
'info': string;
'pink': string;
'primary': string;
'purple': string;
'success': string;
'warning': string;

View File

@@ -47,6 +47,15 @@ function DiscoverMovieSortMenu(props) {
{translate('Studio')}
</SortMenuItem>
<SortMenuItem
name="year"
sortKey={sortKey}
sortDirection={sortDirection}
onPress={onSortSelect}
>
{translate('Year')}
</SortMenuItem>
<SortMenuItem
name="inCinemas"
sortKey={sortKey}

View File

@@ -36,7 +36,8 @@
.imdbRating,
.rottenTomatoesRating,
.traktRating,
.runtime {
.runtime,
.year {
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
flex: 0 0 90px;

View File

@@ -22,6 +22,7 @@ interface CssExports {
'studio': string;
'tmdbRating': string;
'traktRating': string;
'year': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -61,7 +61,8 @@
.imdbRating,
.rottenTomatoesRating,
.traktRating,
.runtime {
.runtime,
.year {
composes: cell;
flex: 0 0 90px;

View File

@@ -28,6 +28,7 @@ interface CssExports {
'studio': string;
'tmdbRating': string;
'traktRating': string;
'year': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -167,6 +167,14 @@ class DiscoverMovieRow extends Component {
);
}
if (name === 'year') {
return (
<VirtualTableRowCell key={name} className={styles[name]}>
{year}
</VirtualTableRowCell>
);
}
if (name === 'collection') {
return (
<VirtualTableRowCell

View File

@@ -284,7 +284,7 @@ const MovieIndex = withScrollPosition((props: MovieIndexProps) => {
/>
<MovieIndexSelectAllButton
label="SelectAll"
label={translate('SelectAll')}
isSelectMode={isSelectMode}
overflowComponent={MovieIndexSelectAllMenuItem}
/>

View File

@@ -1,5 +1,6 @@
import React, { useCallback, useState } from 'react';
import React, { SyntheticEvent, useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useSelect } from 'App/SelectContext';
import { MOVIE_SEARCH, REFRESH_MOVIE } from 'Commands/commandNames';
import Icon from 'Components/Icon';
import ImdbRating from 'Components/ImdbRating';
@@ -141,8 +142,31 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
setIsDeleteMovieModalOpen(false);
}, [setIsDeleteMovieModalOpen]);
const [selectState, selectDispatch] = useSelect();
const onSelectPress = useCallback(
(event: SyntheticEvent<HTMLElement, MouseEvent>) => {
if (event.nativeEvent.ctrlKey || event.nativeEvent.metaKey) {
window.open(`/movie/${tmdbId}`, '_blank');
return;
}
const shiftKey = event.nativeEvent.shiftKey;
selectDispatch({
type: 'toggleSelected',
id: movieId,
isSelected: !selectState.selectedState[movieId],
shiftKey,
});
},
[movieId, selectState.selectedState, selectDispatch, tmdbId]
);
const link = `/movie/${tmdbId}`;
const linkProps = isSelectMode ? { onPress: onSelectPress } : { to: link };
const elementStyle = {
width: `${posterWidth}px`,
height: `${posterHeight}px`,
@@ -196,7 +220,7 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
<div className={styles.deleted} title={translate('Deleted')} />
) : null}
<Link className={styles.link} style={elementStyle} to={link}>
<Link className={styles.link} style={elementStyle} {...linkProps}>
<MoviePoster
style={elementStyle}
images={images}

View File

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

View File

@@ -100,7 +100,7 @@ function ImportList({
<TagList tags={tags} tagList={tagList} />
<div className={styles.enabled}>
<Label kind={kinds.DEFAULT} title="List Refresh Interval">
<Label kind={kinds.DEFAULT} title={translate('ListRefreshInterval')}>
{`${translate('Refresh')}: ${formatShortTimeSpan(
minRefreshInterval
)}`}

View File

@@ -54,11 +54,11 @@ function Tag({ id, label }: TagProps) {
setIsDeleteTagModalOpen(true);
}, []);
const handleConfirmDeleteTag = useCallback(() => {
const handleDeleteTagModalClose = useCallback(() => {
setIsDeleteTagModalOpen(false);
}, []);
const handleDeleteTagModalClose = useCallback(() => {
const handleConfirmDeleteTag = useCallback(() => {
dispatch(deleteTag({ id }));
}, [id, dispatch]);

View File

@@ -133,6 +133,12 @@ export const defaultState = {
isSortable: true,
isVisible: true
},
{
name: 'year',
label: () => translate('Year'),
isSortable: true,
isVisible: false
},
{
name: 'inCinemas',
label: () => translate('InCinemas'),

View File

@@ -96,14 +96,22 @@ function merge(initialState, persistedState) {
return computedState;
}
const KEY = 'radarr';
const config = {
slicer,
serialize,
merge,
key: 'radarr'
key: window.Radarr.instanceName.toLowerCase().replace(/ /g, '_') || KEY
};
export default function createPersistState() {
// Migrate existing local storage value to new key if it does not already exist.
// Leave old value as-is in case there are multiple instances using the same key.
if (config.key !== KEY && localStorage.getItem(KEY) && !localStorage.getItem(config.key)) {
localStorage.setItem(config.key, localStorage.getItem(KEY));
}
// Migrate existing local storage before proceeding
const persistedState = JSON.parse(localStorage.getItem(config.key));
migrate(persistedState);

5
global.json Normal file
View File

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

View File

@@ -29,7 +29,7 @@
"@fortawesome/free-solid-svg-icons": "6.7.2",
"@fortawesome/react-fontawesome": "0.2.2",
"@juggle/resize-observer": "3.4.0",
"@microsoft/signalr": "6.0.25",
"@microsoft/signalr": "8.0.7",
"@sentry/browser": "7.119.1",
"@sentry/integrations": "7.119.1",
"@tanstack/react-query": "5.74.3",

View File

@@ -99,13 +99,6 @@
<RootNamespace Condition="'$(RadarrProject)'=='true'">$(MSBuildProjectName.Replace('Radarr','NzbDrone'))</RootNamespace>
</PropertyGroup>
<ItemGroup Condition="'$(TestProject)'!='true'">
<!-- Annotates .NET assemblies with repository information including SHA -->
<!-- Sentry uses this to link directly to GitHub at the exact version/file/line -->
<!-- This is built-in on .NET 8 and can be removed once the project is updated -->
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
<!-- Sentry specific configuration: Only in Release mode -->
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<!-- https://docs.sentry.io/platforms/dotnet/configuration/msbuild/ -->
@@ -136,7 +129,7 @@
<PackageReference Include="NunitXml.TestLogger" Version="3.0.131" />
</ItemGroup>
<ItemGroup Condition="'$(TestProject)'=='true' and '$(TargetFramework)'=='net6.0'">
<ItemGroup Condition="'$(TestProject)'=='true' and '$(TargetFramework)'=='net8.0'">
<PackageReference Include="coverlet.collector" Version="3.0.4-preview.27.ge7cb7c3b40" />
</ItemGroup>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NBuilder" Version="6.1.0" />

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Selenium.Support" Version="3.141.0" />

View File

@@ -10,7 +10,7 @@ namespace NzbDrone.Common.Test.EnvironmentInfo
[Test]
public void should_return_version()
{
BuildInfo.Version.Major.Should().BeOneOf(5, 10);
BuildInfo.Version.Major.Should().BeOneOf(6, 10);
}
[Test]

View File

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

View File

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

View File

@@ -75,6 +75,17 @@ namespace NzbDrone.Common.EnvironmentInfo
{
try
{
if (OsInfo.IsOsx)
{
var userAppDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile, Environment.SpecialFolderOption.DoNotVerify), ".config", "Radarr");
if (_diskProvider.FolderExists(userAppDataFolder) && !_diskProvider.FileExists(_appFolderInfo.GetConfigPath()))
{
_diskTransferService.MirrorFolder(userAppDataFolder, _appFolderInfo.AppDataFolder);
_diskProvider.DeleteFolder(userAppDataFolder, true);
}
}
var oldDbFile = Path.Combine(_appFolderInfo.AppDataFolder, "nzbdrone.db");
if (_startupContext.Args.ContainsKey(StartupContext.APPDATA))

View File

@@ -202,6 +202,7 @@ namespace NzbDrone.Common.Instrumentation
c.ForLogger("Microsoft.*").WriteToNil(LogLevel.Warn);
c.ForLogger("Microsoft.Hosting.Lifetime*").WriteToNil(LogLevel.Info);
c.ForLogger("Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware").WriteToNil(LogLevel.Fatal);
c.ForLogger("Radarr.Http.Authentication.ApiKeyAuthenticationHandler").WriteToNil(LogLevel.Info);
});
}

View File

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

View File

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

View File

@@ -9,7 +9,7 @@ using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.Datastore.Migration
{
[TestFixture]
public class collectionsFixture : MigrationTest<collections>
public class collectionsFixture : MigrationTest<add_collections>
{
[Test]
public void should_add_collection_from_movie_and_link_back_to_movie()

View File

@@ -68,7 +68,8 @@ namespace NzbDrone.Core.Test.Languages
new object[] { 53, Language.Tagalog },
new object[] { 54, Language.Urdu },
new object[] { 55, Language.Romansh },
new object[] { 56, Language.Mongolian }
new object[] { 56, Language.Mongolian },
new object[] { 57, Language.Georgian }
};
public static object[] ToIntCases =
@@ -131,7 +132,8 @@ namespace NzbDrone.Core.Test.Languages
new object[] { Language.Tagalog, 53 },
new object[] { Language.Urdu, 54 },
new object[] { Language.Romansh, 55 },
new object[] { Language.Mongolian, 56 }
new object[] { Language.Mongolian, 56 },
new object[] { Language.Georgian, 57 }
};
[Test]

View File

@@ -407,6 +407,8 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
[TestCase("nor", "NO")]
[TestCase("khk", "MN")]
[TestCase("mvf", "MN")]
[TestCase("geo", "KA")]
[TestCase("kat", "KA")]
public void should_format_languagecodes_properly(string language, string code)
{
_namingConfig.StandardMovieFormat = "{Movie.Title}.{MEDIAINFO.FULL}";

View File

@@ -119,5 +119,15 @@ namespace NzbDrone.Core.Test.ParserTests
var result = IsoLanguages.Find(isoCode);
result.Language.Should().Be(Language.Bengali);
}
[TestCase("ka")]
[TestCase("geo")]
[TestCase("kat")]
[TestCase("ka-GE")]
public void should_return_georgian(string isoCode)
{
var result = IsoLanguages.Find(isoCode);
result.Language.Should().Be(Language.Georgian);
}
}
}

View File

@@ -521,6 +521,16 @@ namespace NzbDrone.Core.Test.ParserTests
result.Should().Contain(Language.Mongolian);
}
[TestCase("Movie.Title.1994.Georgian.WEB-DL.h264")]
[TestCase("Movie.Title.2016.Geo.WEB-DL.h264")]
[TestCase("Movie.Title.2016.KA.WEB-DL.h264")]
[TestCase("Movie.Title.2016.RU-KA.WEB-DL.h264")]
public void should_parse_language_georgian(string postTitle)
{
var result = LanguageParser.ParseLanguages(postTitle);
result.Should().Contain(Language.Georgian);
}
[TestCase("Movie.Title.en.sub")]
[TestCase("Movie Title.eng.sub")]
[TestCase("Movie.Title.eng.forced.sub")]

View File

@@ -294,6 +294,11 @@ 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("Movie.Title.2012.German.DL.1080p.UHD2BD.x264-QfG", false)]
[TestCase("Movie.Title.2005.1080p.HDDVDRip.x264", false)]
[TestCase("Movie.Title.2019.German.DL.1080p.HDR.UHDBDRip.AV1-GROUP", false)]
[TestCase("Movie.Title.2014.German.OPUS.DL.1080p.UHDBDRiP.HDR.AV1-GROUP", false)]
[TestCase("Movie.Title.1999.German.DL.1080p.HDR.UHDBDRip.AV1-GROUP", false)]
[TestCase("Movie.Title.1993.Uncut.German.DL.1080p.HDR.UHDBDRip.h265-GROUP", false)]
public void should_parse_bluray1080p_quality(string title, bool proper)
{
ParseAndVerifyQuality(title, QualitySource.BLURAY, proper, Resolution.R1080p);
@@ -312,6 +317,8 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Movie.Name.2020.German.UHDBD.2160p.HDR10.HEVC.EAC3.DL-pmHD.mkv", false)]
[TestCase("Movie.Title.2014.2160p.UHD.BluRay.X265-IAMABLE.mkv", false)]
[TestCase("Movie.Title.2014.2160p.BDRip.AAC.7.1.HDR10.x265.10bit-Markll", false)]
[TestCase("Movie.Title.1956.German.DL.2160p.HDR.UHDBDRip.h266-GROUP", false)]
[TestCase("Movie.Title.2021.4K.HDR.2160P.UHDBDRip.HEVC-10bit.GROUP", false)]
public void should_parse_bluray2160p_quality(string title, bool proper)
{
ParseAndVerifyQuality(title, QualitySource.BLURAY, proper, Resolution.R2160p);

View File

@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.151" />
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="NBuilder" Version="6.1.0" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
</ItemGroup>

View File

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

View File

@@ -206,13 +206,24 @@ namespace NzbDrone.Core.Configuration
if (enabled)
{
SetValue("AuthenticationMethod", AuthenticationType.Basic);
return AuthenticationType.Basic;
SetValue("AuthenticationMethod", AuthenticationType.Forms);
return AuthenticationType.Forms;
}
return Enum.TryParse<AuthenticationType>(_authOptions.Method, out var enumValue)
var value = Enum.TryParse<AuthenticationType>(_authOptions.Method, out var enumValue)
? enumValue
: GetValueEnum("AuthenticationMethod", AuthenticationType.None);
#pragma warning disable CS0618 // Type or member is obsolete
if (value == AuthenticationType.Basic)
#pragma warning restore CS0618 // Type or member is obsolete
{
SetValue("AuthenticationMethod", AuthenticationType.Forms);
return AuthenticationType.Forms;
}
return value;
}
}
@@ -386,6 +397,12 @@ namespace NzbDrone.Core.Configuration
{
SetValue("EnableSsl", false);
}
#pragma warning disable CS0618 // Type or member is obsolete
if (AuthenticationMethod == AuthenticationType.Basic)
#pragma warning restore CS0618 // Type or member is obsolete
{
SetValue("AuthenticationMethod", AuthenticationType.Forms);
}
}
private void DeleteOldValues()

View File

@@ -12,7 +12,7 @@ using NzbDrone.Core.Parser;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(208)]
public class collections : NzbDroneMigrationBase
public class add_collections : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{

View File

@@ -85,7 +85,7 @@ namespace NzbDrone.Core.DecisionEngine
if (remoteMovie.Movie == null)
{
decision = new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.UnknownMovie, "Unknown Movie. Unable to identify correct movie using release name."));
decision = new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.UnknownMovie, pushedRelease ? "Unknown Movie. Unable to match to existing movie in Library using release title." : "Unknown Movie. Unable to match to correct movie using release title."));
}
else
{

View File

@@ -280,6 +280,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
{
var setElement = new XElement("set");
setElement.SetAttributeValue("tmdbcolid", movie.MovieMetadata.Value.CollectionTmdbId);
setElement.Add(new XElement("name", movie.MovieMetadata.Value.CollectionTitle));
setElement.Add(new XElement("overview"));

View File

@@ -30,7 +30,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
{
return new HealthCheck(
GetType(),
HealthCheckResult.Warning,
HealthCheckResult.Error,
_localizationService.GetLocalizedString(
"NamingConfigMovieFolderFormatDeprecatedHealthCheckMessage", new Dictionary<string, object>
{

View File

@@ -30,6 +30,8 @@ namespace NzbDrone.Core.ImportLists
public virtual int PageSize => 0;
public virtual TimeSpan RateLimit => TimeSpan.FromSeconds(2);
protected virtual bool UsePreGeneratedPages => false;
public abstract IImportListRequestGenerator GetRequestGenerator();
public abstract IParseImportListResponse GetParser();
@@ -79,7 +81,7 @@ namespace NzbDrone.Core.ImportLists
break;
}
if (!IsFullPage(page))
if (!UsePreGeneratedPages && !IsFullPage(page))
{
break;
}
@@ -210,7 +212,26 @@ namespace NzbDrone.Core.ImportLists
{
var parser = GetParser();
var generator = GetRequestGenerator();
var releases = FetchPage(generator.GetMovies().GetAllTiers().First().First(), parser);
var pageableRequests = generator.GetMovies();
var allTiers = pageableRequests.GetAllTiers();
if (!allTiers.Any())
{
return new NzbDroneValidationFailure(string.Empty,
"No pages were returned from your import list, please check your settings and the log for details.")
{ IsWarning = true };
}
var firstTier = allTiers.First();
if (!firstTier.Any())
{
return new NzbDroneValidationFailure(string.Empty,
"No data could be retrieved from your import list, please check your settings.")
{ IsWarning = true };
}
var firstRequest = firstTier.First();
var releases = FetchPage(firstRequest, parser);
if (releases.Empty())
{

View File

@@ -24,7 +24,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.List
private IEnumerable<ImportListRequest> GetMoviesRequest()
{
Logger.Info("Importing TMDb movies from list: {0}", Settings.ListId);
Logger.Info("TMDb List {0}: Importing movies", Settings.ListId);
var requestBuilder = RequestBuilder.Create()
.SetSegment("api", "4")
@@ -32,19 +32,25 @@ namespace NzbDrone.Core.ImportLists.TMDb.List
.SetSegment("id", Settings.ListId)
.SetSegment("secondaryRoute", "");
Logger.Debug("Getting total pages that TMDb List: {0} consists of", Settings.ListId);
Logger.Trace("TMDb List {0}: Getting total pages", Settings.ListId);
var jsonResponse = JsonConvert.DeserializeObject<MovieSearchResource>(HttpClient.Execute(requestBuilder.Build()).Content);
MaxPages = jsonResponse.TotalPages;
if (jsonResponse.TotalPages > 1)
{
Logger.Debug("TMDb List {0}: processing {1} pages", Settings.ListId, MaxPages);
}
for (var pageNumber = 1; pageNumber <= MaxPages; pageNumber++)
{
requestBuilder.AddQueryParam("page", pageNumber, true);
var request = requestBuilder.Build();
Logger.Debug("Importing TMDb movies from: {0}", request.Url);
Logger.Debug("TMDb List {0}: Processing page {1} of {2}", Settings.ListId, pageNumber, MaxPages);
Logger.Trace("TMDb List {0}: Request URL: {1}", Settings.ListId, request.Url);
yield return new ImportListRequest(request);
}

View File

@@ -119,7 +119,8 @@ namespace NzbDrone.Core.ImportLists.TMDb.Popular
var request = requestBuilder.Build();
Logger.Debug("Importing TMDb movies from: {0}", request.Url);
Logger.Debug("TMDb Popular: Processing page {0} of {1}", pageNumber, MaxPages);
Logger.Trace("TMDb Popular: Request URL: {0}", request.Url);
yield return new ImportListRequest(request);
}

View File

@@ -14,6 +14,7 @@ namespace NzbDrone.Core.ImportLists.TMDb
public override ImportListType ListType => ImportListType.TMDB;
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
public override int PageSize => 20;
protected override bool UsePreGeneratedPages => true;
public readonly ISearchForNewMovie _skyhookProxy;
public readonly IHttpRequestBuilderFactory _requestBuilder;

View File

@@ -75,6 +75,8 @@ namespace NzbDrone.Core.ImportLists.TMDb
[FieldOption(Hint = "Raeto-Romance")]
rm,
[FieldOption(Hint = "Mongolian")]
mn
mn,
[FieldOption(Hint = "Georgian")]
ka
}
}

View File

@@ -52,17 +52,25 @@ namespace NzbDrone.Core.ImportLists.TMDb.User
requestBuilder.Method = HttpMethod.Get;
Logger.Trace("TMDb User {0}: Getting total pages", (TMDbUserListType)Settings.ListType);
var jsonResponse = JsonConvert.DeserializeObject<MovieSearchResource>(HttpClient.Execute(requestBuilder.Build()).Content);
MaxPages = jsonResponse.TotalPages;
if (jsonResponse.TotalPages > 1)
{
Logger.Debug("TMDb User {0}: processing {1} pages", (TMDbUserListType)Settings.ListType, MaxPages);
}
for (var pageNumber = 1; pageNumber <= MaxPages; pageNumber++)
{
requestBuilder.AddQueryParam("page", pageNumber, true);
var request = requestBuilder.Build();
Logger.Debug("Importing TMDb movies from: {0}", request.Url);
Logger.Debug("TMDb User {0}: Processing page {1} of {2}", (TMDbUserListType)Settings.ListType, pageNumber, MaxPages);
Logger.Trace("TMDb User {0}: Request URL: {1}", (TMDbUserListType)Settings.ListType, request.Url);
yield return new ImportListRequest(request);
}

View File

@@ -152,17 +152,18 @@ namespace NzbDrone.Core.Indexers.Newznab
}
}
if (SupportsSearch)
if (SupportsSearch && searchCriteria.Movie.Year > 0)
{
chain.AddTier();
var queryTitles = TextSearchEngine == "raw" ? searchCriteria.SceneTitles : searchCriteria.CleanSceneTitles;
foreach (var queryTitle in queryTitles)
{
var searchQuery = queryTitle;
if (!Settings.RemoveYear)
{
searchQuery = $"{searchQuery} {searchCriteria.Movie.Year}";
searchQuery += $" {searchCriteria.Movie.Year}";
}
chain.Add(GetPagedRequests(MaxPages,

View File

@@ -127,6 +127,7 @@ namespace NzbDrone.Core.Languages
public static Language Urdu => new Language(54, "Urdu");
public static Language Romansh => new Language(55, "Romansh");
public static Language Mongolian => new Language(56, "Mongolian");
public static Language Georgian => new Language(57, "Georgian");
public static Language Any => new Language(-1, "Any");
public static Language Original => new Language(-2, "Original");
@@ -193,6 +194,7 @@ namespace NzbDrone.Core.Languages
Urdu,
Romansh,
Mongolian,
Georgian,
Any,
Original
};

View File

@@ -1204,5 +1204,19 @@
"IndexerHDBitsSettingsCategories": "Категории",
"IndexerHDBitsSettingsMediums": "Среден",
"IndexerSettingsCategories": "Категории",
"ReleaseProfile": "Профил за издания"
"ReleaseProfile": "Профил за издания",
"CinemaRelease": "Пуснат по кината",
"BlocklistedAt": "Блокиран на {date}",
"Complete": "Завърши",
"DeleteSelected": "Изтрийте избраните",
"CollectionShowDetailsHelpText": "Покажи статуса и свойствата на колекцията",
"AutoTaggingSpecificationStudio": "Студио(я)",
"Completed": "Завършено",
"DelayMinutes": "{delay} Минути",
"Category": "Категория",
"AutoTaggingSpecificationKeyword": "Ключова(и) дума(и)",
"ChangeCategory": "Промени категорията",
"DefaultNotFoundMessage": "Трябва да сте се изгубили, няма какво да видите тук.",
"ClearBlocklist": "Изчисти списъка с блокирани",
"CountMissingMoviesFromLibrary": "Липсващи филми от библеотеката : {count}"
}

View File

@@ -2019,5 +2019,22 @@
"NotificationsAppriseSettingsIncludePosterHelpText": "Inclou el pòster al missatge",
"CloneImportList": "Clonar llista d'importació",
"DefaultNameCopiedImportList": "{name} - Còpia",
"ReleaseProfile": "Perfil de llançament"
"ReleaseProfile": "Perfil de llançament",
"CountMissingMoviesFromLibrary": "{count} pel·lícules que manquen de la biblioteca",
"ShowPhysicalReleaseCalendarHelpText": "Mostra els llançaments físics en els esdeveniments del calendari",
"CinemaRelease": "Llançament en cinemes",
"ShowDigitalRelease": "Mostra la versió digital",
"ICalReleaseTypesMoviesHelpText": "Inclou només pel·lícules amb tipus de llançament específics al canal iCal. Si no s'especifica, s'utilitzen totes les opcions.",
"ShowDigitalReleaseCalendarHelpText": "Mostra els llançaments digitals en els esdeveniments del calendari",
"RemoveRootFolderMoviesMessageText": "Esteu segur que voleu eliminar la carpeta arrel '{path}'? Els fitxers i carpetes no s'eliminaran del disc, i les pel·lícules d'aquesta carpeta arrel no s'eliminaran de {appName}.",
"ICalReleaseTypes": "Tipus de llançament",
"Keywords": "Paraules clau",
"ShowPhysicalRelease": "Mostra la versió física",
"ShowCinemaRelease": "Mostra el llançament del cinema",
"ShowCinemaReleaseCalendarHelpText": "Mostra els llançaments de cinema en els esdeveniments del calendari",
"AutoTaggingSpecificationKeyword": "Paraula(es) clau",
"NotificationsPushcutSettingsIncludePoster": "Inclou el cartell",
"NotificationsPushcutSettingsIncludePosterHelpText": "Inclou el cartell amb notificació",
"NotificationsPushcutSettingsMetadataLinks": "Enllaços de metadades",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Afegeix un enllaç a les metadades de les sèries quan s'enviïn notificacions"
}

View File

@@ -46,7 +46,7 @@
"DeleteRestrictionHelpText": "Opravdu chcete toto omezení smazat?",
"DeleteTagMessageText": "Opravdu chcete smazat značku „{0}“?",
"DetailedProgressBar": "Podrobný ukazatel průběhu",
"Discord": "Svár",
"Discord": "Discord",
"DownloadClients": "Stáhnout klienty",
"DownloadClientsSettingsSummary": "Stahování klientů, zpracování stahování a mapování vzdálených cest",
"DownloadPropersAndRepacks": "Sponzoři a přebalení",
@@ -190,7 +190,7 @@
"DeleteCustomFormat": "Odstranit vlastní formát",
"DeletedMovieDescription": "Film byl odstraněn z TMDb",
"DeleteMovieFolder": "Odstranit složku filmu",
"DockerUpdater": "aktualizujte kontejner dockeru, abyste aktualizaci obdrželi",
"DockerUpdater": "Pro získání aktualizace je třeba aktualizovat docker kontejner",
"AddToDownloadQueue": "Přidat stahování do fronty",
"AfterManualRefresh": "Po manuálním obnovení",
"AllFiles": "Všechny soubory",
@@ -347,12 +347,12 @@
"Local": "Místní",
"ManualImport": "Ruční import",
"MarkAsFailed": "Označit jako neúspěšné",
"MaximumSizeHelpText": "Maximální velikost uvolnění, která se má zachytit v MB. Nastavit na nulu nastavit na neomezený",
"MaximumSizeHelpText": "Maximální velikost vydání, která se mají stahovat v MB. Nula znamená bez omezení",
"Mechanism": "Mechanismus",
"MediaInfo": "Informace o médiích",
"MediaManagement": "Správa médií",
"MediaManagementSettings": "Nastavení správy médií",
"MediaManagementSettingsSummary": "Nastavení pojmenování a správy souborů",
"MediaManagementSettingsSummary": "Nastavení jmenné konvence a správy souborů",
"Hostname": "Název hostitele",
"Missing": "Chybějící",
"Month": "Měsíc",
@@ -436,7 +436,7 @@
"RestartRequiredHelpTextWarning": "Vyžaduje restart, aby se projevilo",
"Restore": "Obnovit",
"RestoreBackup": "Obnovit zálohu",
"RootFolder": "Kořenový adresář",
"RootFolder": "Kořenová složka",
"RootFolderCheckMultipleMessage": "Chybí více kořenových složek: {rootFolderPaths}",
"SendAnonymousUsageData": "Odesílejte anonymní údaje o používání",
"FileBrowserPlaceholderText": "Začněte psát nebo vyberte cestu níže",
@@ -495,7 +495,7 @@
"CustomFormatsSettingsSummary": "Vlastní formáty a nastavení",
"CustomFormatUnknownConditionOption": "Neznámá možnost „{key}“ pro podmínku „{implementation}“",
"Cutoff": "Odříznout",
"UpgradeUntilMovieHelpText": "Jakmile je této kvality dosaženo, {appName} již nebude stahovat filmy",
"UpgradeUntilMovieHelpText": "Jakmile stažený film dosáhne nebo překročí nastavenou kvalitu, {appName} nebude dále stahovat další vydání",
"CutoffUnmet": "Mezní hodnota nesplněna",
"Days": "Dny",
"Debug": "Ladit",
@@ -503,7 +503,7 @@
"DefaultDelayProfileMovie": "Toto je výchozí profil. Platí pro všechny filmy, které nemají explicitní profil.",
"DelayProfile": "Zpožděný profil",
"DelayProfiles": "Profily zpoždění",
"Delete": "Vymazat",
"Delete": "Smazat",
"DeleteBackupMessageText": "Opravdu chcete odstranit zálohu '{name}'?",
"Deleted": "Smazáno",
"DeleteDelayProfile": "Smazat profil zpoždění",
@@ -649,7 +649,7 @@
"LinkHere": "tady",
"Links": "Odkazy",
"ImportLists": "Seznamy",
"ImportListSettings": "Nastavení seznamu",
"ImportListSettings": "Nastavení seznamu pro import",
"ListSyncLevelHelpText": "Filmy v knihovně budou zpracovány na základě vašeho výběru, pokud vypadnou nebo se neobjeví na vašich seznamech",
"LogFiles": "Záznam souborů",
"Logging": "Protokolování",
@@ -836,7 +836,7 @@
"SourcePath": "Cesta zdroje",
"SourceRelativePath": "Cesta relativního zdroje",
"SourceTitle": "Název zdroje",
"SslCertPassword": "Heslo SSL Cert",
"SslCertPassword": "Heslo SSL Certifikátu",
"SslCertPasswordHelpText": "Heslo pro soubor pfx",
"SslCertPath": "Cesta certifikátu SSL",
"SslCertPathHelpText": "Cesta k souboru pfx",
@@ -979,7 +979,7 @@
"DeleteDelayProfileMessageText": "Opravdu chcete smazat tento profil zpoždění?",
"DeleteFormatMessageText": "Opravdu chcete smazat značku formátu {0}?",
"RemoveSelectedItemQueueMessageText": "Opravdu chcete odebrat {0} položku {1} z fronty?",
"RemoveSelectedItemsQueueMessageText": "Opravdu chcete odebrat {selectedCount} položky z fronty?",
"RemoveSelectedItemsQueueMessageText": "Opravdu chcete odebrat {selectedCount} položek z fronty?",
"ApplyTagsHelpTextAdd": "Přidat: Přidat štítky do existujícího seznamu štítků",
"ApplyTagsHelpTextHowToApplyIndexers": "Jak použít štítky na vybrané indexery",
"ApplyTagsHelpTextRemove": "Odebrat: Odebrat zadané štítky",
@@ -1037,7 +1037,7 @@
"CollectionShowPostersHelpText": "Zobrazit plakáty položek v kolekci",
"ConnectionLostReconnect": "{appName} se pokusí připojit automaticky, nebo můžete kliknout na tlačítko znovunačtení níže.",
"ConnectionLostToBackend": "{appName} ztratil spojení s backendem a pro obnovení funkčnosti bude potřeba ho znovu načíst.",
"CountDownloadClientsSelected": "{count} vybraných klientů pro stahování",
"CountDownloadClientsSelected": "{count} klientů ke stahování vybráno",
"DefaultNameCopiedProfile": "{name} - Kopírovat",
"DefaultNameCopiedSpecification": "{name} - Kopírovat",
"DelayingDownloadUntil": "Odložení stahování do {date} v {time}",
@@ -1078,7 +1078,7 @@
"CountImportListsSelected": "{count} vybraných seznamů pro import",
"CollectionShowDetailsHelpText": "Zobrazit stav a vlastnosti kolekce",
"AutoTaggingNegateHelpText": "Pokud je zaškrtnuto, pravidlo automatického označování se nepoužije, pokud odpovídá této podmínce {implementationName}.",
"DownloadClientSortingCheckMessage": "Klient pro stahování {downloadClientName} má nastaveno třídění {sortingMode} pro kategorii {appName}. Ve svém klientovi pro stahování byste měli třídění zakázat, abyste se vyhnuli problémům s importem.",
"DownloadClientSortingCheckMessage": "Klient pro stahování {downloadClientName} má nastaveno třídění {sortingMode} pro kategorie {appName}. Je doporučeno toto třídění vypnout, abyste se vyhli případným problémům s importem.",
"EditSelectedImportLists": "Upravit vybrané seznamy k importu",
"EditSelectedIndexers": "Upravit vybrané indexery",
"DisabledForLocalAddresses": "Zakázáno pro místní adresy",
@@ -1278,7 +1278,7 @@
"CutoffUnmetLoadError": "Chybné načítání nesplněných položek",
"CutoffUnmetNoItems": "Žádné neodpovídající nesplněné položky",
"ClickToChangeIndexerFlags": "Kliknutím změníte značky indexeru",
"RecycleBinUnableToWriteHealthCheck": "Nelze zapisovat do nakonfigurované složky koše: {path}. Ujistěte se, že tato cesta existuje a že do ní může zapisovat uživatel se spuštěnou {appName}",
"RecycleBinUnableToWriteHealthCheck": "Nelze zapisovat do nakonfigurované složky koše: {path}. Ujistěte se, že tato cesta existuje a že do ní může zapisovat uživatel, pod kterým běží {appName}",
"AutoTaggingSpecificationMaximumYear": "Maximální Rok",
"AutoTaggingSpecificationMinimumYear": "Minimální Rok",
"ChangeCategoryHint": "Změní stahování do kategorie „Post-Import“ z aplikace Download Client",
@@ -1366,5 +1366,25 @@
"DownloadClientItemErrorMessage": "{clientName} hlásí chybu: {message}",
"CloneImportList": "Klonovat seznam Importu",
"DefaultNameCopiedImportList": "{name} - Kopírovat",
"ReleaseProfile": "profil vydání"
"ReleaseProfile": "profil vydání",
"NotificationsPushcutSettingsIncludePoster": "Zahrnout plakát",
"RemotePathMappingCheckFilesLocalWrongOSPath": "Lokální klient pro stahování {downloadClientName} hlásí soubory v {path}, ale to není validní cesta pro {osName}. Zkontrolujte nastavení klienta pro stahování.",
"RemotePathMappingCheckLocalWrongOSPath": "Lokální klient pro stahování {downloadClientName} ukládá stažené soubory do {path}, ale vypadá to, že taková složka v {osName} neexistuje. Ověřte nastavení klienta pro stahování.",
"TaskUserAgentTooltip": "User-Agent je poskytován aplikací, která volá API",
"RemotePathMappingCheckFilesGenericPermissions": "Klient pro stahování {downloadClientName} hlásí soubory v {path}, ale {appName} tento adresář nevidí. Možná je nutné upravit práva této složky.",
"RemotePathMappingCheckGenericPermissions": "Klient pro stahování {downloadClientName} ukládá soubory do {path}, ale {appName} tento adresář nevidí. Možná je nutné upravit práva této složky.",
"RemotePathMappingCheckFileRemoved": "Soubor {path} byl smazán v průběhu zpracování.",
"RemotePathMappingCheckWrongOSPath": "Vzdálený klient pro stahování {downloadClientName}ukládá stažené soubory do {path}, ale toto není validní cesta pro {osName}. Ověřte nastavení mapování vzdálených cest a klientů pro stahování.",
"Loading": "Načítání",
"NotificationsEmbySettingsSendNotificationsHelpText": "Nechat Emby poslat notifikace nastaveným poskytovatelům. Nefunguje s Jellyfin.",
"RemotePathMappingCheckImportFailed": "{appName} nemohl importovat film. Detaily naleznete v logu.",
"RemotePathMappingCheckBadDockerPath": "Používáte docker; klient pro stahování {downloadClientName} ukládá stažené soubory do {path}, ale to není validní cesta pro {osName}. Ověřte nastavení mapování vzdálených cest a klientů pro stahování.",
"RemotePathMappingCheckFolderPermissions": "{appName} vidí, ale nemůže přistupovat do adresáře stahování {path}. Pravděpodobně jde o chybně nastavené oprávnění.{appName}.",
"RemotePathMappingCheckLocalFolderMissing": "Vzdálený klient pro stahování {downloadClientName} ukládá stažené soubory do {path}, ale vypadá to, že taková složka neexistuje. Ověřte nastavení mapování vzdálených cest a klientů pro stahování.",
"IndexerJackettAll": "Indexery, které používají nepodporovaný Jackett endpoint 'all': {indexerNames}",
"RemotePathMappingCheckFilesWrongOSPath": "Vzdálený klient pro stahování {downloadClientName} hlásí soubory v {path}, ale to není validní cesta pro {osName}. Zkontrolujte mapování vzdálených cest a nastavení klienta pro stahování.",
"RemotePathMappingCheckFilesBadDockerPath": "Používáte docker; klient pro stahování {downloadClientName} hlásí soubory v {path}, ale to není validní cesta pro {osName}. Ověřte nastavení mapování vzdálených cest a klientů pro stahování.",
"RemotePathMappingCheckDockerFolderMissing": "Používáte docker; klient pro stahování {downloadClientName} ukládá stažené soubory do {path}, ale vypadá to, že taková složka v tomto konejneru neexistuje. Ověřte nastavení mapování vzdálených cest a klientů pro stahování.",
"RemotePathMappingsInfo": "Mapování vzdálených cest je potřeba pouze ve výjimečných případech. Pokud {appName} a klient pro stahování je na stejném systému, je lepší cesty tak, aby byly všude stejné. Více informací naleznete na [wiki]({wikiLink}).",
"RemotePathMappingCheckRemoteDownloadClient": "Vzdálený klient pro stahování {downloadClientName} hlásí soubory v {path}, ale vypadá to, že taková složka neexistuje. Pravděpodobně chybí nastavení mapování vzdálených cest."
}

View File

@@ -1976,5 +1976,42 @@
"EditMovieCollectionModalHeader": "Bearbeiten - {title}",
"DownloadClientUTorrentProviderMessage": "uTorrent ist dafür bekannt, dass es Kryptominer, Malware und Werbung enthält. Wir empfehlen dringend einen anderen Client zu wählen.",
"DefaultNameCopiedImportList": "{name} Kopieren",
"ReleaseProfile": "Release-Profil"
"ReleaseProfile": "Release-Profil",
"ImportListsTraktSettingsCertificationMovieHelpText": "Filtriere Filme nach einem Zertifikat(NR,G,PG,PG-13,R,NC-17)(Beistrich getrennt)",
"ImportListsTraktSettingsRatingMovieHelpText": "Sortiere Filme nach Bewertung (0-100)",
"ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Empfohlene Filme nach Woche",
"ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Empfohlene Filme nach Jahr",
"ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Am meisten geschaute Filme nach Monat",
"IndexerSettingsBaseUrl": "Basis-Url",
"ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Am meisten geschaute Filme nach Woche",
"ImportListsTraktSettingsYearsMovieHelpText": "Filme nach Jahr oder Jahresspanne filtern",
"IndexerNewznabSettingsCategoriesHelpText": "Dropdown-Liste, mindestens eine Kategorie muss ausgewählt werden.",
"GrabbedAt": "Geholt am {date}",
"CinemaRelease": "Kinostart",
"FailedAt": "Fehlgeschlagen am {date}",
"ImportListsTraktSettingsLimitMovieHelpText": "Die Anzahl der abzurufenden Filme begrenzen",
"ImportListsTraktSettingsPopularListTypePopularMovies": "Beliebte Filme",
"ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Empfohlene Filme nach Monat",
"ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Empfohlene Filme aller Zeiten",
"ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Am meisten geschaute Filme nach Jahr",
"ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Am meisten geschaute Filme aller Zeiten",
"ImportListsTraktSettingsPopularListTypeTrendingMovies": "Filme im Trend",
"IndexerSettingsRemoveYear": "Entferne Jahr vom Suchfilter",
"AutoTaggingSpecificationStudio": "Filmstudio(s)",
"ImportListsRadarrSettingsApiKeyHelpText": "API-KEY von der {appName} Instanz für den Import von (Radarr 3.0 oder älter)",
"ImportListsRadarrSettingsFullUrlHelpText": "URL, mit Port von der {appName} Instanz für den Import von (Radarr 3.0 oder älter)",
"AutoTaggingSpecificationKeyword": "Schlüsselwort(e)",
"BlocklistedAt": "Zur Sperrliste hinzugefügt am {date}",
"CloneImportList": "Import Liste importieren",
"FileSize": "Dateigröße",
"NotificationsPushcutSettingsMetadataLinks": "Metadaten-Links",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Füge Links zu den Serienmetadaten hinzu, wenn Benachrichtigungen gesendet werden",
"DownloadClientItemErrorMessage": "{clientName} meldet einen Fehler: {message}",
"ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Top-Kinokassenfilme",
"ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "Meist erwartete Filme",
"CountMissingMoviesFromLibrary": "{count} fehlende(r) Film(e) in der Bibliothek",
"ICalReleaseTypes": "Veröffentlichungstypen",
"ICalReleaseTypesMoviesHelpText": "Nur Filme mit bestimmten Veröffentlichungstypen im iCal-Feed einbeziehen. Wenn nicht angegeben, werden alle Optionen verwendet.",
"IndexerFileListSettingsCategoriesHelpText": "Kategorien zur Verwendung in Suche und Feeds. Wenn nicht angegeben, werden alle Optionen verwendet.",
"ImportListsTraktSettingsGenresMovieHelpText": "Filme nach Trakt-Genre-Slug filtern (durch Kommas getrennt) nur für beliebte Listen"
}

View File

@@ -698,6 +698,7 @@
"FilterNotInNext": "not in the next",
"FilterStartsWith": "starts with",
"Filters": "Filters",
"FilterMoviePropertiesOnlyNotFileWarning": "Filters are available only for the properties of a movie, they are not available for properties of the file(s) you may have for that movie.",
"FirstDayOfWeek": "First Day of Week",
"Fixed": "Fixed",
"Folder": "Folder",
@@ -1328,6 +1329,10 @@
"NotificationsPushBulletSettingsDeviceIds": "Device IDs",
"NotificationsPushBulletSettingsDeviceIdsHelpText": "List of device IDs (leave blank to send to all devices)",
"NotificationsPushcutSettingsApiKeyHelpText": "API Keys can be managed in the Account view of the Pushcut app",
"NotificationsPushcutSettingsIncludePoster": "Include Poster",
"NotificationsPushcutSettingsIncludePosterHelpText": "Include poster with notification",
"NotificationsPushcutSettingsMetadataLinks": "Metadata Links",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Add a links to series metadata when sending notifications",
"NotificationsPushcutSettingsNotificationName": "Notification Name",
"NotificationsPushcutSettingsNotificationNameHelpText": "Notification name from Notifications tab of the Pushcut app",
"NotificationsPushcutSettingsTimeSensitive": "Time Sensitive",
@@ -2033,4 +2038,4 @@
"Yesterday": "Yesterday",
"YesterdayAt": "Yesterday at {time}",
"YouCanAlsoSearch": "You can also search using TMDb ID or IMDb ID of a movie. e.g. `tmdb:71663`"
}
}

View File

@@ -997,7 +997,7 @@
"OriginalTitle": "Título original",
"OriginalLanguage": "Idioma original",
"Rating": "Valoración",
"RemoveFailed": "Fallo al eliminar",
"RemoveFailed": "Eliminar Fallidas",
"RemotePathMappingCheckFolderPermissions": "{appName} puede ver pero no acceder al directorio de descarga {path}. Probablemente sea un error de permisos.",
"RemotePathMappingCheckGenericPermissions": "El cliente de descarga {downloadClientName} coloca las descargas en {path} pero {appName} no puede ver este directorio. Es posible que tengas que ajustar los permisos de la carpeta.",
"RemoveDownloadsAlert": "Las opciones de eliminación fueron trasladadas a las opciones del cliente de descarga individual en la tabla anterior.",
@@ -2032,5 +2032,9 @@
"DefaultNameCopiedImportList": "{name} - Copia",
"ReleaseProfile": "Perfil de lanzamiento",
"CountMissingMoviesFromLibrary": "{count} película(s) faltante(s) en la biblioteca",
"RemoveRootFolderMoviesMessageText": "¿Estás seguro que quieres eliminar la carpeta raíz '{path}'? Los archivos y carpetas no serán borrados del disco, y las películas en esta carpeta raíz no serán eliminadas de {appName}."
"RemoveRootFolderMoviesMessageText": "¿Estás seguro que quieres eliminar la carpeta raíz '{path}'? Los archivos y carpetas no serán borrados del disco, y las películas en esta carpeta raíz no serán eliminadas de {appName}.",
"NotificationsPushcutSettingsIncludePoster": "Incluir póster",
"NotificationsPushcutSettingsIncludePosterHelpText": "Incluir póster con notificación",
"NotificationsPushcutSettingsMetadataLinks": "Enlaces de metadatos",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Añade un enlace a los metadatos de las series cuando se envían notificaciones"
}

View File

@@ -154,7 +154,7 @@
"AuthenticationMethodHelpText": "Vaadi {appName}in käyttöön käyttäjätunnus ja salasana.",
"AuthForm": "Lomake (kirjautumissivu)",
"Automatic": "Automaattinen",
"UnmonitorDeletedMoviesHelpText": "{appName} lopettaa levyltä poistettujen elokuvien valvonan automaattisesti.",
"UnmonitorDeletedMoviesHelpText": "{appName} lopettaa levyltä poistettujen elokuvien valvonnan automaattisesti.",
"BackupRetentionHelpText": "Säilytysaikaa vanhemmat varmuuskopiot siivotaan automaattisesti.",
"Backups": "Varmuuskopiot",
"BindAddress": "Sidososoite",
@@ -2021,5 +2021,20 @@
"Keywords": "Avainsanat",
"CloneImportList": "Monista tuontilista",
"DefaultNameCopiedImportList": "{name} (kopio)",
"ReleaseProfile": "Julkaisuprofiili"
"ReleaseProfile": "Julkaisuprofiili",
"CinemaRelease": "Teatterijulkaisu",
"ShowPhysicalReleaseCalendarHelpText": "Näytä fyysiset julkaisut kalenterin tapahtumissa.",
"CountMissingMoviesFromLibrary": "Kirjastosta puuttuu {count} elokuva(a)",
"RemoveRootFolderMoviesMessageText": "Haluatko varmasti poistaa juurikansion \"{path}\"? Tiedostoja ja kansioita ei poisteta levyltä, eikä tämän juurikansion elokuvia poisteta {appName}ista.",
"ShowCinemaReleaseCalendarHelpText": "Näytä teatterijulkaisut kalenterin tapahtumissa.",
"ShowCinemaRelease": "Näytä teatterijulkaisu",
"ICalReleaseTypes": "Julkaisutyypit",
"ICalReleaseTypesMoviesHelpText": "Sisällytä iCal-syötteeseen vain tiettyjen julkaisutyyppien elokuvat. Jos ei määritetty käytetään kaikkia.",
"ShowDigitalReleaseCalendarHelpText": "Näytä digitaalijulkaisut kalenterin tapahtumissa.",
"ShowDigitalRelease": "Näytä digitaalijulkaisu",
"ShowPhysicalRelease": "Näytä fyysinen julkaisu",
"NotificationsPushcutSettingsIncludePoster": "Sisällytä juliste",
"NotificationsPushcutSettingsIncludePosterHelpText": "Näytä juliste ilmoituksessa.",
"NotificationsPushcutSettingsMetadataLinks": "Metatietolinkit",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Lisää lähetettäviin ilmoituksiin linkit median metatietoihin."
}

View File

@@ -170,7 +170,7 @@
"Week": "Semaine",
"Wanted": "Recherché",
"View": "Vues",
"UpdateSelected": "Mise à jour sélectionnée",
"UpdateSelected": "Mettre à jour la sélection",
"Updates": "Mises à jour",
"UpdateAll": "Tout mettre à jour",
"UnmappedFolders": "Dossiers non mappés",
@@ -668,7 +668,7 @@
"RemovedFromTaskQueue": "Supprimé de la file d'attente des tâches",
"RemoveCompletedDownloadsHelpText": "Supprimer les téléchargements importés de l'historique du client de téléchargement",
"Remove": "Retirer",
"ReleaseRejected": "Libération rejetée",
"ReleaseRejected": "Release rejetée",
"ReleaseDates": "Date de sortie",
"RegularExpressionsCanBeTested": "Les expressions régulières peuvent être testées [ici]({url}).",
"RefreshMovie": "Actualiser le film",
@@ -976,7 +976,7 @@
"RemotePathMappingCheckLocalWrongOSPath": "Le client de téléchargement {downloadClientName} met les téléchargements dans {path} mais il ne s'agit pas d'un chemin {osName} valide. Vérifiez les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckFilesGenericPermissions": "Le client de téléchargement {downloadClientName} met les téléchargements dans {path} mais {appName} 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 {downloadClientName} met les téléchargements dans {path} mais il ne s'agit pas d'un chemin {osName} valide. Vérifiez les paramètres de votre client de téléchargement.",
"BypassDelayIfHighestQualityHelpText": "Ignorer le délai lorsque la libération a la qualité activée la plus élevée dans le profil de qualité avec le protocole préféré",
"BypassDelayIfHighestQualityHelpText": "Ignorer le délai lorsque la release a la qualité activée la plus élevée dans le profil de qualité avec le protocole préféré",
"ClickToChangeReleaseGroup": "Cliquez pour changer de groupe de diffusion",
"AnnouncedMovieDescription": "Le film est annoncé",
"Filters": "Filtres",
@@ -1116,7 +1116,7 @@
"IMDbId": "Identifiant TMDb",
"DisabledForLocalAddresses": "Désactivée pour les adresses IP locales",
"BypassDelayIfAboveCustomFormatScore": "Ignorer si le score du format personnalisé est supérieur",
"BypassDelayIfAboveCustomFormatScoreHelpText": "Activer le contournement lorsque la libération a un score supérieur au score minimum configuré pour le format personnalisé",
"BypassDelayIfAboveCustomFormatScoreHelpText": "Activer le contournement lorsque la release a un score supérieur au score minimum configuré pour le format personnalisé",
"BypassDelayIfAboveCustomFormatScoreMinimumScore": "Score minimum pour le format personnalisé",
"AuthenticationRequired": "Authentification requise",
"AuthenticationRequiredHelpText": "Modifier les demandes pour lesquelles l'authentification est requise. Ne rien modifier si vous n'en comprenez pas les risques.",
@@ -1504,7 +1504,7 @@
"IgnoreDownloads": "Ignorer les téléchargements",
"IgnoreDownloadsHint": "Empêche {appName} de poursuivre le traitement de ces téléchargements",
"IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Si un torrent est bloqué par le hachage, il peut ne pas être correctement rejeté pendant le RSS/recherche pour certains indexeurs. L'activation de cette fonction permet de le rejeter après que le torrent a été saisi, mais avant qu'il ne soit envoyé au client.",
"RemoveQueueItemsRemovalMethodHelpTextWarning": "Supprimer du client de téléchargement\" supprimera les téléchargements et les fichiers du client de téléchargement.",
"RemoveQueueItemsRemovalMethodHelpTextWarning": "Supprimer du client de téléchargement\" supprimera les téléchargements et les fichiers du client de téléchargement.",
"DownloadClientAriaSettingsDirectoryHelpText": "Emplacement facultatif pour les téléchargements, laisser vide pour utiliser l'emplacement par défaut Aria2",
"RemoveFromDownloadClientHint": "Supprime le téléchargement et le(s) fichier(s) du client de téléchargement",
"AddAutoTagError": "Impossible d'ajouter un nouveau tag automatique, veuillez réessayer.",
@@ -1967,14 +1967,14 @@
"IndexerSettingsCookieHelpText": "Si votre site nécessite un cookie de connexion pour accéder au flux RSS, vous devrez le récupérer via un navigateur.",
"BlocklistedAt": "Mis sur liste noire le {date}",
"FailedAt": "Échoué le {date}",
"IndexerSettingsFailDownloads": "Échec des téléchargements",
"IndexerSettingsFailDownloads": "Échouer les téléchargements",
"FileSize": "Taille de fichier",
"DownloadClientItemErrorMessage": "{clientName} signale une erreur : {message}",
"GrabbedAt": "Capturé le {date}",
"IndexerSettingsFailDownloadsHelpText": "Lors du traitement des téléchargements terminés, {appName} traitera ces types de fichiers sélectionnés comme des téléchargements ayant échoué.",
"DownloadClientUTorrentProviderMessage": "uTorrent a un historique d'inclusion de cryptomineurs, de logiciels malveillants et de publicités. Nous vous recommandons fortement de choisir un autre client.",
"MyComputer": "Mon ordinateur",
"UpdatePath": "Chemin de mise à jour",
"UpdatePath": "Mettre à jour le chemin",
"ImportListsRadarrSettingsFullUrl": "URL complète",
"ImportListsRadarrSettingsRootFoldersHelpText": "Dossiers racine de l'instance source à partir de laquelle l'importation doit être effectuée",
"ImportListsRadarrSettingsTagsHelpText": "Tags de l'instance source à importer",
@@ -1982,5 +1982,59 @@
"EditMovieCollectionModalHeader": "Modifier - {title}",
"AutoTaggingSpecificationKeyword": "clavier",
"DefaultNameCopiedImportList": "{name} - Copier",
"ReleaseProfile": "Profil de version"
"ReleaseProfile": "Profil de version",
"ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Films recommandés par semaine",
"IndexerSettingsRemoveYearHelpText": "{appName} devrait-il retirer l'année du titre lors d'une recherche avec cet indexeur?",
"IndexerSettingsRequiredFlags": "Indicateurs requis",
"CloneImportList": "Cloner la liste d'importation",
"CountMissingMoviesFromLibrary": "{count} film(s) manquant(s) dans la bibliothèque",
"ImportListsTraktSettingsYearsMovieHelpText": "Filtrer les films par année ou par tranche d'années",
"IndexerFileListSettingsCategoriesHelpText": "Catégories a utiliser pour la recherche et les flux. Si elle n'est pas spécifiée, toutes les options sont utilisées.",
"IndexerSettingsRequiredFlagsHelpText": "Sélectionner les drapeaux d'indexeur qui devraient être obligatoires. Laisser blanc pour utiliser avec tous les drapeaux.",
"Keywords": "Mots clés",
"ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "Films les plus attendus",
"MovieFolderFormatHelpTextDeprecatedWarning": "Les jetons associés au propriétés de fichier du film sont obsolètes and ne seront plus supportés dans la prochaine mise à jour majeure.",
"NamingConfigMovieFolderFormatDeprecatedHealthCheckMessage": "Le format des dossiers de films ne peuvent pas contenir de jetons de fichiers obsolètes : {tokens}",
"NotificationsAppriseSettingsIncludePosterHelpText": "Inclure l'affiche dans les messages",
"ImportListsTraktSettingsCertificationMovieHelpText": "Filtrer les films par certification (NR,G,PG,PG-13,R,NC-17) (Séparé par une virgule)",
"ImportListsTraktSettingsLimitMovieHelpText": "Limiter le nombre de films à obtenir",
"ImportListsTraktSettingsPopularListTypePopularMovies": "Films populaires",
"ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Films recommandés par année",
"CinemaRelease": "Sorties cinéma",
"ICalReleaseTypes": "Types de versions",
"ICalReleaseTypesMoviesHelpText": "Inclure seulement les films avec un type de version spécifique dans le flux iCal. S'il n'est pas spécifié, toutes les options sont utilisées.",
"ImportListsRadarrSettingsFullUrlHelpText": "URL, incluant le port, de l'instance {appName} à importer (Radarr 3.0 or higher)",
"ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Films recommandés par mois",
"ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Films les plus écoutés par mois",
"ImportListsTraktSettingsPopularListTypeTrendingMovies": "Films tendance",
"ImportListsTraktSettingsRatingMovieHelpText": "Filtrer les films par plage de classement (0-100)",
"IndexerNewznabSettingsCategoriesHelpText": "List déroulante, au moins une catégorie doit être spécifié.",
"MetadataMediaBrowserDeprecated": "Les métadonnées de navigateur multimédia sont obsolètes. Leurs support sera retiré entièrement dans la version {version}.",
"MovieEditRootFolderHelpText": "Déplacer les films dans le même dossier racine peut être utilisé pour renommer les dossiers de films pour correspondre à un nouveau titre ou une convention de nom",
"ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Films les plus écoutés par semaine",
"ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Films les plus écoutés par année",
"ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Films les plus écoutés de tous les temps",
"IndexerSettingsBaseUrl": "URL de base",
"IndexerSettingsRemoveYear": "Retirer l'année des paramètres de recherche",
"ImportListsRadarrSettingsApiKeyHelpText": "Clé API de l'instance {appName} à importer (Radarr 3.0 or higher)",
"ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Films recommandés de tous les temps",
"ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Meilleurs films au box-office",
"NotificationsAppriseSettingsIncludePoster": "Inclure l'affiche",
"AutoTaggingSpecificationStudio": "Studio(s)",
"RemoveRootFolderMoviesMessageText": "Êtes-vous sûre que vous voulez supprimer le dossier racine '{path}'? Les fichiers et les dossiers ne seront pas supprimés du disque et les films dans ce dossier racine ne seront pas retiré de {appName}.",
"ShowCinemaReleaseCalendarHelpText": "Afficher les sorties cinéma dans le calendrier des événements",
"SelectMovieModalTitle": "{modalTitle} - Sélectionner le film",
"ShowCinemaRelease": "Afficher les sorties cinéma",
"ShowDigitalReleaseCalendarHelpText": "Afficher les sorties digitales dans le calendrier des événements",
"ShowPhysicalReleaseCalendarHelpText": "Afficher les sorties physiques dans le calendrier des événements",
"ReleaseSource": "Source de version",
"UpdateMoviePath": "Mettre à jour le chemin du film",
"ShowDigitalRelease": "Afficher les sorties digitales",
"ShowPhysicalRelease": "Afficher les sorties physiques",
"NotificationsPushcutSettingsIncludePoster": "Inclure l'affiche",
"NotificationsPushcutSettingsIncludePosterHelpText": "Inclure l'affiche avec les notifications",
"NotificationsPushcutSettingsMetadataLinks": "Lien de métadonnées",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Ajouter un lien vers les métadonnées de la série lors de l'envoi de notifications",
"ImportListsTraktSettingsGenresMovieHelpText": "Filtrer les films par genre Trakt (séparés par des virgules) Uniquement pour les listes populaires",
"ReleasePush": "Poussée de version"
}

View File

@@ -379,5 +379,7 @@
"IndexerSettingsCategories": "Kategorije",
"IndexerHDBitsSettingsCategories": "Kategorije",
"IndexerHDBitsSettingsCodecs": "Kodek",
"ReleaseProfile": "profil verzije"
"ReleaseProfile": "profil verzije",
"AddANewPath": "Dodaj novu putanju",
"AddCustomFilter": "Dodaj proizvoljan filter"
}

View File

@@ -1503,5 +1503,7 @@
"MyComputer": "A számítógépem",
"EditMovieCollectionModalHeader": "Szerkesztés {title}",
"DefaultNameCopiedImportList": "{name} - Másolat",
"ReleaseProfile": "Release profil"
"ReleaseProfile": "Release profil",
"AutoTaggingSpecificationKeyword": "Kulcsszavak",
"AutoTaggingSpecificationStudio": "Stúdió(k)"
}

View File

@@ -182,5 +182,14 @@
"CustomFormatsSpecificationLanguage": "Bahasa",
"IndexerHDBitsSettingsCategories": "Kategori",
"IndexerHDBitsSettingsCodecs": "Codec",
"IndexerSettingsCategories": "Kategori"
"IndexerSettingsCategories": "Kategori",
"AddConditionError": "tidak dapat menambahkan persyaratan baru, coba lagi..",
"AddAutoTagError": "tidak dapat menambahkan label otomatis, coba lagi..",
"AddANewPath": "tambah path baru",
"AddCustomFilter": "tambah filter khusus",
"AddAutoTag": "tambah label otomatis",
"AddCondition": "tambah persyaratan",
"AddConditionImplementation": "tambah persyaratan {implementationName}",
"AddConnection": "tambah koneksi",
"AddConnectionImplementation": "tambah koneksi - {implementationName}"
}

View File

@@ -1541,5 +1541,9 @@
"EditMovieCollectionModalHeader": "Modifica - {title}",
"IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Se un torrent è bloccato tramite hash, potrebbe non essere correttamente rifiutato durante luso di RSS/Ricerca con alcuni indexer. Abilitando questa opzione, il torrent verrà rifiutato dopo essere stato acquisito, ma prima di essere inviato al client.",
"DefaultNameCopiedImportList": "{name} - Copia",
"ReleaseProfile": "profilo release"
"ReleaseProfile": "profilo release",
"BlocklistAndSearchHint": "Inizia una ricerca per sostituzioni dopo l'aggiunta alla lista dei blocchi",
"BlocklistMultipleOnlyHint": "Aggiungi alla blocklist senza ricerca di sostituti",
"BlocklistOnly": "Solo blocklist",
"AutomaticUpdatesDisabledDocker": "Gli aggiornamenti automatici non sono supportati direttamente quando si utilizza il meccanismo di aggiornamento Docker. Sarà necessario aggiornare l'immagine del contenitore al di fuori di {appName} o utilizzare uno script"
}

View File

@@ -1931,5 +1931,6 @@
"FileSize": "파일 크기",
"IndexerSettingsFailDownloadsHelpText": "완료된 다운로드를 처리하는 동안 {appName}는 선택된 파일 유형을 실패한 다운로드로 처리합니다.",
"ImportListsRadarrSettingsFullUrl": "전체 URL",
"DefaultNameCopiedImportList": "{name} - 복사"
"DefaultNameCopiedImportList": "{name} - 복사",
"NotificationsPushcutSettingsMetadataLinksHelpText": "알림을 보낼 때 시리즈 메타데이터에 대한 링크를 추가"
}

View File

@@ -2032,5 +2032,9 @@
"DefaultNameCopiedImportList": "{name} - Cópia",
"ReleaseProfile": "Perfil de Lançamento",
"CountMissingMoviesFromLibrary": "{count} filme(s) faltando na biblioteca",
"RemoveRootFolderMoviesMessageText": "Tem certeza de que deseja remover a pasta raiz '{path}'? Arquivos e pastas não serão excluídos do disco, e os filmes nesta pasta raiz não serão removidos de {appName} ."
"RemoveRootFolderMoviesMessageText": "Tem certeza de que deseja remover a pasta raiz '{path}'? Arquivos e pastas não serão excluídos do disco, e os filmes nesta pasta raiz não serão removidos de {appName} .",
"NotificationsPushcutSettingsIncludePoster": "Incluir Pôster",
"NotificationsPushcutSettingsIncludePosterHelpText": "Incluir pôster com notificação",
"NotificationsPushcutSettingsMetadataLinks": "Links de metadados",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Adicionar links para os metadados da série ao enviar notificações"
}

View File

@@ -1173,5 +1173,7 @@
"IndexerHDBitsSettingsCategories": "Categorii",
"IndexerHDBitsSettingsMediums": "Mediu",
"IndexerSettingsCategories": "Categorii",
"DefaultNameCopiedImportList": "{name} - Copie"
"DefaultNameCopiedImportList": "{name} - Copie",
"Warning": "Avertisment",
"YesterdayAt": "Ieri la {time}"
}

View File

@@ -416,7 +416,7 @@
"PrioritySettings": "Приоритет: {priority}",
"Priority": "Приоритет",
"PreviewRenameHelpText": "Совет: для предварительного просмотра переименования ... выберите \"Отмена\", затем щелкните название любого фильма и используйте",
"PreviewRename": "Предпросмотр\nпереименования",
"PreviewRename": ереименовать предпросмотр",
"Presets": "Пресеты",
"PreferUsenet": "Предпочитать Usenet",
"PreferTorrent": "Предпочитать торрент",
@@ -1290,7 +1290,7 @@
"DownloadClientNzbgetValidationKeepHistoryOverMax": "Для параметра NzbGet KeepHistory должно быть меньше 25000",
"DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Загружать первые и последние части сначала (qBittorrent 4.1.0+)",
"DownloadClientRTorrentSettingsDirectoryHelpText": "Необязательное место для сохранения загрузок, оставьте поле пустым, чтобы использовать расположение rTorrent по умолчанию",
"DownloadClientQbittorrentTorrentStateStalled": "Загрузка останавливается без подключения",
"DownloadClientQbittorrentTorrentStateStalled": "Загрузка не активна, т.к. нет соединений",
"DownloadClientSabnzbdValidationUnknownVersion": "Неизвестная версия: {rawVersion}",
"DownloadClientSettingsInitialState": "Начальное состояние",
"DownloadClientValidationUnableToConnect": "Невозможно подключиться к {clientName}",
@@ -2031,5 +2031,10 @@
"CloneImportList": "Копировать список импорта",
"DefaultNameCopiedImportList": "{name} - Копировать",
"ReleaseProfile": "Профиль релиза",
"CountMissingMoviesFromLibrary": "{count} отсутствующих фильмов в библиотеке"
"CountMissingMoviesFromLibrary": "{count} отсутствующих фильмов в библиотеке",
"RemoveRootFolderMoviesMessageText": "Вы уверены, что хотите удалить корневой каталог '{path}'? Файлы и папки не будут удалены с диска, а фильмы в этом корневом каталоге не будут удалены из {appName}.",
"NotificationsPushcutSettingsIncludePoster": "Добавить постер",
"NotificationsPushcutSettingsIncludePosterHelpText": "Добавляет постер в уведомление",
"NotificationsPushcutSettingsMetadataLinks": "Ссылки на метаданные",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Добавляет ссылки на метаданные сериала при отправке уведомлений"
}

View File

@@ -1082,5 +1082,6 @@
"ImportListsTraktSettingsCertification": "การรับรอง",
"ImportListsTraktSettingsGenres": "ประเภท",
"ImportListsTraktSettingsRating": "การให้คะแนน",
"IndexerHDBitsSettingsMediums": "ปานกลาง"
"IndexerHDBitsSettingsMediums": "ปานกลาง",
"AddANewPath": "เพิ่มเส้นทางใหม่"
}

View File

@@ -1782,7 +1782,7 @@
"DeleteMovieFolderMovieCount": "{size} boyutunda {movieFileCount} film dosyası",
"NotificationsPlexSettingsServer": "Sunucu",
"NotificationsPlexSettingsServerHelpText": "Kimlik doğrulamasından sonra plex.tv hesabından sunucuyu seçin",
"UnableToImportAutomatically": "Otomatikman İçe Aktarılamıyor",
"UnableToImportAutomatically": "Otomatik Olarak İçe Aktarılamıyor",
"ShowTags": "Etiketleri göster",
"ShowTagsHelpText": "Etiketleri posterin altında göster",
"Any": "Herhangi",
@@ -2031,5 +2031,10 @@
"CloneImportList": "İçe Aktarma Listesini Klonla",
"DefaultNameCopiedImportList": "{name} - Kopyala",
"ReleaseProfile": "Sürüm Profili",
"CountMissingMoviesFromLibrary": "{count} kitaplıkta eksik film"
"CountMissingMoviesFromLibrary": "{count} kitaplıkta eksik film",
"RemoveRootFolderMoviesMessageText": "'{path}' kök klasörünü kaldırmak istediğinizden emin misiniz? Dosya ve klasörler diskten silinmez ve bu kök klasördeki filmler {appName} 'dan kaldırılmaz.",
"NotificationsPushcutSettingsIncludePosterHelpText": "Bildirim içeriğine poster ekleyin",
"NotificationsPushcutSettingsMetadataLinks": "Meta Veri Bağlantıları",
"NotificationsPushcutSettingsIncludePoster": "Poster'i ekle",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Bildirim gönderirken dizi meta verilerine bağlantılar ekleyin"
}

View File

@@ -2008,5 +2008,10 @@
"EditMovieCollectionModalHeader": "Редагувати - {title}",
"NotificationsAppriseSettingsIncludePoster": "Включити постер",
"DefaultNameCopiedImportList": "{name} - Копіювати",
"ReleaseProfile": "Профіль релізу"
"ReleaseProfile": "Профіль релізу",
"DownloadClientItemErrorMessage": "{clientName} повертає помилку: {message}",
"NotificationsPushcutSettingsIncludePoster": "Включити постер",
"NotificationsPushcutSettingsIncludePosterHelpText": "Включити постер з сповіщенням",
"NotificationsPushcutSettingsMetadataLinks": "Посилання на метадані",
"NotificationsPushcutSettingsMetadataLinksHelpText": "Додати посилання на метадані серіалу при надсиланні сповіщень"
}

View File

@@ -1878,7 +1878,7 @@
"CustomFormatsSpecificationMinimumSizeHelpText": "必须大于该尺寸才会发布",
"CustomFormatsSpecificationMinimumYear": "最小年份",
"CustomFormatsSpecificationResolution": "分辨率",
"CustomFormatsSpecificationSource": "代码",
"CustomFormatsSpecificationSource": "",
"AutoTaggingSpecificationGenre": "类型",
"AutoTaggingSpecificationMaximumYear": "最大年份",
"Mixed": "混合",
@@ -1986,5 +1986,6 @@
"MyComputer": "我的电脑",
"EditMovieCollectionModalHeader": "编辑 - {title}",
"DefaultNameCopiedImportList": "{name} - 复制",
"ReleaseProfile": "发行配置文件"
"ReleaseProfile": "发行配置文件",
"NotificationsPushcutSettingsMetadataLinks": "元数据链接"
}

View File

@@ -210,7 +210,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
if (videoFormat == "mpeg4" || videoFormat.Contains("msmpeg4"))
{
if (videoCodecID == "XVID")
if (videoCodecID.ToUpperInvariant() == "XVID")
{
return "XviD";
}

View File

@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Runtime.Serialization;
namespace NzbDrone.Core.MediaFiles.MovieImport
{
@@ -19,10 +18,5 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
: base(message, innerException)
{
}
protected RecycleBinException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

View File

@@ -1,6 +1,5 @@
using System;
using System;
using System.IO;
using System.Runtime.Serialization;
namespace NzbDrone.Core.MediaFiles.MovieImport
{
@@ -19,10 +18,5 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
: base(message, innerException)
{
}
protected RootFolderNotFoundException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

View File

@@ -17,7 +17,7 @@ namespace NzbDrone.Core.MediaFiles
{
public interface IRenameMovieFileService
{
List<RenameMovieFilePreview> GetRenamePreviews(int movieId);
List<RenameMovieFilePreview> GetRenamePreviews(List<int> movieIds);
}
public class RenameMovieFileService : IRenameMovieFileService,
@@ -49,12 +49,18 @@ namespace NzbDrone.Core.MediaFiles
_logger = logger;
}
public List<RenameMovieFilePreview> GetRenamePreviews(int movieId)
public List<RenameMovieFilePreview> GetRenamePreviews(List<int> movieIds)
{
var movie = _movieService.GetMovie(movieId);
var file = _mediaFileService.GetFilesByMovie(movieId);
var movies = _movieService.GetMovies(movieIds);
var movieFiles = _mediaFileService.GetFilesByMovies(movieIds).ToLookup(f => f.MovieId);
return GetPreviews(movie, file).OrderByDescending(m => m.MovieId).ToList(); // TODO: Would really like to not have these be lists
return movies.SelectMany(movie =>
{
var files = movieFiles[movie.Id].ToList();
return GetPreviews(movie, files);
})
.ToList();
}
private IEnumerable<RenameMovieFilePreview> GetPreviews(Movie movie, List<MovieFile> files)

View File

@@ -0,0 +1,16 @@
namespace NzbDrone.Core.Notifications
{
public class NotificationMetadataLink
{
public MetadataLinkType? Type { get; set; }
public string Label { get; set; }
public string Link { get; set; }
public NotificationMetadataLink(MetadataLinkType? type, string label, string link)
{
Type = type;
Label = label;
Link = link;
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Movies;
namespace NzbDrone.Core.Notifications;
public static class NotificationMetadataLinkGenerator
{
public static List<NotificationMetadataLink> GenerateLinks(Movie movie, IEnumerable<int> metadataLinks)
{
var links = new List<NotificationMetadataLink>();
if (movie == null)
{
return links;
}
foreach (var type in metadataLinks)
{
var linkType = (MetadataLinkType)type;
if (linkType == MetadataLinkType.Imdb && movie.ImdbId.IsNotNullOrWhiteSpace())
{
links.Add(new NotificationMetadataLink(MetadataLinkType.Imdb, "IMDb", $"https://www.imdb.com/title/{movie.ImdbId}"));
}
if (linkType == MetadataLinkType.Tmdb && movie.TmdbId > 0)
{
links.Add(new NotificationMetadataLink(MetadataLinkType.Tmdb, "TMDb", $"https://www.themoviedb.org/movie/{movie.TmdbId}"));
}
}
return links;
}
}

View File

@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Linq;
using FluentValidation.Results;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Movies;
namespace NzbDrone.Core.Notifications.Pushcut
@@ -30,47 +31,57 @@ namespace NzbDrone.Core.Notifications.Pushcut
public override void OnGrab(GrabMessage grabMessage)
{
_proxy.SendNotification(MOVIE_GRABBED_TITLE, grabMessage?.Message, Settings);
_proxy.SendNotification(MOVIE_GRABBED_TITLE, grabMessage?.Message, GetPosterUrl(grabMessage.Movie), GetLinks(grabMessage.Movie), Settings);
}
public override void OnDownload(DownloadMessage downloadMessage)
{
_proxy.SendNotification(downloadMessage.OldMovieFiles.Any() ? MOVIE_UPGRADED_TITLE : MOVIE_DOWNLOADED_TITLE, downloadMessage.Message, Settings);
_proxy.SendNotification(downloadMessage.OldMovieFiles.Any() ? MOVIE_UPGRADED_TITLE : MOVIE_DOWNLOADED_TITLE, downloadMessage.Message, GetPosterUrl(downloadMessage.Movie), GetLinks(downloadMessage.Movie), Settings);
}
public override void OnMovieAdded(Movie movie)
{
_proxy.SendNotification(MOVIE_ADDED_TITLE, $"{movie.Title} added to library", Settings);
_proxy.SendNotification(MOVIE_ADDED_TITLE, $"{movie.Title} added to library", GetPosterUrl(movie), GetLinks(movie), Settings);
}
public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage)
{
_proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings);
_proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, GetPosterUrl(deleteMessage.Movie), GetLinks(deleteMessage.Movie), Settings);
}
public override void OnMovieDelete(MovieDeleteMessage deleteMessage)
{
_proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings);
_proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, GetPosterUrl(deleteMessage.Movie), GetLinks(deleteMessage.Movie), Settings);
}
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
{
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings);
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, null, new List<NotificationMetadataLink>(), Settings);
}
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheck.Message}", Settings);
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheck.Message}", null, new List<NotificationMetadataLink>(), Settings);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{
_proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, Settings);
_proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, null, new List<NotificationMetadataLink>(), Settings);
}
public override void OnManualInteractionRequired(ManualInteractionRequiredMessage manualInteractionRequiredMessage)
{
_proxy.SendNotification(MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED, manualInteractionRequiredMessage.Message, Settings);
_proxy.SendNotification(MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED, manualInteractionRequiredMessage.Message, null, new List<NotificationMetadataLink>(), Settings);
}
private string GetPosterUrl(Movie movie)
{
return movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.RemoteUrl;
}
private List<NotificationMetadataLink> GetLinks(Movie movie)
{
return NotificationMetadataLinkGenerator.GenerateLinks(movie, Settings.MetadataLinks);
}
}
}

View File

@@ -1,3 +1,5 @@
using System.Collections.Generic;
namespace NzbDrone.Core.Notifications.Pushcut
{
public class PushcutPayload
@@ -5,5 +7,13 @@ namespace NzbDrone.Core.Notifications.Pushcut
public string Title { get; set; }
public string Text { get; set; }
public bool? IsTimeSensitive { get; set; }
public string Image { get; set; }
public List<PushcutAction> Actions;
}
public class PushcutAction
{
public string Name { get; set; }
public string Url { get; set; }
}
}

View File

@@ -12,7 +12,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
{
public interface IPushcutProxy
{
void SendNotification(string title, string message, PushcutSettings settings);
void SendNotification(string title, string message, string posterUrl, List<NotificationMetadataLink> links, PushcutSettings settings);
ValidationFailure Test(PushcutSettings settings);
}
@@ -29,20 +29,37 @@ namespace NzbDrone.Core.Notifications.Pushcut
_logger = logger;
}
public void SendNotification(string title, string message, PushcutSettings settings)
public void SendNotification(string title, string message, string posterUrl, List<NotificationMetadataLink> links, PushcutSettings settings)
{
if (settings == null)
{
return;
}
var request = new HttpRequestBuilder("https://api.pushcut.io/v1/notifications/{notificationName}")
.SetSegment("notificationName", settings?.NotificationName)
.SetHeader("API-Key", settings?.ApiKey)
.Accept(HttpAccept.Json)
.Build();
var payload = new PushcutPayload
{
Title = title,
Text = message,
IsTimeSensitive = settings?.TimeSensitive
IsTimeSensitive = settings?.TimeSensitive,
Image = settings.IncludePoster ? posterUrl : null,
Actions = new List<PushcutAction>()
};
foreach (var link in links)
{
payload.Actions.Add(new PushcutAction
{
Name = link.Label,
Url = link.Link
});
}
request.Method = HttpMethod.Post;
request.Headers.ContentType = "application/json";
request.SetContent(payload.ToJson());
@@ -64,7 +81,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
{
const string title = "Radarr Test Title";
const string message = "Success! You have properly configured your Pushcut notification settings.";
SendNotification(title, message, settings);
SendNotification(title, message, null, new List<NotificationMetadataLink>(), settings);
}
catch (PushcutException pushcutException) when (pushcutException.InnerException is HttpException httpException)
{

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
@@ -15,7 +16,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
public class PushcutSettings : NotificationSettingsBase<PushcutSettings>
{
private static readonly PushcutSettingsValidator Validator = new ();
private static readonly PushcutSettingsValidator Validator = new PushcutSettingsValidator();
[FieldDefinition(0, Label = "NotificationsPushcutSettingsNotificationName", Type = FieldType.Textbox, HelpText = "NotificationsPushcutSettingsNotificationNameHelpText")]
public string NotificationName { get; set; }
@@ -26,6 +27,12 @@ namespace NzbDrone.Core.Notifications.Pushcut
[FieldDefinition(2, Label = "NotificationsPushcutSettingsTimeSensitive", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsTimeSensitiveHelpText")]
public bool TimeSensitive { get; set; }
[FieldDefinition(3, Label = "NotificationsPushcutSettingsIncludePoster", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsIncludePosterHelpText")]
public bool IncludePoster { get; set; }
[FieldDefinition(4, Label = "NotificationsPushcutSettingsMetadataLinks", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsPushcutSettingsMetadataLinksHelpText")]
public IEnumerable<int> MetadataLinks { get; set; } = new List<int>();
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@@ -174,29 +174,13 @@ namespace NzbDrone.Core.Organizer
namingConfig = _namingConfigService.GetConfig();
}
var pattern = namingConfig.MovieFolderFormat;
var multipleTokens = TitleRegex.Matches(pattern).Count > 1;
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
AddMovieTokens(tokenHandlers, movie);
AddReleaseDateTokens(tokenHandlers, movie.Year);
AddIdTokens(tokenHandlers, movie);
var movieFile = movie.MovieFile;
if (movie.MovieFile != null)
{
AddQualityTokens(tokenHandlers, movie, movieFile);
AddMediaInfoTokens(tokenHandlers, movieFile);
AddMovieFileTokens(tokenHandlers, movieFile, multipleTokens);
AddEditionTagsTokens(tokenHandlers, movieFile);
}
else
{
AddMovieFileTokens(tokenHandlers, new MovieFile { SceneName = $"{movie.Title} {movie.Year}", RelativePath = $"{movie.Title} {movie.Year}" }, multipleTokens);
}
var pattern = namingConfig.MovieFolderFormat;
var splitPatterns = pattern.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries);
var components = new List<string>();

View File

@@ -27,6 +27,7 @@ namespace NzbDrone.Core.Organizer
{
ruleBuilder.SetValidator(new NotEmptyValidator(null));
ruleBuilder.SetValidator(new IllegalCharactersValidator());
ruleBuilder.SetValidator(new IllegalMovieFolderTokensValidator());
return ruleBuilder.SetValidator(new ValidMovieFolderFormatValidator());
}
@@ -34,7 +35,7 @@ namespace NzbDrone.Core.Organizer
public class ValidMovieFormatValidator : PropertyValidator
{
protected override string GetDefaultMessageTemplate() => "Must contain movie title and release year OR Original Title";
protected override string GetDefaultMessageTemplate() => "Must contain either movie title and release year OR Original Title/Filename";
protected override bool IsValid(PropertyValidatorContext context)
{
@@ -43,7 +44,7 @@ namespace NzbDrone.Core.Organizer
return false;
}
return (FileNameBuilder.MovieTitleRegex.IsMatch(value) && FileNameBuilder.ReleaseYearRegex.IsMatch(value)) ||
return (FileNameBuilder.MovieTitleRegex.IsMatch(value) && FileNameBuilder.ReleaseYearRegex.IsMatch(value) && !FileNameValidation.OriginalTokenRegex.IsMatch(value)) ||
FileNameValidation.OriginalTokenRegex.IsMatch(value);
}
}
@@ -59,9 +60,31 @@ namespace NzbDrone.Core.Organizer
return false;
}
// TODO: Deprecate OriginalTokenRegex use for Movie Folder Format
return FileNameBuilder.MovieTitleRegex.IsMatch(value) ||
FileNameValidation.OriginalTokenRegex.IsMatch(value);
return FileNameBuilder.MovieTitleRegex.IsMatch(value);
}
}
public class IllegalMovieFolderTokensValidator : PropertyValidator
{
protected override string GetDefaultMessageTemplate() => "Must not contain deprecated tokens derived from file properties: {tokens}";
protected override bool IsValid(PropertyValidatorContext context)
{
if (context.PropertyValue is not string value)
{
return false;
}
var match = FileNameValidation.DeprecatedMovieFolderTokensRegex.Matches(value);
if (match.Any())
{
context.MessageFormatter.AppendArgument("tokens", string.Join(", ", match.Select(c => c.Value).ToArray()));
return false;
}
return true;
}
}

View File

@@ -65,7 +65,8 @@ namespace NzbDrone.Core.Parser
new IsoLanguage("tl", "", "tgl", "Tagalog", Language.Tagalog),
new IsoLanguage("ur", "", "urd", "Urdu", Language.Urdu),
new IsoLanguage("rm", "", "roh", "Romansh", Language.Romansh),
new IsoLanguage("mn", "", "mon", "Mongolian", Language.Mongolian)
new IsoLanguage("mn", "", "mon", "Mongolian", Language.Mongolian),
new IsoLanguage("ka", "", "kat", "Georgian", Language.Georgian)
};
private static readonly Dictionary<string, Language> AlternateIsoCodeMappings = new ()

View File

@@ -40,6 +40,7 @@ namespace NzbDrone.Core.Parser
(?<urdu>\burdu\b)|
(?<romansh>\b(?:romansh|rumantsch|romansch)\b)|
(?<mongolian>\b(?:mongolian|khalkha)\b)|
(?<georgian>\b(?:georgian|geo|ka|kat)\b)|
(?<original>\b(?:orig|original)\b)",
RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
@@ -438,6 +439,11 @@ namespace NzbDrone.Core.Parser
languages.Add(Language.Mongolian);
}
if (match.Groups["georgian"].Success)
{
languages.Add(Language.Georgian);
}
if (match.Groups["original"].Success)
{
languages.Add(Language.Original);

View File

@@ -19,7 +19,7 @@ namespace NzbDrone.Core.Parser
(?<webdl>WEB[-_. ]?DL(?:mux)?|AmazonHD|AmazonSD|iTunesHD|MaxdomeHD|NetflixU?HD|WebHD|HBOMaxHD|DisneyHD|[. ]WEB[. ](?:[xh][ .]?26[45]|AVC|HEVC|DDP?5[. ]1)|[. ](?-i:WEB)$|(?:\d{3,4}0p)[-. ](?:Hybrid[-_. ]?)?WEB[-. ]|[-. ]WEB[-. ]\d{3,4}0p|\b\s\/\sWEB\s\/\s\b|(?:AMZN|NF|DP)[. -]WEB[. -](?!Rip))|
(?<webrip>WebRip|Web-Rip|WEBMux)|
(?<hdtv>HDTV)|
(?<bdrip>BDRip|BDLight)|
(?<bdrip>BDRip|BDLight|HD[-_. ]?DVDRip|UHDBDRip)|
(?<brrip>BRRip)|
(?<dvdr>\d?x?M?DVD-?[R59])|
(?<dvd>DVD(?!-R)|DVDRip|xvidvd)|

View File

@@ -260,7 +260,7 @@ namespace NzbDrone.Core.Profiles.Qualities
Name = name,
Cutoff = profileCutoff,
Items = items,
Language = Language.English,
Language = Language.Original,
MinFormatScore = 0,
CutoffFormatScore = 0,
MinUpgradeFormatScore = 1,

View File

@@ -1,32 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.151" />
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Diacritical.Net" Version="1.0.4" />
<PackageReference Include="Equ" Version="2.3.0" />
<PackageReference Include="MailKit" Version="4.8.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.35" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.1.7" />
<PackageReference Include="Npgsql" Version="7.0.10" />
<PackageReference Include="Polly" Version="8.5.2" />
<PackageReference Include="MailKit" Version="4.13.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.17" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.1" />
<PackageReference Include="Npgsql" Version="9.0.3" />
<PackageReference Include="Polly" Version="8.6.0" />
<PackageReference Include="Servarr.FFMpegCore" Version="4.7.0-26" />
<PackageReference Include="Servarr.FFprobe" Version="5.1.4.112" />
<PackageReference Include="System.Memory" Version="4.6.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Servarr.FluentMigrator.Runner" Version="3.3.2.9" />
<PackageReference Include="Servarr.FluentMigrator.Runner.SQLite" Version="3.3.2.9" />
<PackageReference Include="Servarr.FluentMigrator.Runner.Postgres" Version="3.3.2.9" />
<PackageReference Include="FluentValidation" Version="9.5.4" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.9" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.4.0" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="MonoTorrent" Version="2.0.7" />
<PackageReference Include="System.Text.Json" Version="6.0.10" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\Radarr.Common.csproj" />

View File

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

View File

@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.2" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="8.1.4" />
<PackageReference Include="DryIoc.dll" Version="5.4.3" />
<PackageReference Include="DryIoc.Microsoft.DependencyInjection" Version="6.2.0" />
</ItemGroup>

View File

@@ -52,7 +52,7 @@ namespace NzbDrone.Host
b.ClearProviders();
b.SetMinimumLevel(LogLevel.Trace);
b.AddFilter("Microsoft.AspNetCore", LogLevel.Warning);
b.AddFilter("Radarr.Http.Authentication", LogLevel.Information);
b.AddFilter("Radarr.Http.Authentication.ApiKeyAuthenticationHandler", LogLevel.Information);
b.AddFilter("Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager", LogLevel.Error);
b.AddNLog();
});

View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.35" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.17" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Test.Common\Radarr.Test.Common.csproj" />

View File

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

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<!--
The netstandard version here doesn't work in net framework

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