1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-17 21:26:22 -04:00

Compare commits

...

25 Commits

Author SHA1 Message Date
ta264
6683c88bb9 Remove mono reference 2022-05-08 06:34:08 +01:00
Qstick
5824ba963b Fixed: Correct User-Agent api logging 2022-05-06 08:25:34 -05:00
Qstick
7f2d5d8d10 Delete nan.json 2022-05-01 22:30:00 -05:00
Qstick
81bffe243a Delete zh_Hans.json 2022-05-01 22:29:50 -05:00
Weblate
2d6fde282a Translated using Weblate (Chinese (Simplified)) [skip ci]
Currently translated at 28.6% (320 of 1117 strings)

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

Currently translated at 28.6% (320 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

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

Currently translated at 4.6% (52 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Dutch) [skip ci]

Currently translated at 97.2% (1086 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 19.1% (214 of 1117 strings)

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

Currently translated at 4.5% (51 of 1117 strings)

Translated using Weblate (Dutch) [skip ci]

Currently translated at 95.9% (1072 of 1117 strings)

Update translation files  [skip ci]

Updated by "Remove blank strings" hook in Weblate.

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

Currently translated at 3.5% (40 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

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

Currently translated at 2.0% (23 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 99.5% (1112 of 1117 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 97.9% (1094 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 19.0% (213 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 19.0% (213 of 1117 strings)

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

Currently translated at 1.1% (13 of 1117 strings)

Translated using Weblate (Arabic) [skip ci]

Currently translated at 93.9% (1049 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

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

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Thai) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Bulgarian) [skip ci]

Currently translated at 91.3% (1020 of 1117 strings)

Translated using Weblate (Hindi) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Romanian) [skip ci]

Currently translated at 93.0% (1039 of 1117 strings)

Translated using Weblate (Vietnamese) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Turkish) [skip ci]

Currently translated at 93.2% (1042 of 1117 strings)

Translated using Weblate (Swedish) [skip ci]

Currently translated at 93.8% (1048 of 1117 strings)

Translated using Weblate (Russian) [skip ci]

Currently translated at 98.8% (1104 of 1117 strings)

Translated using Weblate (Portuguese) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Polish) [skip ci]

Currently translated at 93.3% (1043 of 1117 strings)

Translated using Weblate (Dutch) [skip ci]

Currently translated at 95.7% (1070 of 1117 strings)

Translated using Weblate (Korean) [skip ci]

Currently translated at 22.2% (248 of 1117 strings)

Translated using Weblate (Japanese) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Icelandic) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Hebrew) [skip ci]

Currently translated at 93.4% (1044 of 1117 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1117 of 1117 strings)

Translated using Weblate (Greek) [skip ci]

Currently translated at 93.3% (1043 of 1117 strings)

Translated using Weblate (Danish) [skip ci]

Currently translated at 93.1% (1041 of 1117 strings)

Translated using Weblate (Czech) [skip ci]

Currently translated at 94.1% (1052 of 1117 strings)

Translated using Weblate (Italian) [skip ci]

Currently translated at 96.5% (1078 of 1117 strings)

Translated using Weblate (French) [skip ci]

Currently translated at 97.9% (1094 of 1117 strings)

Translated using Weblate (German) [skip ci]

Currently translated at 99.8% (1115 of 1117 strings)

Translated using Weblate (German) [skip ci]

Currently translated at 99.8% (1115 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 15.7% (176 of 1117 strings)

Translated using Weblate (Ukrainian) [skip ci]

Currently translated at 15.7% (176 of 1117 strings)

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

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

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

View File

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

View File

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

View File

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

View File

@@ -127,21 +127,21 @@ function InteractiveSearchContent(props) {
{
!isFetching && !!error &&
<div>
<div className={styles.blankpad}>
{translate('UnableToLoadResultsIntSearch')}
</div>
}
{
!isFetching && isPopulated && !totalReleasesCount &&
<div>
<div className={styles.blankpad}>
{translate('NoResultsFound')}
</div>
}
{
!!totalReleasesCount && isPopulated && !items.length &&
<div>
<div className={styles.blankpad}>
{translate('AllResultsHiddenFilter')}
</div>
}
@@ -159,7 +159,7 @@ function InteractiveSearchContent(props) {
items.map((item) => {
return (
<InteractiveSearchRowConnector
key={item.guid}
key={`${item.indexerId}-${item.guid}`}
{...item}
searchPayload={searchPayload}
longDateFormat={longDateFormat}

View File

@@ -116,10 +116,11 @@ class NamingModal extends Component {
const movieTokens = [
{ token: '{Movie Title}', example: 'Movie\'s Title' },
{ token: '{Movie Title:DE}', example: 'Filetitle' },
{ token: '{Movie Title:DE}', example: 'Titel des Films' },
{ token: '{Movie CleanTitle}', example: 'Movies Title' },
{ token: '{Movie TitleThe}', example: 'Movie\'s Title, The' },
{ token: '{Movie OriginalTitle}', example: 'Τίτλος ταινίας' },
{ token: '{Movie CleanOriginalTitle}', example: 'Τίτλος ταινίας' },
{ token: '{Movie TitleFirstCharacter}', example: 'M' },
{ token: '{Movie Collection}', example: 'The Movie Collection' },
{ token: '{Movie Certification}', example: 'R' },

View File

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

View File

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

View File

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

View File

@@ -320,7 +320,6 @@ namespace NzbDrone.Common.Processes
processInfo = new ProcessInfo();
processInfo.Id = process.Id;
processInfo.Name = process.ProcessName;
processInfo.StartPath = GetExeFileName(process);
if (process.Id != GetCurrentProcessId() && process.HasExited)
{
@@ -335,16 +334,6 @@ namespace NzbDrone.Common.Processes
return processInfo;
}
private static string GetExeFileName(Process process)
{
if (process.MainModule.FileName != "mono.exe")
{
return process.MainModule.FileName;
}
return process.Modules.Cast<ProcessModule>().FirstOrDefault(module => module.ModuleName.ToLower().EndsWith(".exe")).FileName;
}
private List<Process> GetProcessesByName(string name)
{
var processes = Process.GetProcessesByName(name).ToList();

View File

@@ -20,7 +20,6 @@
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="EnsureThat\Resources\ExceptionMessages.Designer.cs">

View File

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

View File

@@ -27,6 +27,11 @@ namespace NzbDrone.Core.Test.Datastore
return new WhereBuilderPostgres(filter, true, 0);
}
private WhereBuilderPostgres WhereMeta(Expression<Func<MovieMetadata, bool>> filter)
{
return new WhereBuilderPostgres(filter, true, 0);
}
[Test]
public void postgres_where_equal_const()
{
@@ -86,36 +91,36 @@ namespace NzbDrone.Core.Test.Datastore
[Test]
public void postgres_where_string_is_null()
{
_subject = Where(x => x.CleanTitle == null);
_subject = WhereMeta(x => x.CleanTitle == null);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
}
[Test]
public void postgres_where_string_is_null_value()
{
string cleanTitle = null;
_subject = Where(x => x.CleanTitle == cleanTitle);
_subject = WhereMeta(x => x.CleanTitle == cleanTitle);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
}
[Test]
public void postgres_where_equal_null_property()
{
var movie = new Movie { CleanTitle = null };
_subject = Where(x => x.CleanTitle == movie.CleanTitle);
var movie = new MovieMetadata { CleanTitle = null };
_subject = WhereMeta(x => x.CleanTitle == movie.CleanTitle);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
}
[Test]
public void postgres_where_column_contains_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.Contains(test));
_subject = WhereMeta(x => x.CleanTitle.Contains(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE '%' || @Clause1_P1 || '%')");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" ILIKE '%' || @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@@ -123,9 +128,9 @@ namespace NzbDrone.Core.Test.Datastore
public void postgres_where_string_contains_column()
{
var test = "small";
_subject = Where(x => test.Contains(x.CleanTitle));
_subject = WhereMeta(x => test.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(@Clause1_P1 ILIKE '%' || \"Movies\".\"CleanTitle\" || '%')");
_subject.ToString().Should().Be($"(@Clause1_P1 ILIKE '%' || \"MovieMetadata\".\"CleanTitle\" || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@@ -133,9 +138,9 @@ namespace NzbDrone.Core.Test.Datastore
public void postgres_where_column_starts_with_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.StartsWith(test));
_subject = WhereMeta(x => x.CleanTitle.StartsWith(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE @Clause1_P1 || '%')");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" ILIKE @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@@ -143,9 +148,9 @@ namespace NzbDrone.Core.Test.Datastore
public void postgres_where_column_ends_with_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.EndsWith(test));
_subject = WhereMeta(x => x.CleanTitle.EndsWith(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE '%' || @Clause1_P1)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" ILIKE '%' || @Clause1_P1)");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@@ -162,9 +167,9 @@ namespace NzbDrone.Core.Test.Datastore
public void postgres_where_in_list_2()
{
var list = new List<int> { 1, 2, 3 };
_subject = Where(x => x.CleanTitle == "test" && list.Contains(x.Id));
_subject = WhereMeta(x => x.CleanTitle == "test" && list.Contains(x.Id));
_subject.ToString().Should().Be($"((\"Movies\".\"CleanTitle\" = @Clause1_P1) AND (\"Movies\".\"Id\" = ANY (('{{1, 2, 3}}'))))");
_subject.ToString().Should().Be($"((\"MovieMetadata\".\"CleanTitle\" = @Clause1_P1) AND (\"MovieMetadata\".\"Id\" = ANY (('{{1, 2, 3}}'))))");
}
[Test]
@@ -172,35 +177,35 @@ namespace NzbDrone.Core.Test.Datastore
{
var list = new List<string> { "first", "second", "third" };
_subject = Where(x => list.Contains(x.CleanTitle));
_subject = WhereMeta(x => list.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" = ANY (@Clause1_P1))");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" = ANY (@Clause1_P1))");
}
[Test]
public void enum_as_int()
{
_subject = Where(x => x.Status == MovieStatusType.Announced);
_subject = WhereMeta(x => x.Status == MovieStatusType.Announced);
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = @Clause1_P1)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" = @Clause1_P1)");
}
[Test]
public void enum_in_list()
{
var allowed = new List<MovieStatusType> { MovieStatusType.Announced, MovieStatusType.InCinemas };
_subject = Where(x => allowed.Contains(x.Status));
_subject = WhereMeta(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = ANY (@Clause1_P1))");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" = ANY (@Clause1_P1))");
}
[Test]
public void enum_in_array()
{
var allowed = new MovieStatusType[] { MovieStatusType.Announced, MovieStatusType.InCinemas };
_subject = Where(x => allowed.Contains(x.Status));
_subject = WhereMeta(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = ANY (@Clause1_P1))");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" = ANY (@Clause1_P1))");
}
}
}

View File

@@ -27,6 +27,11 @@ namespace NzbDrone.Core.Test.Datastore
return new WhereBuilderSqlite(filter, true, 0);
}
private WhereBuilderSqlite WhereMeta(Expression<Func<MovieMetadata, bool>> filter)
{
return new WhereBuilderSqlite(filter, true, 0);
}
[Test]
public void where_equal_const()
{
@@ -86,36 +91,36 @@ namespace NzbDrone.Core.Test.Datastore
[Test]
public void where_string_is_null()
{
_subject = Where(x => x.CleanTitle == null);
_subject = WhereMeta(x => x.CleanTitle == null);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
}
[Test]
public void where_string_is_null_value()
{
string cleanTitle = null;
_subject = Where(x => x.CleanTitle == cleanTitle);
_subject = WhereMeta(x => x.CleanTitle == cleanTitle);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
}
[Test]
public void where_equal_null_property()
{
var movie = new Movie { CleanTitle = null };
_subject = Where(x => x.CleanTitle == movie.CleanTitle);
var movie = new MovieMetadata { CleanTitle = null };
_subject = WhereMeta(x => x.CleanTitle == movie.CleanTitle);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
}
[Test]
public void where_column_contains_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.Contains(test));
_subject = WhereMeta(x => x.CleanTitle.Contains(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" LIKE '%' || @Clause1_P1 || '%')");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" LIKE '%' || @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@@ -123,9 +128,9 @@ namespace NzbDrone.Core.Test.Datastore
public void where_string_contains_column()
{
var test = "small";
_subject = Where(x => test.Contains(x.CleanTitle));
_subject = WhereMeta(x => test.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(@Clause1_P1 LIKE '%' || \"Movies\".\"CleanTitle\" || '%')");
_subject.ToString().Should().Be($"(@Clause1_P1 LIKE '%' || \"MovieMetadata\".\"CleanTitle\" || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@@ -133,9 +138,9 @@ namespace NzbDrone.Core.Test.Datastore
public void where_column_starts_with_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.StartsWith(test));
_subject = WhereMeta(x => x.CleanTitle.StartsWith(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" LIKE @Clause1_P1 || '%')");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" LIKE @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@@ -143,9 +148,9 @@ namespace NzbDrone.Core.Test.Datastore
public void where_column_ends_with_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.EndsWith(test));
_subject = WhereMeta(x => x.CleanTitle.EndsWith(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" LIKE '%' || @Clause1_P1)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" LIKE '%' || @Clause1_P1)");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@@ -164,9 +169,9 @@ namespace NzbDrone.Core.Test.Datastore
public void where_in_list_2()
{
var list = new List<int> { 1, 2, 3 };
_subject = Where(x => x.CleanTitle == "test" && list.Contains(x.Id));
_subject = WhereMeta(x => x.CleanTitle == "test" && list.Contains(x.Id));
_subject.ToString().Should().Be($"((\"Movies\".\"CleanTitle\" = @Clause1_P1) AND (\"Movies\".\"Id\" IN (1, 2, 3)))");
_subject.ToString().Should().Be($"((\"MovieMetadata\".\"CleanTitle\" = @Clause1_P1) AND (\"MovieMetadata\".\"Id\" IN (1, 2, 3)))");
}
[Test]
@@ -174,35 +179,35 @@ namespace NzbDrone.Core.Test.Datastore
{
var list = new List<string> { "first", "second", "third" };
_subject = Where(x => list.Contains(x.CleanTitle));
_subject = WhereMeta(x => list.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IN @Clause1_P1)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IN @Clause1_P1)");
}
[Test]
public void enum_as_int()
{
_subject = Where(x => x.Status == MovieStatusType.Announced);
_subject = WhereMeta(x => x.Status == MovieStatusType.Announced);
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = @Clause1_P1)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" = @Clause1_P1)");
}
[Test]
public void enum_in_list()
{
var allowed = new List<MovieStatusType> { MovieStatusType.Announced, MovieStatusType.InCinemas };
_subject = Where(x => allowed.Contains(x.Status));
_subject = WhereMeta(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" IN @Clause1_P1)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" IN @Clause1_P1)");
}
[Test]
public void enum_in_array()
{
var allowed = new MovieStatusType[] { MovieStatusType.Announced, MovieStatusType.InCinemas };
_subject = Where(x => allowed.Contains(x.Status));
_subject = WhereMeta(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" IN @Clause1_P1)");
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" IN @Clause1_P1)");
}
}
}

View File

@@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[TestCase(60, 1000, false)]
public void single_episode(int runtime, int sizeInMegaBytes, bool expectedResult)
{
_movie.Runtime = runtime;
_movie.MovieMetadata.Value.Runtime = runtime;
_remoteMovie.Movie = _movie;
_remoteMovie.Release.Size = sizeInMegaBytes.Megabytes();
@@ -63,7 +63,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_return_true_if_size_is_zero()
{
_movie.Runtime = 120;
_movie.MovieMetadata.Value.Runtime = 120;
_remoteMovie.Movie = _movie;
_remoteMovie.Release.Size = 0;
_qualityType.MinSize = 10;
@@ -75,7 +75,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_return_true_if_unlimited_30_minute()
{
_movie.Runtime = 30;
_movie.MovieMetadata.Value.Runtime = 30;
_remoteMovie.Movie = _movie;
_remoteMovie.Release.Size = 18457280000;
_qualityType.MaxSize = null;
@@ -86,7 +86,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_return_true_if_unlimited_60_minute()
{
_movie.Runtime = 60;
_movie.MovieMetadata.Value.Runtime = 60;
_remoteMovie.Movie = _movie;
_remoteMovie.Release.Size = 36857280000;
_qualityType.MaxSize = null;
@@ -97,7 +97,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_use_110_minutes_if_runtime_is_0()
{
_movie.Runtime = 0;
_movie.MovieMetadata.Value.Runtime = 0;
_remoteMovie.Movie = _movie;
_remoteMovie.Release.Size = 1095.Megabytes();

View File

@@ -31,7 +31,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
Language = Language.English
},
OriginalLanguage = Language.French
MovieMetadata = new MovieMetadata
{
OriginalLanguage = Language.French
}
}
};
}

View File

@@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
MinFormatScore = 0
})
.With(m => m.Title = "A Movie")
.With(m => m.Runtime = runtime).Build();
.With(m => m.MovieMetadata.Value.Runtime = runtime).Build();
remoteMovie.Release = new ReleaseInfo();
remoteMovie.Release.PublishDate = DateTime.Now.AddDays(-age);

View File

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

View File

@@ -32,16 +32,16 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
{
movie = Builder<Movie>.CreateListOfSize(amount)
.All()
.With(v => v.Status = MovieStatusType.Released)
.With(v => v.MovieMetadata.Value.Status = MovieStatusType.Released)
.BuildList();
}
else
{
movie = Builder<Movie>.CreateListOfSize(amount)
.All()
.With(v => v.Status = MovieStatusType.Released)
.With(v => v.MovieMetadata.Value.Status = MovieStatusType.Released)
.Random(deleted)
.With(v => v.Status = MovieStatusType.Deleted)
.With(v => v.MovieMetadata.Value.Status = MovieStatusType.Deleted)
.BuildList();
}

View File

@@ -16,7 +16,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
public void should_delete_orphaned_alternative_title_items()
{
var altTitle = Builder<AlternativeTitle>.CreateNew()
.With(h => h.MovieId = default)
.With(h => h.MovieMetadataId = default)
.With(h => h.Language = Language.English)
.BuildNew();
@@ -28,14 +28,14 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
[Test]
public void should_not_delete_unorphaned_alternative_title_items()
{
var movie = Builder<Movie>.CreateNew().BuildNew();
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
Db.Insert(movie);
Db.Insert(movieMetadata);
var altTitle = Builder<AlternativeTitle>.CreateNew()
.With(h => h.MovieId = default)
.With(h => h.MovieMetadataId = default)
.With(h => h.Language = Language.English)
.With(b => b.MovieId = movie.Id)
.With(b => b.MovieMetadataId = movieMetadata.Id)
.BuildNew();
Db.Insert(altTitle);

View File

@@ -15,7 +15,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
public void should_delete_orphaned_credit_items()
{
var credit = Builder<Credit>.CreateNew()
.With(h => h.MovieId = default)
.With(h => h.MovieMetadataId = default)
.With(h => h.Name = "Some Credit")
.BuildNew();
@@ -27,14 +27,14 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
[Test]
public void should_not_delete_unorphaned_credit_items()
{
var movie = Builder<Movie>.CreateNew().BuildNew();
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
Db.Insert(movie);
Db.Insert(movieMetadata);
var credit = Builder<Credit>.CreateNew()
.With(h => h.MovieId = default)
.With(h => h.MovieMetadataId = default)
.With(h => h.Name = "Some Credit")
.With(b => b.MovieId = movie.Id)
.With(b => b.MovieMetadataId = movieMetadata.Id)
.BuildNew();
Db.Insert(credit);

View File

@@ -0,0 +1,60 @@
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Housekeeping.Housekeepers;
using NzbDrone.Core.ImportLists.ImportListMovies;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.Translations;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
{
[TestFixture]
public class CleanupOrphanedMovieMetadataFixture : DbTest<CleanupOrphanedMovieMetadata, MovieMetadata>
{
[Test]
public void should_delete_orphaned_movie_metadata_items()
{
var metadata = Builder<MovieMetadata>.CreateNew().BuildNew();
Db.Insert(metadata);
Subject.Clean();
AllStoredModels.Should().BeEmpty();
}
[Test]
public void should_not_delete_unorphaned_movie_metadata_items()
{
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
Db.Insert(movieMetadata);
var movie = Builder<Movie>.CreateNew()
.With(b => b.MovieMetadataId = movieMetadata.Id)
.BuildNew();
Db.Insert(movie);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
}
[Test]
public void should_not_delete_unorphaned_movie_metadata_items_for_lists()
{
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
Db.Insert(movieMetadata);
var movie = Builder<ImportListMovie>.CreateNew()
.With(b => b.MovieMetadataId = movieMetadata.Id)
.BuildNew();
Db.Insert(movie);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
}
}
}

View File

@@ -16,7 +16,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
public void should_delete_orphaned_movie_translation_items()
{
var translation = Builder<MovieTranslation>.CreateNew()
.With(h => h.MovieId = default)
.With(h => h.MovieMetadataId = default)
.With(h => h.Language = Language.English)
.BuildNew();
@@ -28,14 +28,14 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
[Test]
public void should_not_delete_unorphaned_movie_translation_items()
{
var movie = Builder<Movie>.CreateNew().BuildNew();
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
Db.Insert(movie);
Db.Insert(movieMetadata);
var translation = Builder<MovieTranslation>.CreateNew()
.With(h => h.MovieId = default)
.With(h => h.MovieMetadataId = default)
.With(h => h.Language = Language.English)
.With(b => b.MovieId = movie.Id)
.With(b => b.MovieMetadataId = movieMetadata.Id)
.BuildNew();
Db.Insert(translation);

View File

@@ -38,8 +38,8 @@ namespace NzbDrone.Core.Test.ImportListTests
.Build().ToList();
Mocker.GetMock<ISearchForNewMovie>()
.Setup(v => v.MapMovieToTmdbMovie(It.IsAny<Movie>()))
.Returns<Movie>(m => new Movie { TmdbId = m.TmdbId });
.Setup(v => v.MapMovieToTmdbMovie(It.IsAny<MovieMetadata>()))
.Returns<MovieMetadata>(m => new MovieMetadata { TmdbId = m.TmdbId });
}
private void GivenList(int id, bool enabled, bool enabledAuto, ImportListFetchResult fetchResult)

View File

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

View File

@@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
_movie = Builder<Movie>.CreateNew()
.With(v => v.Id = 2)
.With(v => v.Images = new List<MediaCover.MediaCover> { new MediaCover.MediaCover(MediaCoverTypes.Poster, "") })
.With(v => v.MovieMetadata.Value.Images = new List<MediaCover.MediaCover> { new MediaCover.MediaCover(MediaCoverTypes.Poster, "") })
.Build();
Mocker.GetMock<IMovieService>().Setup(m => m.GetMovie(It.Is<int>(id => id == _movie.Id))).Returns(_movie);

View File

@@ -255,7 +255,7 @@ namespace NzbDrone.Core.Test.MediaFiles
.Returns(imported.Select(i => new ImportResult(i)).ToList());
Mocker.GetMock<IDetectSample>()
.Setup(s => s.IsSample(It.IsAny<Movie>(),
.Setup(s => s.IsSample(It.IsAny<MovieMetadata>(),
It.IsAny<string>()))
.Returns(DetectSampleResult.Sample);
@@ -324,7 +324,7 @@ namespace NzbDrone.Core.Test.MediaFiles
.Returns(imported.Select(i => new ImportResult(i)).ToList());
Mocker.GetMock<IDetectSample>()
.Setup(s => s.IsSample(It.IsAny<Movie>(),
.Setup(s => s.IsSample(It.IsAny<MovieMetadata>(),
It.IsAny<string>()))
.Returns(DetectSampleResult.Sample);
@@ -431,7 +431,7 @@ namespace NzbDrone.Core.Test.MediaFiles
.Returns(new List<ImportResult>());
Mocker.GetMock<IDetectSample>()
.Setup(s => s.IsSample(It.IsAny<Movie>(),
.Setup(s => s.IsSample(It.IsAny<MovieMetadata>(),
It.IsAny<string>()))
.Returns(DetectSampleResult.Sample);

View File

@@ -24,7 +24,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Aggregation.Aggregators
public void Setup()
{
_movie = Builder<Movie>.CreateNew()
.With(m => m.OriginalLanguage = Language.English)
.With(m => m.MovieMetadata.Value.OriginalLanguage = Language.English)
.Build();
_localMovie = Builder<LocalMovie>.CreateNew()
@@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Aggregation.Aggregators
{
var result = Subject.Aggregate(_localMovie, null, false);
result.Languages.Should().Contain(_movie.OriginalLanguage);
result.Languages.Should().Contain(_movie.MovieMetadata.Value.OriginalLanguage);
}
[Test]

View File

@@ -16,20 +16,20 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
[TestFixture]
public class DetectSampleFixture : CoreTest<DetectSample>
{
private Movie _movie;
private MovieMetadata _movie;
private LocalMovie _localMovie;
[SetUp]
public void Setup()
{
_movie = Builder<Movie>.CreateNew()
_movie = Builder<MovieMetadata>.CreateNew()
.With(s => s.Runtime = 30)
.Build();
_localMovie = new LocalMovie
{
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi",
Movie = _movie,
Movie = new Movie { MovieMetadata = _movie },
Quality = new QualityModel(Quality.HDTV720p)
};
}
@@ -96,7 +96,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
{
GivenRuntime(120);
Subject.IsSample(_localMovie.Movie,
Subject.IsSample(_localMovie.Movie.MovieMetadata,
_localMovie.Path);
Mocker.GetMock<IVideoFileInfoReader>().Verify(v => v.GetRunTime(It.IsAny<string>()), Times.Once());
@@ -152,7 +152,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
.Setup(s => s.GetRunTime(It.IsAny<string>()))
.Returns((TimeSpan?)null);
Subject.IsSample(_localMovie.Movie,
Subject.IsSample(_localMovie.Movie.MovieMetadata,
_localMovie.Path).Should().Be(DetectSampleResult.Indeterminate);
ExceptionVerification.ExpectedErrors(1);
@@ -160,13 +160,13 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
private void ShouldBeSample()
{
Subject.IsSample(_localMovie.Movie,
Subject.IsSample(_localMovie.Movie.MovieMetadata,
_localMovie.Path).Should().Be(DetectSampleResult.Sample);
}
private void ShouldBeNotSample()
{
Subject.IsSample(_localMovie.Movie,
Subject.IsSample(_localMovie.Movie.MovieMetadata,
_localMovie.Path).Should().Be(DetectSampleResult.NotSample);
}
}

View File

@@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook
details.Title.Should().Be(title);
}
private void ValidateMovie(Movie movie)
private void ValidateMovie(MovieMetadata movie)
{
movie.Should().NotBeNull();
movie.Title.Should().NotBeNullOrWhiteSpace();
@@ -41,7 +41,6 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook
movie.ImdbId.Should().NotBeNullOrWhiteSpace();
movie.Studio.Should().NotBeNullOrWhiteSpace();
movie.Runtime.Should().BeGreaterThan(0);
movie.TitleSlug.Should().NotBeNullOrWhiteSpace();
//series.TvRageId.Should().BeGreaterThan(0);
movie.TmdbId.Should().BeGreaterThan(0);

View File

@@ -20,14 +20,13 @@ namespace NzbDrone.Core.Test.MovieTests
[TestFixture]
public class AddMovieFixture : CoreTest<AddMovieService>
{
private Movie _fakeMovie;
private MovieMetadata _fakeMovie;
[SetUp]
public void Setup()
{
_fakeMovie = Builder<Movie>
_fakeMovie = Builder<MovieMetadata>
.CreateNew()
.With(s => s.Path = null)
.Build();
}
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Test.MovieTests
{
Mocker.GetMock<IProvideMovieInfo>()
.Setup(s => s.GetMovieInfo(tmdbId))
.Returns(new Tuple<Movie, List<Credit>>(_fakeMovie, new List<Credit>()));
.Returns(new Tuple<MovieMetadata, List<Credit>>(_fakeMovie, new List<Credit>()));
}
private void GivenValidPath()

View File

@@ -18,16 +18,17 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
private AlternativeTitle _title2;
private AlternativeTitle _title3;
private Movie _movie;
private MovieMetadata _movie;
[SetUp]
public void Setup()
{
var titles = Builder<AlternativeTitle>.CreateListOfSize(3).All().With(t => t.MovieId = 0).Build();
var titles = Builder<AlternativeTitle>.CreateListOfSize(3).All().With(t => t.MovieMetadataId = 0).Build();
_title1 = titles[0];
_title2 = titles[1];
_title3 = titles[2];
_movie = Builder<Movie>.CreateNew()
_movie = Builder<MovieMetadata>.CreateNew()
.With(m => m.CleanTitle = "myothertitle")
.With(m => m.Id = 1)
.Build();
@@ -35,7 +36,7 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
private void GivenExistingTitles(params AlternativeTitle[] titles)
{
Mocker.GetMock<IAlternativeTitleRepository>().Setup(r => r.FindByMovieId(_movie.Id))
Mocker.GetMock<IAlternativeTitleRepository>().Setup(r => r.FindByMovieMetadataId(_movie.Id))
.Returns(titles.ToList());
}
@@ -72,7 +73,7 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
{
GivenExistingTitles();
var titles = new List<AlternativeTitle> { _title1 };
var movie = Builder<Movie>.CreateNew().With(m => m.CleanTitle = _title1.CleanTitle).Build();
var movie = Builder<MovieMetadata>.CreateNew().With(m => m.CleanTitle = _title1.CleanTitle).Build();
Subject.UpdateTitles(titles, movie);
@@ -87,8 +88,8 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
Subject.UpdateTitles(titles, _movie);
_title1.MovieId.Should().Be(_movie.Id);
_title2.MovieId.Should().Be(_movie.Id);
_title1.MovieMetadataId.Should().Be(_movie.Id);
_title2.MovieMetadataId.Should().Be(_movie.Id);
}
[Test]

View File

@@ -32,18 +32,18 @@ namespace NzbDrone.Core.Test.MovieTests.CreditTests
var credits = Builder<Credit>.CreateListOfSize(5)
.TheFirst(1)
.With(c => c.Id = 0)
.With(c => c.MovieId = _movie2.Id)
.With(c => c.MovieMetadataId = _movie2.Id)
.TheRest()
.With(c => c.Id = 0)
.With(c => c.MovieId = _movie1.Id)
.With(c => c.MovieMetadataId = _movie1.Id)
.BuildListOfNew();
Db.InsertMany(credits);
Subject.DeleteForMovies(new List<int> { _movie1.Id });
var removedMovieCredits = Subject.FindByMovieId(_movie1.Id);
var nonRemovedMovieCredits = Subject.FindByMovieId(_movie2.Id);
var removedMovieCredits = Subject.FindByMovieMetadataId(_movie1.Id);
var nonRemovedMovieCredits = Subject.FindByMovieMetadataId(_movie2.Id);
removedMovieCredits.Should().HaveCount(0);
nonRemovedMovieCredits.Should().HaveCount(1);

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
@@ -18,25 +18,25 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
private Credit _credit2;
private Credit _credit3;
private Movie _movie;
private MovieMetadata _movie;
[SetUp]
public void Setup()
{
var credits = Builder<Credit>.CreateListOfSize(3)
.All()
.With(t => t.MovieId = 0).Build();
.With(t => t.MovieMetadataId = 0).Build();
_credit1 = credits[0];
_credit2 = credits[1];
_credit3 = credits[2];
_movie = Builder<Movie>.CreateNew().With(m => m.Id = 1).Build();
_movie = Builder<MovieMetadata>.CreateNew().With(m => m.Id = 1).Build();
}
private void GivenExistingCredits(params Credit[] credits)
{
Mocker.GetMock<ICreditRepository>().Setup(r => r.FindByMovieId(_movie.Id))
Mocker.GetMock<ICreditRepository>().Setup(r => r.FindByMovieMetadataId(_movie.Id))
.Returns(credits.ToList());
}
@@ -77,8 +77,8 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
Subject.UpdateCredits(titles, _movie);
_credit1.MovieId.Should().Be(_movie.Id);
_credit2.MovieId.Should().Be(_movie.Id);
_credit1.MovieMetadataId.Should().Be(_movie.Id);
_credit2.MovieMetadataId.Should().Be(_movie.Id);
}
[Test]

View File

@@ -21,9 +21,9 @@ namespace NzbDrone.Core.Test.MovieTests
private void SetMovieProperties(DateTime? cinema, DateTime? physical, DateTime? digital, MovieStatusType minimumAvailability)
{
_movie.InCinemas = cinema;
_movie.PhysicalRelease = physical;
_movie.DigitalRelease = digital;
_movie.MovieMetadata.Value.InCinemas = cinema;
_movie.MovieMetadata.Value.PhysicalRelease = physical;
_movie.MovieMetadata.Value.DigitalRelease = digital;
_movie.MinimumAvailability = minimumAvailability;
}

View File

@@ -0,0 +1,62 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.MovieTests.MovieMetadataRepositoryTests
{
[TestFixture]
public class MovieMetadataRepositoryFixture : DbTest<MovieMetadataRepository, MovieMetadata>
{
private MovieMetadataRepository _movieMetadataRepo;
private List<MovieMetadata> _metadataList;
[SetUp]
public void Setup()
{
_movieMetadataRepo = Mocker.Resolve<MovieMetadataRepository>();
_metadataList = Builder<MovieMetadata>.CreateListOfSize(10).All().With(x => x.Id = 0).BuildList();
}
[Test]
public void upsert_many_should_insert_list_of_new()
{
var updated = _movieMetadataRepo.UpsertMany(_metadataList);
AllStoredModels.Should().HaveCount(_metadataList.Count);
updated.Should().BeTrue();
}
[Test]
public void upsert_many_should_upsert_existing_with_id_0()
{
var clone = _metadataList.JsonClone();
var updated = _movieMetadataRepo.UpsertMany(clone);
updated.Should().BeTrue();
AllStoredModels.Should().HaveCount(_metadataList.Count);
updated = _movieMetadataRepo.UpsertMany(_metadataList);
updated.Should().BeFalse();
AllStoredModels.Should().HaveCount(_metadataList.Count);
}
[Test]
public void upsert_many_should_upsert_mixed_list_of_old_and_new()
{
var clone = _metadataList.Take(5).ToList().JsonClone();
var updated = _movieMetadataRepo.UpsertMany(clone);
updated.Should().BeTrue();
AllStoredModels.Should().HaveCount(clone.Count);
updated = _movieMetadataRepo.UpsertMany(_metadataList);
updated.Should().BeTrue();
AllStoredModels.Should().HaveCount(_metadataList.Count);
}
}
}

View File

@@ -19,15 +19,15 @@ namespace NzbDrone.Core.Test.MovieTests.MovieServiceTests
{
_candidates = Builder<Movie>.CreateListOfSize(3)
.TheFirst(1)
.With(x => x.CleanTitle = "batman")
.With(x => x.MovieMetadata.Value.CleanTitle = "batman")
.With(x => x.Year = 2000)
.TheNext(1)
.With(x => x.CleanTitle = "batman")
.With(x => x.MovieMetadata.Value.CleanTitle = "batman")
.With(x => x.Year = 1999)
.TheRest()
.With(x => x.CleanTitle = "darkknight")
.With(x => x.MovieMetadata.Value.CleanTitle = "darkknight")
.With(x => x.Year = 2008)
.With(x => x.AlternativeTitles = new List<AlternativeTitle>
.With(x => x.MovieMetadata.Value.AlternativeTitles = new List<AlternativeTitle>
{
new AlternativeTitle
{

View File

@@ -1,79 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MovieTests
{
[TestFixture]
public class MovieTitleSlugValidatorFixture : CoreTest<MovieTitleSlugValidator>
{
private List<Movie> _movies;
private TestValidator<Movie> _validator;
[SetUp]
public void Setup()
{
_movies = Builder<Movie>.CreateListOfSize(1)
.Build()
.ToList();
_validator = new TestValidator<Movie>
{
v => v.RuleFor(s => s.TitleSlug).SetValidator(Subject)
};
Mocker.GetMock<IMovieService>()
.Setup(s => s.AllMovieTitleSlugs())
.Returns(_movies.ToDictionary(m => m.Id, m => m.TitleSlug));
}
[Test]
public void should_not_be_valid_if_there_is_an_existing_movie_with_the_same_title_slug()
{
Mocker.GetMock<IMovieService>()
.Setup(s => s.GetMovie(_movies.First().Id))
.Returns(_movies.First());
var movie = Builder<Movie>.CreateNew()
.With(s => s.Id = 100)
.With(s => s.TitleSlug = _movies.First().TitleSlug)
.Build();
_validator.Validate(movie).IsValid.Should().BeFalse();
}
[Test]
public void should_be_valid_if_there_is_not_an_existing_movie_with_the_same_title_slug()
{
var movie = Builder<Movie>.CreateNew()
.With(s => s.TitleSlug = "MyTitleSlug")
.Build();
_validator.Validate(movie).IsValid.Should().BeTrue();
}
[Test]
public void should_be_valid_if_there_is_an_existing_movie_with_a_null_title_slug()
{
_movies.First().TitleSlug = null;
var movie = Builder<Movie>.CreateNew()
.With(s => s.TitleSlug = "MyTitleSlug")
.Build();
_validator.Validate(movie).IsValid.Should().BeTrue();
}
[Test]
public void should_be_valid_when_updating_an_existing_movie()
{
_validator.Validate(_movies.First().JsonClone()).IsValid.Should().BeTrue();
}
}
}

View File

@@ -18,17 +18,26 @@ namespace NzbDrone.Core.Test.MovieTests
[TestFixture]
public class RefreshMovieServiceFixture : CoreTest<RefreshMovieService>
{
private Movie _movie;
private MovieMetadata _movie;
private Movie _existingMovie;
[SetUp]
public void Setup()
{
_movie = Builder<Movie>.CreateNew()
_movie = Builder<MovieMetadata>.CreateNew()
.With(s => s.Status = MovieStatusType.Released)
.Build();
_existingMovie = Builder<Movie>.CreateNew()
.With(s => s.MovieMetadata.Value.Status = MovieStatusType.Released)
.Build();
Mocker.GetMock<IMovieService>()
.Setup(s => s.GetMovie(_movie.Id))
.Returns(_existingMovie);
Mocker.GetMock<IMovieMetadataService>()
.Setup(s => s.Get(_movie.Id))
.Returns(_movie);
Mocker.GetMock<IProvideMovieInfo>()
@@ -36,11 +45,11 @@ namespace NzbDrone.Core.Test.MovieTests
.Callback<int>((i) => { throw new MovieNotFoundException(i); });
}
private void GivenNewMovieInfo(Movie movie)
private void GivenNewMovieInfo(MovieMetadata movie)
{
Mocker.GetMock<IProvideMovieInfo>()
.Setup(s => s.GetMovieInfo(_movie.TmdbId))
.Returns(new Tuple<Movie, List<Credit>>(movie, new List<Credit>()));
.Returns(new Tuple<MovieMetadata, List<Credit>>(movie, new List<Credit>()));
}
[Test]
@@ -53,8 +62,8 @@ namespace NzbDrone.Core.Test.MovieTests
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
Mocker.GetMock<IMovieService>()
.Verify(v => v.UpdateMovie(It.Is<List<Movie>>(s => s.First().ImdbId == newMovieInfo.ImdbId), true));
Mocker.GetMock<IMovieMetadataService>()
.Verify(v => v.Upsert(It.Is<MovieMetadata>(s => s.ImdbId == newMovieInfo.ImdbId)));
}
[Test]
@@ -62,8 +71,8 @@ namespace NzbDrone.Core.Test.MovieTests
{
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
Mocker.GetMock<IMovieService>()
.Verify(v => v.UpdateMovie(It.Is<Movie>(s => s.Status == MovieStatusType.Deleted)), Times.Once());
Mocker.GetMock<IMovieMetadataService>()
.Verify(v => v.Upsert(It.Is<MovieMetadata>(s => s.Status == MovieStatusType.Deleted)), Times.Once());
ExceptionVerification.ExpectedErrors(1);
}
@@ -78,8 +87,8 @@ namespace NzbDrone.Core.Test.MovieTests
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
Mocker.GetMock<IMovieService>()
.Verify(v => v.UpdateMovie(It.Is<List<Movie>>(s => s.First().TmdbId == newMovieInfo.TmdbId), true));
Mocker.GetMock<IMovieMetadataService>()
.Verify(v => v.Upsert(It.Is<MovieMetadata>(s => s.TmdbId == newMovieInfo.TmdbId)));
ExceptionVerification.ExpectedWarns(1);
}
@@ -89,8 +98,8 @@ namespace NzbDrone.Core.Test.MovieTests
{
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
Mocker.GetMock<IMovieService>()
.Verify(v => v.UpdateMovie(It.Is<Movie>(s => s.Status == MovieStatusType.Deleted)), Times.Once());
Mocker.GetMock<IMovieMetadataService>()
.Verify(v => v.Upsert(It.Is<MovieMetadata>(s => s.Status == MovieStatusType.Deleted)), Times.Once());
ExceptionVerification.ExpectedErrors(1);
}
@@ -102,8 +111,8 @@ namespace NzbDrone.Core.Test.MovieTests
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
Mocker.GetMock<IMovieService>()
.Verify(v => v.UpdateMovie(It.IsAny<Movie>()), Times.Never());
Mocker.GetMock<IMovieMetadataService>()
.Verify(v => v.Upsert(It.IsAny<MovieMetadata>()), Times.Never());
ExceptionVerification.ExpectedErrors(1);
}

View File

@@ -10,12 +10,12 @@ namespace NzbDrone.Core.Test.MovieTests
[TestFixture]
public class ShouldRefreshMovieFixture : TestBase<ShouldRefreshMovie>
{
private Movie _movie;
private MovieMetadata _movie;
[SetUp]
public void Setup()
{
_movie = Builder<Movie>.CreateNew()
_movie = Builder<MovieMetadata>.CreateNew()
.With(v => v.Status = MovieStatusType.InCinemas)
.With(m => m.PhysicalRelease = DateTime.Today.AddDays(-100))
.Build();

View File

@@ -50,7 +50,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
_movie = Builder<Movie>
.CreateNew()
.With(s => s.Title = "South Park")
.With(s => s.OriginalTitle = "South of the Park")
.With(s => s.MovieMetadata.Value.OriginalTitle = "South of the Park")
.Build();
_namingConfig = NamingConfig.Default;
@@ -70,7 +70,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
.Returns(new List<CustomFormat>());
Mocker.GetMock<IMovieTranslationService>()
.Setup(v => v.GetAllTranslationsForMovie(It.IsAny<int>()))
.Setup(v => v.GetAllTranslationsForMovieMetadata(It.IsAny<int>()))
.Returns(_movieTranslations);
}
@@ -206,7 +206,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
public void should_replace_movie_original_title()
{
_namingConfig.StandardMovieFormat = "{Movie OriginalTitle}";
_movie.OriginalTitle = "South of the Park";
_movie.MovieMetadata.Value.OriginalTitle = "South of the Park";
Subject.BuildFileName(_movie, _movieFile)
.Should().Be("South of the Park");
@@ -216,7 +216,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
public void should_replace_movie_certification()
{
_namingConfig.StandardMovieFormat = "{Movie Certification}";
_movie.Certification = "R";
_movie.MovieMetadata.Value.Certification = "R";
Subject.BuildFileName(_movie, _movieFile)
.Should().Be("R");
@@ -226,7 +226,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
public void should_replace_movie_collection()
{
_namingConfig.StandardMovieFormat = "{Movie Collection}";
_movie.Collection = new MovieCollection { Name = "South Part Collection" };
_movie.MovieMetadata.Value.Collection = new MovieCollection { Name = "South Part Collection" };
Subject.BuildFileName(_movie, _movieFile)
.Should().Be("South Part Collection");

View File

@@ -16,7 +16,10 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
var releaseInfo = new ParsedMovieInfo();
var movie = new Movies.Movie
{
OriginalLanguage = Language.English
MovieMetadata = new Movies.MovieMetadata
{
OriginalLanguage = Language.English
}
};
var result = Subject.AugmentMovieInfo(releaseInfo, movie);
result.ExtraInfo.Should().ContainKey("OriginalLanguage");

View File

@@ -36,11 +36,11 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
_movie = Builder<Movie>.CreateNew()
.With(m => m.Title = "Fack Ju Göthe 2")
.With(m => m.CleanTitle = "fackjugoethe2")
.With(m => m.MovieMetadata.Value.CleanTitle = "fackjugoethe2")
.With(m => m.Year = 2015)
.With(m => m.AlternativeTitles = new List<AlternativeTitle> { new AlternativeTitle("Fack Ju Göthe 2: Same same") })
.With(m => m.Translations = new List<MovieTranslation> { new MovieTranslation { Title = "Translated Title", CleanTitle = "translatedtitle" } })
.With(m => m.OriginalLanguage = Language.English)
.With(m => m.MovieMetadata.Value.AlternativeTitles = new List<AlternativeTitle> { new AlternativeTitle("Fack Ju Göthe 2: Same same") })
.With(m => m.MovieMetadata.Value.Translations = new List<MovieTranslation> { new MovieTranslation { Title = "Translated Title", CleanTitle = "translatedtitle" } })
.With(m => m.MovieMetadata.Value.OriginalLanguage = Language.English)
.Build();
_parsedMovieInfo = new ParsedMovieInfo
@@ -66,14 +66,14 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
_alternativeTitleInfo = new ParsedMovieInfo
{
MovieTitles = new List<string> { _movie.AlternativeTitles.First().Title },
MovieTitles = new List<string> { _movie.MovieMetadata.Value.AlternativeTitles.First().Title },
Languages = new List<Language> { Language.English },
Year = _movie.Year,
};
_translationTitleInfo = new ParsedMovieInfo
{
MovieTitles = new List<string> { _movie.Translations.First().Title },
MovieTitles = new List<string> { _movie.MovieMetadata.Value.Translations.First().Title },
Languages = new List<Language> { Language.English },
Year = _movie.Year,
};

View File

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

View File

@@ -76,20 +76,20 @@ namespace NzbDrone.Core.CustomFormats
var info = new ParsedMovieInfo
{
MovieTitles = new List<string>() { movieFile.Movie.Title },
MovieTitles = new List<string>() { movieFile.Movie.MovieMetadata.Value.Title },
SimpleReleaseTitle = sceneName.SimplifyReleaseTitle(),
Quality = movieFile.Quality,
Languages = movieFile.Languages,
ReleaseGroup = movieFile.ReleaseGroup,
Edition = movieFile.Edition,
Year = movieFile.Movie.Year,
ImdbId = movieFile.Movie.ImdbId,
Year = movieFile.Movie.MovieMetadata.Value.Year,
ImdbId = movieFile.Movie.MovieMetadata.Value.ImdbId,
ExtraInfo = new Dictionary<string, object>
{
{ "IndexerFlags", movieFile.IndexerFlags },
{ "Size", movieFile.Size },
{ "Filename", Path.GetFileName(movieFile.RelativePath) },
{ "OriginalLanguage", movieFile.Movie.OriginalLanguage }
{ "OriginalLanguage", movieFile.Movie.MovieMetadata.Value.OriginalLanguage }
}
};
@@ -114,14 +114,14 @@ namespace NzbDrone.Core.CustomFormats
var info = new ParsedMovieInfo
{
MovieTitles = new List<string>() { movie.Title },
MovieTitles = new List<string>() { movie.MovieMetadata.Value.Title },
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? blocklist.SourceTitle.SimplifyReleaseTitle(),
Quality = blocklist.Quality,
Languages = blocklist.Languages,
ReleaseGroup = parsed?.ReleaseGroup,
Edition = parsed?.Edition,
Year = movie.Year,
ImdbId = movie.ImdbId,
Year = movie.MovieMetadata.Value.Year,
ImdbId = movie.MovieMetadata.Value.ImdbId,
ExtraInfo = new Dictionary<string, object>
{
{ "IndexerFlags", blocklist.IndexerFlags },
@@ -142,14 +142,14 @@ namespace NzbDrone.Core.CustomFormats
var info = new ParsedMovieInfo
{
MovieTitles = new List<string>() { movie.Title },
MovieTitles = new List<string>() { movie.MovieMetadata.Value.Title },
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? history.SourceTitle.SimplifyReleaseTitle(),
Quality = history.Quality,
Languages = history.Languages,
ReleaseGroup = parsed?.ReleaseGroup,
Edition = parsed?.Edition,
Year = movie.Year,
ImdbId = movie.ImdbId,
Year = movie.MovieMetadata.Value.Year,
ImdbId = movie.MovieMetadata.Value.ImdbId,
ExtraInfo = new Dictionary<string, object>
{
{ "IndexerFlags", flags },

View File

@@ -47,13 +47,6 @@ namespace NzbDrone.Core.Datastore
return builder.Where(wb.ToString(), wb.Parameters);
}
public static SqlBuilder WherePostgres<TModel>(this SqlBuilder builder, Expression<Func<TModel, bool>> filter)
{
var wb = new WhereBuilderPostgres(filter, true, builder.Sequence);
return builder.Where(wb.ToString(), wb.Parameters);
}
public static SqlBuilder OrWhere<TModel>(this SqlBuilder builder, Expression<Func<TModel, bool>> filter)
{
var wb = GetWhereBuilder(builder.DatabaseType, filter, true, builder.Sequence);

View File

@@ -0,0 +1,151 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(207)]
public class movie_metadata : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Create.TableForModel("MovieMetadata")
.WithColumn("TmdbId").AsInt32().Unique()
.WithColumn("ImdbId").AsString().Nullable()
.WithColumn("Images").AsString()
.WithColumn("Genres").AsString().Nullable()
.WithColumn("Title").AsString()
.WithColumn("SortTitle").AsString().Nullable()
.WithColumn("CleanTitle").AsString().Nullable().Indexed()
.WithColumn("OriginalTitle").AsString().Nullable()
.WithColumn("CleanOriginalTitle").AsString().Nullable().Indexed()
.WithColumn("OriginalLanguage").AsInt32()
.WithColumn("Status").AsInt32()
.WithColumn("LastInfoSync").AsDateTime().Nullable()
.WithColumn("Runtime").AsInt32()
.WithColumn("InCinemas").AsDateTime().Nullable()
.WithColumn("PhysicalRelease").AsDateTime().Nullable()
.WithColumn("DigitalRelease").AsDateTime().Nullable()
.WithColumn("Year").AsInt32().Nullable()
.WithColumn("SecondaryYear").AsInt32().Nullable()
.WithColumn("Ratings").AsString().Nullable()
.WithColumn("Recommendations").AsString()
.WithColumn("Certification").AsString().Nullable()
.WithColumn("YouTubeTrailerId").AsString().Nullable()
.WithColumn("Collection").AsString().Nullable()
.WithColumn("Studio").AsString().Nullable()
.WithColumn("Overview").AsString().Nullable()
.WithColumn("Website").AsString().Nullable()
.WithColumn("Popularity").AsFloat().Nullable();
// Transfer metadata from Movies to MovieMetadata
Execute.Sql(@"INSERT INTO ""MovieMetadata"" (""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""CleanTitle"", ""OriginalTitle"", ""CleanOriginalTitle"", ""OriginalLanguage"", ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""SecondaryYear"", ""Recommendations"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website"")
SELECT ""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""CleanTitle"", ""OriginalTitle"", ""CleanTitle"", ""OriginalLanguage"", ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""SecondaryYear"", ""Recommendations"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website""
FROM ""Movies""");
// Transfer metadata from ImportListMovies to MovieMetadata if not already in
Execute.Sql(@"INSERT INTO ""MovieMetadata"" (""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""CleanTitle"", ""OriginalTitle"", ""CleanOriginalTitle"", ""OriginalLanguage"", ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""Recommendations"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website"")
SELECT ""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""Title"", ""OriginalTitle"", ""OriginalTitle"", 1, ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", '[]', ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website""
FROM ""ImportListMovies""
WHERE ""ImportListMovies"".""TmdbId"" NOT IN ( SELECT ""MovieMetadata"".""TmdbId"" FROM ""MovieMetadata"" )
AND ""ImportListMovies"".""Id"" IN ( SELECT MIN(""Id"") FROM ""ImportListMovies"" GROUP BY ""TmdbId"" )");
// Add an MovieMetadataId column to Movies
Alter.Table("Movies").AddColumn("MovieMetadataId").AsInt32().WithDefaultValue(0);
Alter.Table("AlternativeTitles").AddColumn("MovieMetadataId").AsInt32().WithDefaultValue(0);
Alter.Table("Credits").AddColumn("MovieMetadataId").AsInt32().WithDefaultValue(0);
Alter.Table("MovieTranslations").AddColumn("MovieMetadataId").AsInt32().WithDefaultValue(0);
Alter.Table("ImportListMovies").AddColumn("MovieMetadataId").AsInt32().WithDefaultValue(0).Indexed();
// Update MovieMetadataId
Execute.Sql(@"UPDATE ""Movies""
SET ""MovieMetadataId"" = (SELECT ""MovieMetadata"".""Id""
FROM ""MovieMetadata""
WHERE ""MovieMetadata"".""TmdbId"" = ""Movies"".""TmdbId"")");
Execute.Sql(@"UPDATE ""AlternativeTitles""
SET ""MovieMetadataId"" = (SELECT ""Movies"".""MovieMetadataId""
FROM ""Movies""
WHERE ""Movies"".""Id"" = ""AlternativeTitles"".""MovieId"")");
Execute.Sql(@"UPDATE ""Credits""
SET ""MovieMetadataId"" = (SELECT ""Movies"".""MovieMetadataId""
FROM ""Movies""
WHERE ""Movies"".""Id"" = ""Credits"".""MovieId"")");
Execute.Sql(@"UPDATE ""MovieTranslations""
SET ""MovieMetadataId"" = (SELECT ""Movies"".""MovieMetadataId""
FROM ""Movies""
WHERE ""Movies"".""Id"" = ""MovieTranslations"".""MovieId"")");
Execute.Sql(@"UPDATE ""ImportListMovies""
SET ""MovieMetadataId"" = (SELECT ""MovieMetadata"".""Id""
FROM ""MovieMetadata""
WHERE ""MovieMetadata"".""TmdbId"" = ""ImportListMovies"".""TmdbId"")");
// Alter MovieMetadataId column to be unique on Movies
Alter.Table("Movies").AlterColumn("MovieMetadataId").AsInt32().Unique();
// Remove Movie Link from Metadata Tables
Delete.Column("MovieId").FromTable("AlternativeTitles");
Delete.Column("MovieId").FromTable("Credits");
Delete.Column("MovieId").FromTable("MovieTranslations");
// Remove the columns in Movies now in MovieMetadata
Delete.Column("TmdbId")
.Column("ImdbId")
.Column("Title")
.Column("SortTitle")
.Column("CleanTitle")
.Column("OriginalTitle")
.Column("OriginalLanguage")
.Column("Overview")
.Column("Status")
.Column("LastInfoSync")
.Column("Images")
.Column("Genres")
.Column("Ratings")
.Column("Runtime")
.Column("InCinemas")
.Column("PhysicalRelease")
.Column("DigitalRelease")
.Column("Year")
.Column("SecondaryYear")
.Column("Recommendations")
.Column("Certification")
.Column("YouTubeTrailerId")
.Column("Studio")
.Column("Collection")
.Column("Website")
// as well as the ones no longer used
.Column("LastDiskSync")
.Column("TitleSlug")
.FromTable("Movies");
// Remove the columns in ImportListMovies now in MovieMetadata
Delete.Column("TmdbId")
.Column("ImdbId")
.Column("Title")
.Column("SortTitle")
.Column("Overview")
.Column("Status")
.Column("LastInfoSync")
.Column("OriginalTitle")
.Column("Translations")
.Column("Images")
.Column("Genres")
.Column("Ratings")
.Column("Runtime")
.Column("InCinemas")
.Column("PhysicalRelease")
.Column("DigitalRelease")
.Column("Year")
.Column("Certification")
.Column("YouTubeTrailerId")
.Column("Studio")
.Column("Collection")
.Column("Website")
.FromTable("ImportListMovies");
}
}
}

View File

@@ -109,9 +109,18 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<Movie>("Movies").RegisterModel()
.Ignore(s => s.RootFolderPath)
.Ignore(s => s.Translations);
.Ignore(s => s.Title)
.Ignore(s => s.Year)
.Ignore(s => s.TmdbId)
.Ignore(s => s.ImdbId)
.HasOne(a => a.MovieMetadata, a => a.MovieMetadataId);
Mapper.Entity<ImportListMovie>("ImportListMovies").RegisterModel();
Mapper.Entity<ImportListMovie>("ImportListMovies").RegisterModel()
.Ignore(s => s.Title)
.Ignore(s => s.Year)
.Ignore(s => s.TmdbId)
.Ignore(s => s.ImdbId)
.HasOne(a => a.MovieMetadata, a => a.MovieMetadataId);
Mapper.Entity<AlternativeTitle>("AlternativeTitles").RegisterModel();
@@ -156,6 +165,9 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<DownloadHistory>("DownloadHistory").RegisterModel();
Mapper.Entity<UpdateHistory>("UpdateHistory").RegisterModel();
Mapper.Entity<MovieMetadata>("MovieMetadata").RegisterModel()
.Ignore(s => s.Translations);
}
private static void RegisterMappers()

View File

@@ -174,9 +174,9 @@ namespace NzbDrone.Core.DecisionEngine
var preferredSize = _qualityDefinitionService.Get(remoteMovie.ParsedMovieInfo.Quality.Quality).PreferredSize;
// If no value for preferred it means unlimited so fallback to sort largest is best
if (preferredSize.HasValue && remoteMovie.Movie.Runtime > 0)
if (preferredSize.HasValue && remoteMovie.Movie.MovieMetadata.Value.Runtime > 0)
{
var preferredMovieSize = remoteMovie.Movie.Runtime * preferredSize.Value.Megabytes();
var preferredMovieSize = remoteMovie.Movie.MovieMetadata.Value.Runtime * preferredSize.Value.Megabytes();
// Calculate closest to the preferred size
return Math.Abs((remoteMovie.Release.Size - preferredMovieSize).Round(200.Megabytes())) * (-1);

View File

@@ -34,10 +34,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
var qualityDefinition = _qualityDefinitionService.Get(quality);
if (subject.Movie.Runtime == 0)
if (subject.Movie.MovieMetadata.Value.Runtime == 0)
{
_logger.Warn("{0} has no runtime information using median movie runtime of 110 minutes.", subject.Movie);
subject.Movie.Runtime = 110;
subject.Movie.MovieMetadata.Value.Runtime = 110;
}
if (qualityDefinition.MinSize.HasValue)
@@ -45,7 +45,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
var minSize = qualityDefinition.MinSize.Value.Megabytes();
//Multiply maxSize by Series.Runtime
minSize = minSize * subject.Movie.Runtime;
minSize = minSize * subject.Movie.MovieMetadata.Value.Runtime;
//If the parsed size is smaller than minSize we don't want it
if (subject.Release.Size < minSize)
@@ -61,7 +61,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
{
_logger.Debug("Max size is unlimited, skipping check");
}
else if (subject.Movie.Runtime == 0)
else if (subject.Movie.MovieMetadata.Value.Runtime == 0)
{
_logger.Debug("Movie runtime is 0, unable to validate size until it is available, rejecting");
return Decision.Reject("Movie runtime is 0, unable to validate size until it is available");
@@ -71,7 +71,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
var maxSize = qualityDefinition.MaxSize.Value.Megabytes();
//Multiply maxSize by Series.Runtime
maxSize = maxSize * subject.Movie.Runtime;
maxSize = maxSize * subject.Movie.MovieMetadata.Value.Runtime;
//If the parsed size is greater than maxSize we don't want it
if (subject.Release.Size > maxSize)

View File

@@ -27,7 +27,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
var originalLanguage = subject.Movie.OriginalLanguage;
var originalLanguage = subject.Movie.MovieMetadata.Value.OriginalLanguage;
if (wantedLanguage == Language.Original)
{

View File

@@ -68,7 +68,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
_proxy.SetTorrentLabel(actualHash, Settings.MovieCategory, Settings);
}
var isRecentMovie = remoteMovie.Movie.IsRecentMovie;
var isRecentMovie = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie;
if ((isRecentMovie && Settings.RecentMoviePriority == (int)DelugePriority.First) ||
(!isRecentMovie && Settings.OlderMoviePriority == (int)DelugePriority.First))
@@ -95,7 +95,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
_proxy.SetTorrentLabel(actualHash, Settings.MovieCategory, Settings);
}
var isRecentMovie = remoteMovie.Movie.IsRecentMovie;
var isRecentMovie = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie;
if ((isRecentMovie && Settings.RecentMoviePriority == (int)DelugePriority.First) ||
(!isRecentMovie && Settings.OlderMoviePriority == (int)DelugePriority.First))

View File

@@ -52,7 +52,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
switch (additionalTag)
{
case (int)AdditionalTags.Collection:
result.Add(remoteMovie.Movie.Collection.Name);
result.Add(remoteMovie.Movie.MovieMetadata.Value.Collection.Name);
break;
case (int)AdditionalTags.Quality:
result.Add(remoteMovie.ParsedMovieInfo.Quality.Quality.ToString());
@@ -70,7 +70,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
result.Add(remoteMovie.Release.Indexer);
break;
case (int)AdditionalTags.Studio:
result.Add(remoteMovie.Movie.Studio);
result.Add(remoteMovie.Movie.MovieMetadata.Value.Studio);
break;
default:
throw new DownloadClientException("Unexpected additional tag ID");

View File

@@ -34,7 +34,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
protected override string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents)
{
var priority = remoteMovie.Movie.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority;
var priority = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority;
var response = _proxy.DownloadNzb(fileContents, filename, priority, Settings);

View File

@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
{
var category = Settings.MovieCategory;
var priority = remoteMovie.Movie.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority;
var priority = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority;
var addpaused = Settings.AddPaused;
var response = _proxy.DownloadNzb(fileContent, filename, category, priority, addpaused, Settings);

View File

@@ -73,7 +73,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
var setShareLimits = remoteMovie.SeedConfiguration != null && (remoteMovie.SeedConfiguration.Ratio.HasValue || remoteMovie.SeedConfiguration.SeedTime.HasValue);
var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1);
var isRecentMovie = remoteMovie.Movie.IsRecentMovie;
var isRecentMovie = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie;
var moveToTop = (isRecentMovie && Settings.RecentMoviePriority == (int)QBittorrentPriority.First) || (!isRecentMovie && Settings.OlderMoviePriority == (int)QBittorrentPriority.First);
var forceStart = (QBittorrentState)Settings.InitialState == QBittorrentState.ForceStart;
@@ -132,7 +132,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
{
var setShareLimits = remoteMovie.SeedConfiguration != null && (remoteMovie.SeedConfiguration.Ratio.HasValue || remoteMovie.SeedConfiguration.SeedTime.HasValue);
var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1);
var isRecentMovie = remoteMovie.Movie.IsRecentMovie;
var isRecentMovie = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie;
var moveToTop = (isRecentMovie && Settings.RecentMoviePriority == (int)QBittorrentPriority.First) || (!isRecentMovie && Settings.OlderMoviePriority == (int)QBittorrentPriority.First);
var forceStart = (QBittorrentState)Settings.InitialState == QBittorrentState.ForceStart;
@@ -288,7 +288,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
break;
case "forcedDL": //torrent is being downloaded, and was forced started
case "forcedDL": // torrent is being downloaded, and was forced started
case "forcedMetaDL": // torrent metadata is being forcibly downloaded
case "moving": // torrent is being moved from a folder
case "downloading": // torrent is being downloaded and data is being transferred
item.Status = DownloadItemStatus.Downloading;

View File

@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
protected override string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContent)
{
var category = Settings.MovieCategory;
var priority = remoteMovie.Movie.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority;
var priority = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority;
var response = _proxy.DownloadNzb(fileContent, filename, category, priority, Settings);

View File

@@ -194,7 +194,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
_proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings);
_proxy.SetTorrentSeedingConfiguration(hash, remoteMovie.SeedConfiguration, Settings);
var isRecentMovie = remoteMovie.Movie.IsRecentMovie;
var isRecentMovie = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie;
if ((isRecentMovie && Settings.RecentMoviePriority == (int)TransmissionPriority.First) ||
(!isRecentMovie && Settings.OlderMoviePriority == (int)TransmissionPriority.First))
@@ -210,7 +210,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
_proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings);
_proxy.SetTorrentSeedingConfiguration(hash, remoteMovie.SeedConfiguration, Settings);
var isRecentMovie = remoteMovie.Movie.IsRecentMovie;
var isRecentMovie = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie;
if ((isRecentMovie && Settings.RecentMoviePriority == (int)TransmissionPriority.First) ||
(!isRecentMovie && Settings.OlderMoviePriority == (int)TransmissionPriority.First))

View File

@@ -72,7 +72,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
{
var priority = (RTorrentPriority)(remoteMovie.Movie.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority);
var priority = (RTorrentPriority)(remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority);
_proxy.AddTorrentFromUrl(magnetLink, Settings.MovieCategory, priority, Settings.MovieDirectory, Settings);
@@ -92,7 +92,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent)
{
var priority = (RTorrentPriority)(remoteMovie.Movie.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority);
var priority = (RTorrentPriority)(remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie ? Settings.RecentMoviePriority : Settings.OlderMoviePriority);
_proxy.AddTorrentFromFile(filename, fileContent, Settings.MovieCategory, priority, Settings.MovieDirectory, Settings);

View File

@@ -64,7 +64,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
_proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings);
}
var isRecentMovie = remoteMovie.Movie.IsRecentMovie;
var isRecentMovie = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie;
if ((isRecentMovie && Settings.RecentMoviePriority == (int)UTorrentPriority.First) ||
(!isRecentMovie && Settings.OlderMoviePriority == (int)UTorrentPriority.First))
@@ -87,7 +87,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
_proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings);
}
var isRecentEpisode = remoteMovie.Movie.IsRecentMovie;
var isRecentEpisode = remoteMovie.Movie.MovieMetadata.Value.IsRecentMovie;
if ((isRecentEpisode && Settings.RecentMoviePriority == (int)UTorrentPriority.First) ||
(!isRecentEpisode && Settings.OlderMoviePriority == (int)UTorrentPriority.First))

View File

@@ -67,19 +67,19 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser
{
var movieElement = new XElement("Movie");
movieElement.Add(new XElement("id", movie.ImdbId));
movieElement.Add(new XElement("Status", movie.Status));
movieElement.Add(new XElement("id", movie.MovieMetadata.Value.ImdbId));
movieElement.Add(new XElement("Status", movie.MovieMetadata.Value.Status));
movieElement.Add(new XElement("Added", movie.Added.ToString("MM/dd/yyyy HH:mm:ss tt")));
movieElement.Add(new XElement("LockData", "false"));
movieElement.Add(new XElement("Overview", movie.Overview));
movieElement.Add(new XElement("Overview", movie.MovieMetadata.Value.Overview));
movieElement.Add(new XElement("LocalTitle", movie.Title));
movieElement.Add(new XElement("Rating", movie.Ratings.Tmdb?.Value ?? 0));
movieElement.Add(new XElement("Rating", movie.MovieMetadata.Value.Ratings.Tmdb?.Value ?? 0));
movieElement.Add(new XElement("ProductionYear", movie.Year));
movieElement.Add(new XElement("RunningTime", movie.Runtime));
movieElement.Add(new XElement("IMDB", movie.ImdbId));
movieElement.Add(new XElement("Genres", movie.Genres.Select(genre => new XElement("Genre", genre))));
movieElement.Add(new XElement("RunningTime", movie.MovieMetadata.Value.Runtime));
movieElement.Add(new XElement("IMDB", movie.MovieMetadata.Value.ImdbId));
movieElement.Add(new XElement("Genres", movie.MovieMetadata.Value.Genres.Select(genre => new XElement("Genre", genre))));
var doc = new XDocument(movieElement);
doc.Save(xw);

View File

@@ -118,9 +118,9 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
var details = new XElement("video");
details.Add(new XElement("title", movie.Title));
details.Add(new XElement("genre", string.Join(" / ", movie.Genres)));
details.Add(new XElement("description", movie.Overview));
details.Add(new XElement("length", movie.Runtime));
details.Add(new XElement("genre", string.Join(" / ", movie.MovieMetadata.Value.Genres)));
details.Add(new XElement("description", movie.MovieMetadata.Value.Overview));
details.Add(new XElement("length", movie.MovieMetadata.Value.Runtime));
doc.Add(details);
doc.Save(xw);
@@ -139,7 +139,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
return new List<ImageFileResult>();
}
var image = movie.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? movie.Images.FirstOrDefault();
var image = movie.MovieMetadata.Value.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? movie.MovieMetadata.Value.Images.FirstOrDefault();
if (image == null)
{
_logger.Trace("Failed to find suitable Movie image for movie {0}.", movie.Title);

View File

@@ -113,8 +113,8 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
var details = new XElement("details");
details.Add(new XElement("id", movie.Id));
details.Add(new XElement("title", movie.Title));
details.Add(new XElement("genre", string.Join(" / ", movie.Genres)));
details.Add(new XElement("overview", movie.Overview));
details.Add(new XElement("genre", string.Join(" / ", movie.MovieMetadata.Value.Genres)));
details.Add(new XElement("overview", movie.MovieMetadata.Value.Overview));
doc.Add(details);
doc.Save(xw);
@@ -136,7 +136,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
}
//Because we only support one image, attempt to get the Poster type, then if that fails grab the first
var image = movie.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? movie.Images.FirstOrDefault();
var image = movie.MovieMetadata.Value.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? movie.MovieMetadata.Value.Images.FirstOrDefault();
if (image == null)
{
_logger.Trace("Failed to find suitable Movie image for movie {0}.", movie.Title);

View File

@@ -123,14 +123,14 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
_logger.Debug("Generating Movie Metadata for: {0}", Path.Combine(movie.Path, movieFile.RelativePath));
var movieMetadataLanguage = (Settings.MovieMetadataLanguage == (int)Language.Original) ?
(int)movie.OriginalLanguage :
(int)movie.MovieMetadata.Value.OriginalLanguage :
Settings.MovieMetadataLanguage;
var movieTranslations = _movieTranslationsService.GetAllTranslationsForMovie(movie.Id);
var movieTranslations = _movieTranslationsService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId);
var selectedSettingsLanguage = Language.FindById(movieMetadataLanguage);
var movieTranslation = movieTranslations.FirstOrDefault(mt => mt.Language == selectedSettingsLanguage);
var credits = _creditService.GetAllCreditsForMovie(movie.Id);
var credits = _creditService.GetAllCreditsForMovieMetadata(movie.MovieMetadataId);
var watched = GetExistingWatchedStatus(movie, movieFile.RelativePath);
@@ -142,44 +142,44 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
using (var xw = XmlWriter.Create(sb, xws))
{
var doc = new XDocument();
var thumbnail = movie.Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot);
var posters = movie.Images.Where(i => i.CoverType == MediaCoverTypes.Poster);
var fanarts = movie.Images.Where(i => i.CoverType == MediaCoverTypes.Fanart);
var thumbnail = movie.MovieMetadata.Value.Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot);
var posters = movie.MovieMetadata.Value.Images.Where(i => i.CoverType == MediaCoverTypes.Poster);
var fanarts = movie.MovieMetadata.Value.Images.Where(i => i.CoverType == MediaCoverTypes.Fanart);
var details = new XElement("movie");
details.Add(new XElement("title", movieTranslation?.Title ?? movie.Title));
details.Add(new XElement("originaltitle", movie.OriginalTitle));
details.Add(new XElement("originaltitle", movie.MovieMetadata.Value.OriginalTitle));
details.Add(new XElement("sorttitle", movie.SortTitle));
details.Add(new XElement("sorttitle", movie.MovieMetadata.Value.SortTitle));
if (movie.Ratings.Tmdb?.Votes > 0 || movie.Ratings.Imdb?.Votes > 0)
if (movie.MovieMetadata.Value.Ratings.Tmdb?.Votes > 0 || movie.MovieMetadata.Value.Ratings.Imdb?.Votes > 0)
{
var setRating = new XElement("ratings");
if (movie.Ratings.Tmdb?.Votes > 0)
if (movie.MovieMetadata.Value.Ratings.Tmdb?.Votes > 0)
{
var setRatethemoviedb = new XElement("rating", new XAttribute("name", "themoviedb"), new XAttribute("max", "10"), new XAttribute("default", "true"));
setRatethemoviedb.Add(new XElement("value", movie.Ratings.Tmdb.Value));
setRatethemoviedb.Add(new XElement("votes", movie.Ratings.Tmdb.Votes));
setRatethemoviedb.Add(new XElement("value", movie.MovieMetadata.Value.Ratings.Tmdb.Value));
setRatethemoviedb.Add(new XElement("votes", movie.MovieMetadata.Value.Ratings.Tmdb.Votes));
setRating.Add(setRatethemoviedb);
}
if (movie.Ratings.Imdb?.Votes > 0)
if (movie.MovieMetadata.Value.Ratings.Imdb?.Votes > 0)
{
var setRateImdb = new XElement("rating", new XAttribute("name", "imdb"), new XAttribute("max", "10"));
setRateImdb.Add(new XElement("value", movie.Ratings.Imdb.Value));
setRateImdb.Add(new XElement("votes", movie.Ratings.Imdb.Votes));
setRateImdb.Add(new XElement("value", movie.MovieMetadata.Value.Ratings.Imdb.Value));
setRateImdb.Add(new XElement("votes", movie.MovieMetadata.Value.Ratings.Imdb.Votes));
setRating.Add(setRateImdb);
}
details.Add(setRating);
}
if (movie.Ratings?.Tmdb?.Votes > 0)
if (movie.MovieMetadata.Value.Ratings?.Tmdb?.Votes > 0)
{
details.Add(new XElement("rating", movie.Ratings.Tmdb.Value));
details.Add(new XElement("rating", movie.MovieMetadata.Value.Ratings.Tmdb.Value));
}
details.Add(new XElement("userrating"));
@@ -188,11 +188,11 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
details.Add(new XElement("outline"));
details.Add(new XElement("plot", movieTranslation?.Overview ?? movie.Overview));
details.Add(new XElement("plot", movieTranslation?.Overview ?? movie.MovieMetadata.Value.Overview));
details.Add(new XElement("tagline"));
details.Add(new XElement("runtime", movie.Runtime));
details.Add(new XElement("runtime", movie.MovieMetadata.Value.Runtime));
if (thumbnail != null)
{
@@ -221,9 +221,9 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
details.Add(fanartElement);
}
if (movie.Certification.IsNotNullOrWhiteSpace())
if (movie.MovieMetadata.Value.Certification.IsNotNullOrWhiteSpace())
{
details.Add(new XElement("mpaa", movie.Certification));
details.Add(new XElement("mpaa", movie.MovieMetadata.Value.Certification));
}
details.Add(new XElement("playcount"));
@@ -237,25 +237,25 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
uniqueId.SetAttributeValue("default", true);
details.Add(uniqueId);
if (movie.ImdbId.IsNotNullOrWhiteSpace())
if (movie.MovieMetadata.Value.ImdbId.IsNotNullOrWhiteSpace())
{
var imdbId = new XElement("uniqueid", movie.ImdbId);
var imdbId = new XElement("uniqueid", movie.MovieMetadata.Value.ImdbId);
imdbId.SetAttributeValue("type", "imdb");
details.Add(imdbId);
}
foreach (var genre in movie.Genres)
foreach (var genre in movie.MovieMetadata.Value.Genres)
{
details.Add(new XElement("genre", genre));
}
details.Add(new XElement("country"));
if (movie.Collection?.Name != null)
if (movie.MovieMetadata.Value.Collection?.Name != null)
{
var setElement = new XElement("set");
setElement.Add(new XElement("name", movie.Collection.Name));
setElement.Add(new XElement("name", movie.MovieMetadata.Value.Collection.Name));
setElement.Add(new XElement("overview"));
details.Add(setElement);
@@ -284,16 +284,16 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
}
}
if (movie.InCinemas.HasValue)
if (movie.MovieMetadata.Value.InCinemas.HasValue)
{
details.Add(new XElement("premiered", movie.InCinemas.Value.ToString("yyyy-MM-dd")));
details.Add(new XElement("premiered", movie.MovieMetadata.Value.InCinemas.Value.ToString("yyyy-MM-dd")));
}
details.Add(new XElement("year", movie.Year));
details.Add(new XElement("studio", movie.Studio));
details.Add(new XElement("studio", movie.MovieMetadata.Value.Studio));
details.Add(new XElement("trailer", "plugin://plugin.video.youtube/play/?video_id=" + movie.YouTubeTrailerId));
details.Add(new XElement("trailer", "plugin://plugin.video.youtube/play/?video_id=" + movie.MovieMetadata.Value.YouTubeTrailerId));
if (movieFile.MediaInfo != null)
{
@@ -369,10 +369,10 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
if (Settings.MovieMetadataURL)
{
xmlResult += "https://www.themoviedb.org/movie/" + movie.TmdbId;
xmlResult += "https://www.themoviedb.org/movie/" + movie.MovieMetadata.Value.TmdbId;
xmlResult += Environment.NewLine;
xmlResult += "https://www.imdb.com/title/" + movie.ImdbId;
xmlResult += "https://www.imdb.com/title/" + movie.MovieMetadata.Value.ImdbId;
xmlResult += Environment.NewLine;
}
@@ -393,7 +393,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
private IEnumerable<ImageFileResult> ProcessMovieImages(Movie movie)
{
foreach (var image in movie.Images)
foreach (var image in movie.MovieMetadata.Value.Images)
{
var source = _mediaCoverService.GetCoverPath(movie.Id, image.CoverType);
var destination = image.CoverType.ToString().ToLowerInvariant() + Path.GetExtension(source);

View File

@@ -21,7 +21,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
public override HealthCheck Check()
{
var deletedMovie = _movieService.GetAllMovies().Where(v => v.Status == MovieStatusType.Deleted).ToList();
var deletedMovie = _movieService.GetAllMovies().Where(v => v.MovieMetadata.Value.Status == MovieStatusType.Deleted).ToList();
if (deletedMovie.Empty())
{
@@ -40,12 +40,12 @@ namespace NzbDrone.Core.HealthCheck.Checks
public bool ShouldCheckOnEvent(MoviesDeletedEvent message)
{
return message.Movies.Any(m => m.Status == MovieStatusType.Deleted);
return message.Movies.Any(m => m.MovieMetadata.Value.Status == MovieStatusType.Deleted);
}
public bool ShouldCheckOnEvent(MovieUpdatedEvent message)
{
return message.Movie.Status == MovieStatusType.Deleted;
return message.Movie.MovieMetadata.Value.Status == MovieStatusType.Deleted;
}
}
}

View File

@@ -1,4 +1,4 @@
using Dapper;
using Dapper;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Housekeeping.Housekeepers
@@ -19,9 +19,9 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
mapper.Execute(@"DELETE FROM ""AlternativeTitles""
WHERE ""Id"" IN (
SELECT ""AlternativeTitles"".""Id"" FROM ""AlternativeTitles""
LEFT OUTER JOIN ""Movies""
ON ""AlternativeTitles"".""MovieId"" = ""Movies"".""Id""
WHERE ""Movies"".""Id"" IS NULL)");
LEFT OUTER JOIN ""MovieMetadata""
ON ""AlternativeTitles"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
WHERE ""MovieMetadata"".""Id"" IS NULL)");
}
}
}

View File

@@ -19,9 +19,9 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
mapper.Execute(@"DELETE FROM ""Credits""
WHERE ""Id"" IN (
SELECT ""Credits"".""Id"" FROM ""Credits""
LEFT OUTER JOIN ""Movies""
ON ""Credits"".""MovieId"" = ""Movies"".""Id""
WHERE ""Movies"".""Id"" IS NULL)");
LEFT OUTER JOIN ""MovieMetadata""
ON ""Credits"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
WHERE ""MovieMetadata"".""Id"" IS NULL)");
}
}
}

View File

@@ -0,0 +1,28 @@
using Dapper;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Housekeeping.Housekeepers
{
public class CleanupOrphanedMovieMetadata : IHousekeepingTask
{
private readonly IMainDatabase _database;
public CleanupOrphanedMovieMetadata(IMainDatabase database)
{
_database = database;
}
public void Clean()
{
using (var mapper = _database.OpenConnection())
{
mapper.Execute(@"DELETE FROM ""MovieMetadata""
WHERE ""Id"" IN (
SELECT ""MovieMetadata"".""Id"" FROM ""MovieMetadata""
LEFT OUTER JOIN ""Movies"" ON ""Movies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
LEFT OUTER JOIN ""ImportListMovies"" ON ""ImportListMovies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
WHERE ""Movies"".""Id"" IS NULL AND ""ImportListMovies"".""Id"" IS NULL)");
}
}
}
}

View File

@@ -19,9 +19,9 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
mapper.Execute(@"DELETE FROM ""MovieTranslations""
WHERE ""Id"" IN (
SELECT ""MovieTranslations"".""Id"" FROM ""MovieTranslations""
LEFT OUTER JOIN ""Movies""
ON ""MovieTranslations"".""MovieId"" = ""Movies"".""Id""
WHERE ""Movies"".""Id"" IS NULL)");
LEFT OUTER JOIN ""MovieMetadata""
ON ""MovieTranslations"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
WHERE ""MovieMetadata"".""Id"" IS NULL)");
}
}
}

View File

@@ -24,18 +24,21 @@ namespace NzbDrone.Core.ImportLists
private readonly IImportListStatusService _importListStatusService;
private readonly IImportListMovieService _listMovieService;
private readonly ISearchForNewMovie _movieSearch;
private readonly IMovieMetadataService _movieMetadataService;
private readonly Logger _logger;
public FetchAndParseImportListService(IImportListFactory importListFactory,
IImportListStatusService importListStatusService,
IImportListMovieService listMovieService,
ISearchForNewMovie movieSearch,
IMovieMetadataService movieMetadataService,
Logger logger)
{
_importListFactory = importListFactory;
_importListStatusService = importListStatusService;
_listMovieService = listMovieService;
_movieSearch = movieSearch;
_movieMetadataService = movieMetadataService;
_logger = logger;
}
@@ -173,33 +176,16 @@ namespace NzbDrone.Core.ImportLists
private ImportListMovie MapMovieReport(ImportListMovie report)
{
var mappedMovie = _movieSearch.MapMovieToTmdbMovie(new Movie { Title = report.Title, TmdbId = report.TmdbId, ImdbId = report.ImdbId, Year = report.Year });
var mappedMovie = _movieSearch.MapMovieToTmdbMovie(new MovieMetadata { Title = report.Title, TmdbId = report.TmdbId, ImdbId = report.ImdbId, Year = report.Year });
_movieMetadataService.Upsert(mappedMovie);
var mappedListMovie = new ImportListMovie { ListId = report.ListId };
if (mappedMovie != null)
{
mappedListMovie.TmdbId = mappedMovie.TmdbId;
mappedListMovie.ImdbId = mappedMovie.ImdbId;
mappedListMovie.Title = mappedMovie.Title;
mappedListMovie.SortTitle = mappedMovie?.SortTitle;
mappedListMovie.Year = mappedMovie.Year;
mappedListMovie.Overview = mappedMovie.Overview;
mappedListMovie.Ratings = mappedMovie.Ratings;
mappedListMovie.Studio = mappedMovie.Studio;
mappedListMovie.Certification = mappedMovie.Certification;
mappedListMovie.Collection = mappedMovie.Collection;
mappedListMovie.Status = mappedMovie.Status;
mappedListMovie.Images = mappedMovie.Images;
mappedListMovie.Website = mappedMovie.Website;
mappedListMovie.YouTubeTrailerId = mappedMovie.YouTubeTrailerId;
mappedListMovie.Translations = mappedMovie.Translations;
mappedListMovie.InCinemas = mappedMovie.InCinemas;
mappedListMovie.PhysicalRelease = mappedMovie.PhysicalRelease;
mappedListMovie.DigitalRelease = mappedMovie.DigitalRelease;
mappedListMovie.Genres = mappedMovie.Genres;
mappedListMovie.Runtime = mappedMovie.Runtime;
mappedListMovie.OriginalTitle = mappedMovie.OriginalTitle;
mappedListMovie.MovieMetadata = mappedMovie;
mappedListMovie.MovieMetadataId = mappedMovie.Id;
}
return mappedListMovie;

View File

@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.Translations;
namespace NzbDrone.Core.ImportLists.ImportListMovies
{
@@ -10,37 +7,35 @@ namespace NzbDrone.Core.ImportLists.ImportListMovies
{
public ImportListMovie()
{
Images = new List<MediaCover.MediaCover>();
Genres = new List<string>();
Translations = new List<MovieTranslation>();
Ratings = new Ratings();
MovieMetadata = new MovieMetadata();
}
public int TmdbId { get; set; }
public string ImdbId { get; set; }
public string Title { get; set; }
public string SortTitle { get; set; }
public MovieStatusType Status { get; set; }
public string Overview { get; set; }
public DateTime? LastInfoSync { get; set; }
public int Runtime { get; set; }
public List<MediaCover.MediaCover> Images { get; set; }
public string Website { get; set; }
public int Year { get; set; }
public Ratings Ratings { get; set; }
public List<string> Genres { get; set; }
public MovieCollection Collection { get; set; }
public string Certification { get; set; }
public DateTime? InCinemas { get; set; }
public DateTime? PhysicalRelease { get; set; }
public DateTime? DigitalRelease { get; set; }
public List<MovieTranslation> Translations { get; set; }
public string YouTubeTrailerId { get; set; }
public string Studio { get; set; }
public string OriginalTitle { get; set; }
public int ListId { get; set; }
public int MovieMetadataId { get; set; }
public LazyLoaded<MovieMetadata> MovieMetadata { get; set; }
public string Title
{
get { return MovieMetadata.Value.Title; }
set { MovieMetadata.Value.Title = value; }
}
public int TmdbId
{
get { return MovieMetadata.Value.TmdbId; }
set { MovieMetadata.Value.TmdbId = value; }
}
public string ImdbId
{
get { return MovieMetadata.Value.ImdbId; }
set { MovieMetadata.Value.ImdbId = value; }
}
public int Year
{
get { return MovieMetadata.Value.Year; }
set { MovieMetadata.Value.Year = value; }
}
}
}

View File

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

View File

@@ -48,11 +48,6 @@ namespace NzbDrone.Core.ImportLists.Radarr
{
TmdbId = remoteMovie.TmdbId,
Title = remoteMovie.Title,
SortTitle = remoteMovie.SortTitle,
Overview = remoteMovie.Overview,
Images = remoteMovie.Images.Select(x => MapImage(x, Settings.BaseUrl)).ToList(),
PhysicalRelease = remoteMovie.PhysicalRelease,
InCinemas = remoteMovie.InCinemas,
Year = remoteMovie.Year
});
}

View File

@@ -36,10 +36,7 @@ namespace NzbDrone.Core.ImportLists.TMDb
var movie = new ImportListMovie
{
TmdbId = movieResult.Id,
Overview = movieResult.Overview,
Title = movieResult.Title,
SortTitle = Parser.Parser.NormalizeTitle(movieResult.Title),
Images = new List<MediaCover.MediaCover>(),
};
if (movieResult.ReleaseDate.IsNotNullOrWhiteSpace())
@@ -48,8 +45,6 @@ namespace NzbDrone.Core.ImportLists.TMDb
movie.Year = releaseDate.Year;
}
movie.Images.AddIfNotNull(MapPosterImage(movieResult.PosterPath));
return movie;
}

View File

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

View File

@@ -24,9 +24,9 @@ namespace NzbDrone.Core.Indexers.FileList
{
var pageableRequests = new IndexerPageableRequestChain();
if (searchCriteria.Movie.ImdbId.IsNotNullOrWhiteSpace())
if (searchCriteria.Movie.MovieMetadata.Value.ImdbId.IsNotNullOrWhiteSpace())
{
pageableRequests.Add(GetRequest("search-torrents", string.Format("&type=imdb&query={0}", searchCriteria.Movie.ImdbId)));
pageableRequests.Add(GetRequest("search-torrents", string.Format("&type=imdb&query={0}", searchCriteria.Movie.MovieMetadata.Value.ImdbId)));
}
else
{

View File

@@ -35,12 +35,12 @@ namespace NzbDrone.Core.Indexers.HDBits
private bool TryAddSearchParameters(TorrentQuery query, SearchCriteriaBase searchCriteria)
{
if (searchCriteria.Movie.ImdbId.IsNullOrWhiteSpace())
if (searchCriteria.Movie.MovieMetadata.Value.ImdbId.IsNullOrWhiteSpace())
{
return false;
}
var imdbId = int.Parse(searchCriteria.Movie.ImdbId.Substring(2));
var imdbId = int.Parse(searchCriteria.Movie.MovieMetadata.Value.ImdbId.Substring(2));
if (imdbId != 0)
{

View File

@@ -115,8 +115,8 @@ namespace NzbDrone.Core.Indexers.Newznab
private void AddMovieIdPageableRequests(IndexerPageableRequestChain chain, int maxPages, IEnumerable<int> categories, SearchCriteriaBase searchCriteria)
{
var includeTmdbSearch = SupportsTmdbSearch && searchCriteria.Movie.TmdbId > 0;
var includeImdbSearch = SupportsImdbSearch && searchCriteria.Movie.ImdbId.IsNotNullOrWhiteSpace();
var includeTmdbSearch = SupportsTmdbSearch && searchCriteria.Movie.MovieMetadata.Value.TmdbId > 0;
var includeImdbSearch = SupportsImdbSearch && searchCriteria.Movie.MovieMetadata.Value.ImdbId.IsNotNullOrWhiteSpace();
if (SupportsAggregatedIdSearch && (includeTmdbSearch || includeImdbSearch))
{
@@ -124,12 +124,12 @@ namespace NzbDrone.Core.Indexers.Newznab
if (includeTmdbSearch)
{
ids += "&tmdbid=" + searchCriteria.Movie.TmdbId;
ids += "&tmdbid=" + searchCriteria.Movie.MovieMetadata.Value.TmdbId;
}
if (includeImdbSearch)
{
ids += "&imdbid=" + searchCriteria.Movie.ImdbId.Substring(2);
ids += "&imdbid=" + searchCriteria.Movie.MovieMetadata.Value.ImdbId.Substring(2);
}
chain.Add(GetPagedRequests(maxPages, categories, "movie", ids));
@@ -141,14 +141,14 @@ namespace NzbDrone.Core.Indexers.Newznab
chain.Add(GetPagedRequests(maxPages,
categories,
"movie",
string.Format("&tmdbid={0}", searchCriteria.Movie.TmdbId)));
string.Format("&tmdbid={0}", searchCriteria.Movie.MovieMetadata.Value.TmdbId)));
}
else if (includeImdbSearch)
{
chain.Add(GetPagedRequests(maxPages,
categories,
"movie",
string.Format("&imdbid={0}", searchCriteria.Movie.ImdbId.Substring(2))));
string.Format("&imdbid={0}", searchCriteria.Movie.MovieMetadata.Value.ImdbId.Substring(2))));
}
}

View File

@@ -29,9 +29,9 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
{
var pageableRequests = new IndexerPageableRequestChain();
if (searchCriteria.Movie.ImdbId.IsNotNullOrWhiteSpace())
if (searchCriteria.Movie.MovieMetadata.Value.ImdbId.IsNotNullOrWhiteSpace())
{
pageableRequests.Add(GetRequest(searchCriteria.Movie.ImdbId));
pageableRequests.Add(GetRequest(searchCriteria.Movie.MovieMetadata.Value.ImdbId));
}
else if (searchCriteria.Movie.Year > 0)
{

View File

@@ -87,11 +87,11 @@ namespace NzbDrone.Core.Indexers.Rarbg
requestBuilder.AddQueryParam("mode", "search");
if (searchCriteria.Movie.ImdbId.IsNotNullOrWhiteSpace())
if (searchCriteria.Movie.MovieMetadata.Value.ImdbId.IsNotNullOrWhiteSpace())
{
requestBuilder.AddQueryParam("search_imdb", searchCriteria.Movie.ImdbId);
requestBuilder.AddQueryParam("search_imdb", searchCriteria.Movie.MovieMetadata.Value.ImdbId);
}
else if (searchCriteria.Movie.TmdbId > 0)
else if (searchCriteria.Movie.MovieMetadata.Value.TmdbId > 0)
{
requestBuilder.AddQueryParam("search_themoviedb", searchCriteria.Movie.TmdbId);
}

View File

@@ -212,6 +212,7 @@ namespace NzbDrone.Core.Jobs
_scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, lastExecution, message.Command.StartedAt.Value);
_cache.Find(scheduledTask.TypeName).LastExecution = lastExecution;
_cache.Find(scheduledTask.TypeName).LastStartTime = message.Command.StartedAt.Value;
}
}

View File

@@ -269,7 +269,7 @@
"Size": "Koko",
"SuggestTranslationChange": "Ehdota käännösmuutosta",
"Queued": "Jonossa",
"TMDb": "TMDb",
"TMDb": "TMDB",
"UnableToLoadAltTitle": "Vaihtoehtoisten nimikkeiden lataus epäonnistui.",
"Released": "Julkaistu",
"ReleasedMsg": "Elokuva julkaistaan",

View File

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

View File

@@ -1 +0,0 @@
{}

View File

@@ -122,7 +122,7 @@
"ListExclusions": "Uitzonderingenlijst",
"Languages": "Talen",
"Language": "Taal",
"ShowAdvanced": "Toon Gevorderd",
"ShowAdvanced": "Toon Geavanceerd",
"RootFolderCheckSingleMessage": "Ontbrekende hoofdmap: {0}",
"RSSSync": "RSS Sync.",
"IndexerSearchCheckNoInteractiveMessage": "Geen indexeerders beschikbaar met \"Interactief Zoeken\" ingeschakeld, Radarr zal geen interactieve zoekopdrachten uitvoeren",
@@ -271,7 +271,7 @@
"ShowSearch": "Toon Zoeken",
"ShowQualityProfile": "Toon Kwaliteitsprofielen",
"ShowPath": "Toon Pad",
"ShowMonitored": "Toon Bewaakte",
"ShowMonitored": "Toon Gemonitorde",
"ShowDateAdded": "Toon Datum Toegevoegd",
"SettingsWeekColumnHeaderHelpText": "Wordt getoond boven elke kolom wanneer de actieve weergave Week is",
"SettingsWeekColumnHeader": "Week Kolom Koptekst",
@@ -1083,6 +1083,24 @@
"SelectLanguages": "Selecteer Taal",
"Rating": "Waardering",
"List": "Lijst",
"Filters": "Filter",
"RemotePath": "Extern Pad"
"Filters": "Filters",
"RemotePath": "Extern Pad",
"SelectReleaseGroup": "Selecteer Release Groep",
"SetReleaseGroup": "Stel Release Groep in",
"Auto": "Automatisch",
"AnnouncedMsg": "Film is aangekondigd",
"ClickToChangeReleaseGroup": "Klik om de releasegroep te wijzigen",
"Duration": "Duur",
"IndexerDownloadClientHelpText": "Specificeer welke download cliënt wordt gebruikt voor deze indexer",
"IndexerTagHelpText": "Gebruik deze indexer alleen voor films met ten minste één overeenkomende tag. Laat leeg om te gebruiken met alle films.",
"Letterboxd": "Letterboxd",
"ManualImportSetReleaseGroup": "Handmatig importeren - Vrijgavegroep instellen",
"Never": "Nooit",
"OnApplicationUpdate": "Bij applicatie update",
"OnApplicationUpdateHelpText": "Bij applicatie update",
"OriginalLanguage": "Originele taal",
"OriginalTitle": "Originele titel",
"Database": "Databasis",
"ImdbRating": "IMDb beoordeling",
"ImdbVotes": "IMDb stemmen"
}

View File

@@ -19,7 +19,7 @@
"IndexerStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas",
"IndexersSettingsSummary": "Indexadores e restrições de lançamento",
"IndexerSettings": "Configurações do indexador",
"IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a Pesquisa interativa ativada, o Radarr não fornecerá nenhum resultado de pesquisa interativa",
"IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a pesquisa interativa ativada, o Radarr não fornecerá nenhum resultado de pesquisa interativa",
"IndexerSearchCheckNoAvailableIndexersMessage": "Todos os indexadores com capacidade de pesquisa estão temporariamente indisponíveis devido a erros recentes do indexador",
"IndexerSearchCheckNoAutomaticMessage": "Nenhum indexador disponível com a Pesquisa automática habilitada, o Radarr não fornecerá nenhum resultado de pesquisa automática",
"Indexers": "Indexadores",
@@ -327,7 +327,7 @@
"CertificationCountryHelpText": "Selecione o país para as certificações de filmes",
"CertificationCountry": "País da certificação",
"Certification": "Certificação",
"CertificateValidationHelpText": "Altere como a validação de certificação HTTPS estrita é. Não mude a menos que você entenda os riscos.",
"CertificateValidationHelpText": "Mudar o quão rigorosa é a validação de certificação HTTPS. Não mude a menos que você entenda os riscos.",
"CertificateValidation": "Validação do Certificado",
"Cast": "Elenco",
"CantFindMovie": "Por que não consigo encontrar meu filme?",
@@ -341,7 +341,7 @@
"BranchUpdateMechanism": "Ramificação usada pelo mecanismo de atualização externo",
"BranchUpdate": "Ramificação para atualização do Radarr",
"Branch": "Ramo",
"BindAddressHelpText": "Endereço IPv4 válido ou '*' para todas as interfaces",
"BindAddressHelpText": "Endereço IPv4 Válido ou '*' para todas as interfaces",
"BindAddress": "Fixar Endereço",
"BeforeUpdate": "Antes da atualização",
"Backups": "Backups",
@@ -437,7 +437,7 @@
"LowerCase": "Minúsculas",
"LookingForReleaseProfiles2": "em vez disso.",
"LookingForReleaseProfiles1": "Procurando pelos perfis de versões? Tente",
"Logs": "Logs",
"Logs": "Registros",
"LogOnly": "Somente log",
"LogLevelTraceHelpTextWarning": "O registro de rastreamento deve ser ativado apenas temporariamente",
"LogLevel": "Nível do log",
@@ -529,7 +529,7 @@
"MovieFiles": "Arquivos do filme",
"MovieExcludedFromAutomaticAdd": "Filme excluído da adição automática",
"MovieEditor": "Editor de filme",
"MovieDetailsPreviousMovie": "Detalhes do filme: filme anterior",
"MovieDetailsPreviousMovie": "Detalhes do Filme: Filme Anterior",
"MovieDetailsNextMovie": "Detalhes do filme: próximo filme",
"MovieChat": "Bate-papo sobre o filme",
"MovieAlreadyExcluded": "Filme já excluído",
@@ -562,7 +562,7 @@
"YesCancel": "Sim, cancelar",
"YesMoveFiles": "Sim, Mover os Arquivos",
"YouCanAlsoSearch": "Você também pode pesquisar usando TMDb ID ou IMDb ID de um filme. Por exemplo: `tmdb: 71663`",
"NoMatchFound": "Nenhuma correspondência encontrada",
"NoMatchFound": "Nenhuma correspondência encontrada!",
"NoLogFiles": "Sem arquivos de log",
"NoListRecommendations": "Não foram encontrados itens da lista ou recomendações. Para começar, adicione um novo filme, importe alguns existentes ou adicione uma lista.",
"NoLinks": "Sem Links",
@@ -584,7 +584,7 @@
"Script": "Script",
"RSSSyncIntervalHelpTextWarning": "Isso se aplicará a todos os indexadores, siga as regras estabelecidas por eles",
"RootFolderCheckSingleMessage": "Pasta raiz ausente: {0}",
"RootFolderCheckMultipleMessage": "Várias pastas raiz estão ausentes: {0}",
"RootFolderCheckMultipleMessage": "Estão faltando várias pastas raiz: {0}",
"RetryingDownloadInterp": "Tentando novamente o download {0} em {1}",
"RetentionHelpText": "Apenas Usenet: use 0 para definir para retenção ilimitada",
"RestartReloadNote": "Observação: o Radarr reiniciará automaticamente e recarregará a interface durante o processo de restauração.",
@@ -648,7 +648,7 @@
"TableOptionsColumnsMessage": "Escolha quais colunas são visíveis e em que ordem aparecem",
"TableOptions": "Opções da tabela",
"Table": "Tabela",
"SystemTimeCheckMessage": "A hora do sistema está errada por mais de 1 dia. As tarefas agendadas podem não funcionar corretamente até que a hora seja corrigida",
"SystemTimeCheckMessage": "A hora do sistema está desligada por mais de 1 dia. As tarefas agendadas podem não ser executadas corretamente até que a hora seja corrigida",
"System": "Sistema",
"Sunday": "Domingo",
"SuggestTranslationChange": "Sugerir alteração para a tradução",
@@ -705,8 +705,8 @@
"SettingsShowRelativeDates": "Mostrar datas relativas",
"SettingsShortDateFormat": "Formato curto da data",
"SettingsRuntimeFormat": "Formato da duração",
"SettingsRemotePathMappingRemotePathHelpText": "Caminho raiz para o diretório que o Cliente de download acessa",
"SettingsRemotePathMappingRemotePath": "Caminho remoto",
"SettingsRemotePathMappingRemotePathHelpText": "Caminho raiz para o diretório que o Cliente de Download acessa",
"SettingsRemotePathMappingRemotePath": "Caminho Remoto",
"SettingsRemotePathMappingLocalPathHelpText": "Caminho que o Radarr deve usar para acessar o caminho remoto localmente",
"SettingsRemotePathMappingHostHelpText": "O mesmo host que você especificou para o Cliente de download remoto",
"SettingsRemotePathMappingLocalPath": "Caminho local",
@@ -733,7 +733,7 @@
"SearchMissing": "Pesquisar ausentes",
"SearchForMovie": "Pesquisar filme",
"SearchForMissing": "Pesquisar ausentes",
"SearchFiltered": "Pesquisar filtrados",
"SearchFiltered": "Pesquisa filtrada",
"SearchFailedPleaseTryAgainLater": "A pesquisa falhou, tente novamente mais tarde.",
"SearchCutoffUnmet": "Pesquisar Limite não atingido",
"SearchAll": "Pesquisar tudo",
@@ -851,7 +851,7 @@
"QualitySettings": "Configurações de qualidade",
"QualityProfiles": "Perfis de qualidade",
"QualityProfileInUse": "Não é possível excluir um perfil de qualidade que está vinculado a um filme",
"QualityProfileDeleteConfirm": "Tem certeza que deseja excluir o perfil de qualidade {0}?",
"QualityProfileDeleteConfirm": "Tem certeza que deseja excluir o perfil de qualidade {0}",
"QualityProfile": "Perfil de qualidade",
"QualityOrLangCutoffHasNotBeenMet": "Limite de qualidade ou de idioma não atingido",
"QualityLimitsHelpText": "Os limites são ajustados automaticamente para o tempo de execução do filme.",
@@ -965,10 +965,10 @@
"UpdateSelected": "Atualizar selecionado(s)",
"UpdateScriptPathHelpText": "Caminho para um script personalizado que usa um pacote de atualização extraído e lida com o restante do processo de atualização",
"Updates": "Atualizações",
"UpdateMechanismHelpText": "Usar o atualizador embutido do Radarr ou um script",
"UpdateMechanismHelpText": "Usar o atualizador interno do Radarr ou um script",
"UpdateCheckUINotWritableMessage": "Não é possível instalar a atualização porque a pasta de interface do usuário '{0}' não é gravável pelo usuário '{1}'.",
"UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização \"{0}\" está em uma pasta de transposição de aplicativos.",
"UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização \"{0}\" não pode ser acessada pelo usuário \"{1}\".",
"UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' está em uma pasta App Translocation.",
"UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' não pode ser gravada pelo usuário '{1}'.",
"UpdateAutomaticallyHelpText": "Baixar e instalar atualizações automaticamente. Você ainda poderá instalar a partir de Sistema: Atualizações",
"UpdateAll": "Atualizar tudo",
"UnselectAll": "Deselecionar Todos",
@@ -1016,7 +1016,7 @@
"UnableToAddANewQualityProfilePleaseTryAgain": "Não foi possível adicionar um novo perfil de qualidade, tente novamente.",
"UnableToAddANewListPleaseTryAgain": "Não foi possível adicionar uma nova lista, tente novamente.",
"UnableToAddANewListExclusionPleaseTryAgain": "Não foi possível adicionar uma nova exclusão da lista, tente novamente.",
"UISettingsSummary": "Opções de calendário, data e cor para deficientes",
"UISettingsSummary": "Opções de calendário, data e cores prejudicadas",
"Trigger": "Acionador",
"Trakt": "Trakt",
"Trailer": "Trailer",
@@ -1049,20 +1049,20 @@
"DeleteFileLabel": "Excluir {0} arquivos do filme",
"UpdateAvailable": "Nova atualização está disponível",
"RemotePathMappingCheckFilesGenericPermissions": "O cliente de download {0} relatou arquivos em {1}, mas o Radarr não pode ver esse diretório. Pode ser necessário ajustar as permissões da pasta.",
"RemotePathMappingCheckRemoteDownloadClient": "O cliente de download remoto {0} relatou arquivos em {1}, mas esse diretório parece não existir. Mapeamento de caminho remoto provavelmente ausente.",
"RemotePathMappingCheckRemoteDownloadClient": "O cliente de download remoto {0} relatou arquivos em {1}, mas este diretório parece não existir. Provavelmente faltando mapeamento de caminho remoto.",
"RemotePathMappingCheckFolderPermissions": "O Radarr pode ver, mas não pode acessar o diretório de download {0}. Provável erro de permissões.",
"RemotePathMappingCheckFilesLocalWrongOSPath": "O cliente de download local {0} relatou arquivos em {1}, mas este não é um caminho {2} válido. Revise as configurações do cliente de download.",
"RemotePathMappingCheckFilesBadDockerPath": "Você está usando o Docker; o cliente de download {0} relatou arquivos em {1}, mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e as configurações do cliente de download.",
"RemotePathMappingCheckFilesWrongOSPath": "O cliente de download remoto {0} relatou arquivos em {1}, mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e as configurações do cliente de download.",
"RemotePathMappingCheckFilesLocalWrongOSPath": "O cliente de download local {0} relatou arquivos em {1}, mas este não é um caminho {2} válido. Revise as configurações do seu cliente de download.",
"RemotePathMappingCheckFilesBadDockerPath": "Você está usando o docker; baixe os arquivos relatados do cliente {0} em {1}, mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e baixe as configurações do cliente.",
"RemotePathMappingCheckFilesWrongOSPath": "O cliente de download remoto {0} relatou arquivos em {1}, mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e baixe as configurações do cliente.",
"RemotePathMappingCheckImportFailed": "O Radarr não conseguiu importar um filme. Verifique os logs para saber mais.",
"RemotePathMappingCheckFileRemoved": "O arquivo {0} foi removido durante o processamento.",
"RemotePathMappingCheckFileRemoved": "O arquivo {0} foi removido no meio do processamento.",
"RemotePathMappingCheckDownloadPermissions": "O Radarr pode ver, mas não pode acessar o filme baixado {0}. Provável erro de permissões.",
"RemotePathMappingCheckGenericPermissions": "O cliente de download {0} coloca os downloads em {1}, mas o Radarr não pode ver esse diretório. Pode ser necessário ajustar as permissões da pasta.",
"RemotePathMappingCheckWrongOSPath": "O cliente de download remoto {0} coloca downloads em {1}, mas esse não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e as configurações do cliente de download.",
"RemotePathMappingCheckLocalWrongOSPath": "O cliente de download local {0} coloca downloads em {1}, mas esse não é um caminho {2} válido. Revise as configurações do cliente de download.",
"RemotePathMappingCheckLocalFolderMissing": "O cliente de download remoto {0} coloca downloads em {1}, mas esse diretório parece não existir. Mapeamento de caminho remoto está provavelmente ausente ou incorreto.",
"RemotePathMappingCheckDockerFolderMissing": "Você está usando o Docker; o cliente de download {0} coloca downloads em {1}, mas esse diretório não parece existir no contêiner. Revise seus mapeamentos de caminho remoto e as configurações de volume do contêiner.",
"RemotePathMappingCheckBadDockerPath": "Você está usando o Docker; o cliente de download {0} coloca downloads em {1}, mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e as configurações do cliente de download.",
"RemotePathMappingCheckWrongOSPath": "O cliente de download remoto {0} coloca downloads em {1}, mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e baixe as configurações do cliente.",
"RemotePathMappingCheckLocalWrongOSPath": "O cliente de download local {0} coloca downloads em {1}, mas este não é um caminho {2} válido. Revise as configurações do seu cliente de download.",
"RemotePathMappingCheckLocalFolderMissing": "O cliente de download remoto {0} coloca downloads em {1}, mas esse diretório parece não existir. Mapeamento de caminho remoto provavelmente ausente ou incorreto.",
"RemotePathMappingCheckDockerFolderMissing": "Você está usando o docker; cliente de download {0} coloca downloads em {1}, mas esse diretório parece não existir dentro do contêiner. Revise seus mapeamentos de caminho remoto e configurações de volume de contêiner.",
"RemotePathMappingCheckBadDockerPath": "Você está usando o docker; cliente de download {0} coloca downloads em {1} mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e baixe as configurações do cliente.",
"ImportListMultipleMissingRoots": "Faltam várias pastas raiz para listas de importação: {0}",
"ImportListMissingRoot": "Pasta raiz ausente para lista(s) de importação: {0}",
"BypassDelayIfHighestQualityHelpText": "Ignorar o atraso quando a versão tiver a qualidade mais alta habilitada no perfil de qualidade com o protocolo preferido",
@@ -1100,7 +1100,7 @@
"ClickToChangeReleaseGroup": "Clique para mudar o grupo do lançamento",
"Filters": "Filtros",
"RemotePath": "Caminho Remoto",
"SizeLimit": "Limite de Tamanho",
"SizeLimit": "Tamanho Limite",
"ImdbRating": "Avaliação no IMDb",
"TmdbRating": "Avaliação no TMDb",
"TmdbVotes": "Votos no TMDb",

View File

@@ -214,5 +214,6 @@
"DeleteIndexerMessageText": "Ви впевнені, що хочете видалити тег {0} ?",
"DeleteListMessageText": "Ви впевнені, що хочете видалити тег {0} ?",
"DeleteNotificationMessageText": "Ви впевнені, що хочете видалити клієнт завантаження '{0}'?",
"DeleteTagMessageText": "Ви впевнені, що хочете видалити тег {0} ?"
"DeleteTagMessageText": "Ви впевнені, що хочете видалити тег {0} ?",
"ExportCustomFormat": "Додати свій формат"
}

View File

@@ -146,12 +146,12 @@
"ShowRatings": "显示评分",
"ShowPath": "显示路径",
"ShownClickToHide": "已显示,点击隐藏",
"ShowMovieInformationHelpText": "显示影片风格和认证",
"ShowMovieInformationHelpText": "显示影片风格和分级",
"ShowMovieInformation": "显示影片信息",
"ShowMonitored": "显示监控中的影片",
"ShowGenres": "显示风格",
"ShowDateAdded": "显示添加日期",
"ShowCertification": "显示认证",
"ShowCertification": "显示分级",
"ShowAsAllDayEvents": "作为全天事件显示",
"ShowAdvanced": "显示高级设置",
"SettingsTimeFormat": "时间格式",
@@ -550,7 +550,7 @@
"ChangeFileDate": "修改文件日期",
"CertificationCountryHelpText": "选择电影分级国别",
"CertificationCountry": "电影分级国别",
"Certification": "认证",
"Certification": "分级",
"CancelProcessing": "取消进行中",
"BuiltIn": "内置的",
"BeforeUpdate": "更新前",
@@ -560,7 +560,7 @@
"AsAllDayHelpText": "事件将以全天事件的形式显示在日历中",
"AreYouSureYouWantToRemoveSelectedItemsFromQueue": "确认从队列中删除已选择项目?",
"AreYouSureYouWantToDeleteThisImportListExclusion": "确定删除导入排除列表?",
"AppDataLocationHealthCheckMessage": "更新将无法阻止在更新时删除应用数据",
"AppDataLocationHealthCheckMessage": "更新将无法阻止在更新时删除 AppData",
"Announced": "已公布",
"Analytics": "分析",
"AllMoviesInPathHaveBeenImported": "在 {0} 中的所有电影已被导入",
@@ -995,7 +995,7 @@
"MovieAlreadyExcluded": "影片已排除",
"Mode": "模式",
"MinimumLimits": "最小限制",
"MinimumAgeHelpText": "仅限Usenet抓取NewzBin文件的最小时间间隔分钟 开启此功能会让新版本有时间传播到你的usenet提供商",
"MinimumAgeHelpText": "仅限Usenet抓取NewzBin文件的最小时间间隔分钟开启此功能会让新版本有时间传播到你的usenet提供商",
"MIA": "MIA",
"MegabytesPerMinute": "每分钟MB",
"Mechanism": "机制",
@@ -1079,7 +1079,7 @@
"RemotePathMappingCheckFilesGenericPermissions": "下载{1}中客户端{0}报告的文件但Radarr无法看到此目录。您可能需要调整文件夹的权限。",
"RemotePathMappingCheckGenericPermissions": "下载客户端{0}将下载放置在{1}中但Radarr无法看到此目录。您可能需要调整文件夹的权限。",
"UpdateAvailable": "有新的更新可用",
"Letterboxd": "信箱",
"Letterboxd": "Letterboxd",
"RemoveSelectedItem": "删除所选项目",
"RemoveSelectedItems": "删除所选项目",
"TaskUserAgentTooltip": "由调用API的应用程序提供的User-Agent",
@@ -1088,32 +1088,32 @@
"RemoveDownloadsAlert": "移除设置被移至上表中的单个下载客户端设置。",
"RemoveFailed": "删除失败",
"AnnouncedMsg": "电影已公布",
"ClickToChangeReleaseGroup": "点击改发布组",
"ClickToChangeReleaseGroup": "点击改发布组",
"Auto": "自动",
"Duration": "期间",
"Duration": "时长",
"Filters": "过滤器",
"ImdbVotes": "IMDb票",
"ImdbVotes": "IMDb票",
"List": "列表",
"ImdbRating": "IMDb评分",
"ImdbRating": "IMDb 评分",
"LocalPath": "本地路径",
"OnApplicationUpdateHelpText": "应用更新中,请耐心等待",
"OnApplicationUpdate": "应用更新",
"ManualImportSetReleaseGroup": "手动导入-设置发布组",
"Never": "未打开",
"OnApplicationUpdateHelpText": "在程序更新时",
"OnApplicationUpdate": "程序更新",
"ManualImportSetReleaseGroup": "手动导入 - 选择发布组",
"Never": "永不",
"SelectLanguages": "选择语言",
"SelectReleaseGroup": "选择发布组",
"SetReleaseGroup": "设发布组",
"SetReleaseGroup": "设发布组",
"SizeLimit": "尺寸限制",
"Started": "已开始",
"Waiting": "等待",
"Waiting": "等待",
"IndexerJackettAll": "使用的Jackett端口: {0}不被索引器支持",
"IndexerDownloadClientHelpText": "指定的客户端将用于索引器",
"OriginalTitle": "原",
"IndexerDownloadClientHelpText": "指定索引器的下载客户端",
"OriginalTitle": "原标题",
"OriginalLanguage": "原语言",
"Rating": "评分",
"RemotePath": "远程路径",
"TmdbRating": "TMDb评分",
"TmdbVotes": "TMDb评分数",
"TmdbRating": "TMDb 评分",
"TmdbVotes": "TMDb 投票",
"DiscordUrlInSlackNotification": "你将Discord通知设为Slack通知如设为Discord通知功能更好受到影响的通知是: {0}",
"Database": "数据库"
}

View File

@@ -1,15 +0,0 @@
{
"Added": "已添加",
"AddDownloadClient": "添加下载客户端",
"Add": "添加",
"About": "关于",
"Always": "总是",
"Analytics": "分析",
"AddIndexer": "添加索引器",
"ApiKey": "API密钥",
"AddingTag": "添加标签",
"Apply": "应用",
"MinutesNinety": "60 分钟: {0}",
"MinutesSixty": "60 分钟: {0}",
"MinutesHundredTwenty": "20 分钟: {0}"
}

View File

@@ -1,3 +1,4 @@
using Equ;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.MediaCover
@@ -12,7 +13,7 @@ namespace NzbDrone.Core.MediaCover
Headshot = 5
}
public class MediaCover : IEmbeddedDocument
public class MediaCover : MemberwiseEquatable<MediaCover>, IEmbeddedDocument
{
public MediaCoverTypes CoverType { get; set; }
public string Url { get; set; }

View File

@@ -145,7 +145,7 @@ namespace NzbDrone.Core.MediaCover
bool updated = false;
var toResize = new List<Tuple<MediaCover, bool>>();
foreach (var cover in movie.Images)
foreach (var cover in movie.MovieMetadata.Value.Images)
{
var fileName = GetCoverPath(movie.Id, cover.CoverType);
var alreadyExists = false;

View File

@@ -133,7 +133,7 @@ namespace NzbDrone.Core.MediaFiles
return false;
}
if (_detectSample.IsSample(movie, videoFile) != DetectSampleResult.Sample)
if (_detectSample.IsSample(movie.MovieMetadata, videoFile) != DetectSampleResult.Sample)
{
_logger.Warn("Non-sample file detected: [{0}]", videoFile);
return false;

View File

@@ -22,7 +22,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators
public LocalMovie Aggregate(LocalMovie localMovie, DownloadClientItem downloadClientItem, bool otherFiles)
{
var languages = new List<Language> { localMovie.Movie?.OriginalLanguage ?? Language.Unknown };
var languages = new List<Language> { localMovie.Movie?.MovieMetadata.Value.OriginalLanguage ?? Language.Unknown };
var languagesConfidence = Confidence.Default;
foreach (var augmentLanguage in _augmentLanguages)

View File

@@ -9,7 +9,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
{
public interface IDetectSample
{
DetectSampleResult IsSample(Movie movie, string path);
DetectSampleResult IsSample(MovieMetadata movie, string path);
}
public class DetectSample : IDetectSample
@@ -23,7 +23,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
_logger = logger;
}
public DetectSampleResult IsSample(Movie movie, string path)
public DetectSampleResult IsSample(MovieMetadata movie, string path)
{
var extension = Path.GetExtension(path);
@@ -75,7 +75,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
return DetectSampleResult.NotSample;
}
private int GetMinimumAllowedRuntime(Movie movie)
private int GetMinimumAllowedRuntime(MovieMetadata movie)
{
//Anime short - 15 seconds
if (movie.Runtime <= 3)

View File

@@ -78,7 +78,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
downloadClientItemInfo = _parsingService.EnhanceMovieInfo(downloadClientItemInfo);
}
var nonSampleVideoFileCount = GetNonSampleVideoFileCount(newFiles, movie);
var nonSampleVideoFileCount = GetNonSampleVideoFileCount(newFiles, movie.MovieMetadata);
var decisions = new List<ImportDecision>();
@@ -187,7 +187,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
return null;
}
private int GetNonSampleVideoFileCount(List<string> videoFiles, Movie movie)
private int GetNonSampleVideoFileCount(List<string> videoFiles, MovieMetadata movie)
{
return videoFiles.Count(file =>
{

View File

@@ -104,8 +104,8 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
if (languageParse.Count <= 1 && languageParse.First() == Language.Unknown && movie != null)
{
languageParse = new List<Language> { movie.OriginalLanguage };
_logger.Debug("Language couldn't be parsed from release, fallback to movie original language: {0}", movie.OriginalLanguage.Name);
languageParse = new List<Language> { movie.MovieMetadata.Value.OriginalLanguage };
_logger.Debug("Language couldn't be parsed from release, fallback to movie original language: {0}", movie.MovieMetadata.Value.OriginalLanguage.Name);
}
var localMovie = new LocalMovie

View File

@@ -25,7 +25,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications
return Decision.Accept();
}
var sample = _detectSample.IsSample(localMovie.Movie, localMovie.Path);
var sample = _detectSample.IsSample(localMovie.Movie.MovieMetadata, localMovie.Path);
if (sample == DetectSampleResult.Sample)
{

View File

@@ -49,7 +49,7 @@ namespace NzbDrone.Core.MediaFiles
{
case FileDateType.Release:
{
var releaseDate = movie.PhysicalRelease ?? movie.DigitalRelease;
var releaseDate = movie.MovieMetadata.Value.PhysicalRelease ?? movie.MovieMetadata.Value.DigitalRelease;
if (releaseDate.HasValue == false)
{
@@ -61,7 +61,7 @@ namespace NzbDrone.Core.MediaFiles
case FileDateType.Cinemas:
{
var airDate = movie.InCinemas;
var airDate = movie.MovieMetadata.Value.InCinemas;
if (airDate.HasValue == false)
{

View File

@@ -7,9 +7,9 @@ namespace NzbDrone.Core.MetadataSource
{
public interface IProvideMovieInfo
{
Movie GetMovieByImdbId(string imdbId);
Tuple<Movie, List<Credit>> GetMovieInfo(int tmdbId);
List<Movie> GetBulkMovieInfo(List<int> tmdbIds);
MovieMetadata GetMovieByImdbId(string imdbId);
Tuple<MovieMetadata, List<Credit>> GetMovieInfo(int tmdbId);
List<MovieMetadata> GetBulkMovieInfo(List<int> tmdbIds);
HashSet<int> GetChangedMovies(DateTime startTime);
}

View File

@@ -7,6 +7,6 @@ namespace NzbDrone.Core.MetadataSource
{
List<Movie> SearchForNewMovie(string title);
Movie MapMovieToTmdbMovie(Movie movie);
MovieMetadata MapMovieToTmdbMovie(MovieMetadata movie);
}
}

View File

@@ -38,5 +38,6 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public string OriginalLanguage { get; set; }
public string Homepage { get; set; }
public List<RecommendationResource> Recommendations { get; set; }
public float? Popularity { get; set; }
}
}

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