mirror of
https://github.com/Radarr/Radarr.git
synced 2026-03-21 16:54:30 -04:00
Compare commits
63 Commits
movie-deta
...
update-cha
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b4a6b1309 | ||
|
|
fcebfe6759 | ||
|
|
f890aadffa | ||
|
|
a8695959f1 | ||
|
|
696bb845a5 | ||
|
|
301a6904c0 | ||
|
|
8b4621db61 | ||
|
|
822b597f26 | ||
|
|
737a0176d4 | ||
|
|
5dc541c69e | ||
|
|
a9627771e6 | ||
|
|
5facab0744 | ||
|
|
63dde3eb89 | ||
|
|
144f564076 | ||
|
|
a6205c1ad4 | ||
|
|
64f27bca4f | ||
|
|
8a84975954 | ||
|
|
e923b2fc6c | ||
|
|
a4136150d0 | ||
|
|
1f1f3cdaa2 | ||
|
|
bd85936a62 | ||
|
|
93b2395228 | ||
|
|
14cccd3a23 | ||
|
|
006c9289de | ||
|
|
79cd2b2346 | ||
|
|
f80272a659 | ||
|
|
a158e008e9 | ||
|
|
c798987379 | ||
|
|
097b46c49f | ||
|
|
ddeb3a7840 | ||
|
|
50018d0325 | ||
|
|
a37fc0dc1f | ||
|
|
39ad315e73 | ||
|
|
0559996566 | ||
|
|
e7d4429fe4 | ||
|
|
6c494e9a92 | ||
|
|
62faa1aad8 | ||
|
|
907950e309 | ||
|
|
1caced614e | ||
|
|
5824ba963b | ||
|
|
7f2d5d8d10 | ||
|
|
81bffe243a | ||
|
|
2d6fde282a | ||
|
|
3125b038d5 | ||
|
|
89e25a6241 | ||
|
|
4db6688fe0 | ||
|
|
4ac1aeaf06 | ||
|
|
e2ae743ee1 | ||
|
|
9ad316a6f5 | ||
|
|
b643d2e23d | ||
|
|
6a03eddda9 | ||
|
|
1576bf1f17 | ||
|
|
6325b70e27 | ||
|
|
24206ad0a3 | ||
|
|
2fc7cbff89 | ||
|
|
55ef505d74 | ||
|
|
cabdad6306 | ||
|
|
8d4b2dd21b | ||
|
|
ad04031c99 | ||
|
|
e9a5f87e45 | ||
|
|
bc6ac0cd4b | ||
|
|
c2328e4b79 | ||
|
|
36119facf0 |
@@ -9,13 +9,13 @@ variables:
|
||||
testsFolder: './_tests'
|
||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
||||
majorVersion: '4.1.0'
|
||||
majorVersion: '4.2.0'
|
||||
minorVersion: $[counter('minorVersion', 2000)]
|
||||
radarrVersion: '$(majorVersion).$(minorVersion)'
|
||||
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
|
||||
sentryOrg: 'servarr'
|
||||
sentryUrl: 'https://sentry.servarr.com'
|
||||
dotnetVersion: '6.0.201'
|
||||
dotnetVersion: '6.0.300'
|
||||
nodeVersion: '16.X'
|
||||
innoVersion: '6.2.0'
|
||||
windowsImage: 'windows-2022'
|
||||
@@ -97,15 +97,14 @@ stages:
|
||||
- bash: |
|
||||
BUNDLEDVERSIONS=${AGENT_TOOLSDIRECTORY}/dotnet/sdk/${DOTNETVERSION}/Microsoft.NETCoreSdk.BundledVersions.props
|
||||
echo $BUNDLEDVERSIONS
|
||||
grep osx-x64 $BUNDLEDVERSIONS
|
||||
if grep -q freebsd-x64 $BUNDLEDVERSIONS; then
|
||||
echo "BSD already enabled"
|
||||
echo "Extra platforms already enabled"
|
||||
else
|
||||
echo "Enabling BSD support"
|
||||
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64/' $BUNDLEDVERSIONS
|
||||
echo "Enabling extra platform support"
|
||||
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS
|
||||
fi
|
||||
displayName: Enable FreeBSD Support
|
||||
- bash: ./build.sh --backend --enable-bsd
|
||||
displayName: Enable Extra Platform Support
|
||||
- bash: ./build.sh --backend --enable-extra-platforms
|
||||
displayName: Build Radarr Backend
|
||||
- bash: |
|
||||
find ${OUTPUTFOLDER} -type f ! -path "*/publish/*" -exec rm -rf {} \;
|
||||
@@ -119,24 +118,28 @@ stages:
|
||||
displayName: Publish Backend
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/win-x64/publish'
|
||||
artifact: WindowsCoreTests
|
||||
displayName: Publish Windows Test Package
|
||||
artifact: win-x64-tests
|
||||
displayName: Publish win-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/linux-x64/publish'
|
||||
artifact: LinuxCoreTests
|
||||
displayName: Publish Linux Test Package
|
||||
artifact: linux-x64-tests
|
||||
displayName: Publish linux-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/linux-x86/publish'
|
||||
artifact: linux-x86-tests
|
||||
displayName: Publish linux-x86 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/linux-musl-x64/publish'
|
||||
artifact: LinuxMuslCoreTests
|
||||
displayName: Publish Linux Musl Test Package
|
||||
artifact: linux-musl-x64-tests
|
||||
displayName: Publish linux-musl-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/freebsd-x64/publish'
|
||||
artifact: FreebsdCoreTests
|
||||
displayName: Publish FreeBSD Test Package
|
||||
artifact: freebsd-x64-tests
|
||||
displayName: Publish freebsd-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/osx-x64/publish'
|
||||
artifact: MacCoreTests
|
||||
displayName: Publish MacOS Test Package
|
||||
artifact: osx-x64-tests
|
||||
displayName: Publish osx-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
|
||||
- stage: Build_Frontend
|
||||
@@ -240,7 +243,7 @@ stages:
|
||||
artifactName: WindowsFrontend
|
||||
targetPath: _output
|
||||
displayName: Fetch Frontend
|
||||
- bash: ./build.sh --packages --enable-bsd
|
||||
- bash: ./build.sh --packages --enable-extra-platforms
|
||||
displayName: Create Packages
|
||||
- bash: |
|
||||
find . -name "ffprobe" -exec chmod a+x {} \;
|
||||
@@ -248,28 +251,28 @@ stages:
|
||||
find . -name "Radarr.Update" -exec chmod a+x {} \;
|
||||
displayName: Set executable bits
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Windows Core zip
|
||||
displayName: Create win-x64 zip
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).windows-core-x64.zip'
|
||||
archiveType: 'zip'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/win-x64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Windows x86 Core zip
|
||||
displayName: Create win-x86 zip
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).windows-core-x86.zip'
|
||||
archiveType: 'zip'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/win-x86/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create MacOS x64 Core app
|
||||
displayName: Create osx-x64 app
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-app-core-x64.zip'
|
||||
archiveType: 'zip'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create MacOS x64 Core tar
|
||||
displayName: Create osx-x64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-core-x64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -277,14 +280,14 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/osx-x64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create MacOS arm64 Core app
|
||||
displayName: Create osx-arm64 app
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-app-core-arm64.zip'
|
||||
archiveType: 'zip'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create MacOS arm64 Core tar
|
||||
displayName: Create osx-arm64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-core-arm64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -292,7 +295,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Linux Core tar
|
||||
displayName: Create linux-x64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-x64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -300,7 +303,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-x64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Linux Musl Core tar
|
||||
displayName: Create linux-musl-x64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-x64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -308,7 +311,15 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create ARM32 Linux Core tar
|
||||
displayName: Create linux-x86 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-x86.tar.gz'
|
||||
archiveType: 'tar'
|
||||
tarCompression: 'gz'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-x86/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create linux-arm tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-arm.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -316,7 +327,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-arm/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create ARM32 Linux Musl Core tar
|
||||
displayName: Create linux-musl-arm tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-arm.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -324,7 +335,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create ARM64 Linux Core tar
|
||||
displayName: Create linux-arm64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-arm64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -332,7 +343,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create ARM64 Linux Musl Core tar
|
||||
displayName: Create linux-musl-arm64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-arm64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -340,7 +351,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create FreeBSD Core Core tar
|
||||
displayName: Create freebsd-x64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).freebsd-core-x64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -407,22 +418,22 @@ stages:
|
||||
matrix:
|
||||
MacCore:
|
||||
osName: 'Mac'
|
||||
testName: 'MacCore'
|
||||
testName: 'osx-x64'
|
||||
poolName: 'Azure Pipelines'
|
||||
imageName: ${{ variables.macImage }}
|
||||
WindowsCore:
|
||||
osName: 'Windows'
|
||||
testName: 'WindowsCore'
|
||||
testName: 'win-x64'
|
||||
poolName: 'Azure Pipelines'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
LinuxCore:
|
||||
osName: 'Linux'
|
||||
testName: 'LinuxCore'
|
||||
testName: 'linux-x64'
|
||||
poolName: 'Azure Pipelines'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
FreebsdCore:
|
||||
osName: 'Linux'
|
||||
testName: 'FreebsdCore'
|
||||
testName: 'freebsd-x64'
|
||||
poolName: 'FreeBSD'
|
||||
imageName:
|
||||
|
||||
@@ -441,7 +452,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: '$(testName)Tests'
|
||||
artifactName: '$(testName)-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- powershell: Set-Service SCardSvr -StartupType Manual
|
||||
displayName: Enable Windows Test Service
|
||||
@@ -475,8 +486,12 @@ stages:
|
||||
matrix:
|
||||
alpine:
|
||||
testName: 'Musl Net Core'
|
||||
artifactName: LinuxMuslCoreTests
|
||||
artifactName: linux-musl-x64-tests
|
||||
containerImage: ghcr.io/servarr/testimages:alpine
|
||||
linux-x86:
|
||||
testName: 'linux-x86'
|
||||
artifactName: linux-x86-tests
|
||||
containerImage: ghcr.io/servarr/testimages:linux-x86
|
||||
|
||||
pool:
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
@@ -487,9 +502,15 @@ stages:
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
displayName: 'Install .NET'
|
||||
inputs:
|
||||
version: $(dotnetVersion)
|
||||
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
|
||||
- bash: |
|
||||
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
|
||||
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
|
||||
displayName: 'Install .NET'
|
||||
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Test Artifact
|
||||
@@ -522,7 +543,7 @@ stages:
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
variables:
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
artifactName: LinuxCoreTests
|
||||
artifactName: linux-x64-tests
|
||||
Radarr__Postgres__Host: 'localhost'
|
||||
Radarr__Postgres__Port: '5432'
|
||||
Radarr__Postgres__User: 'radarr'
|
||||
@@ -597,17 +618,17 @@ stages:
|
||||
matrix:
|
||||
MacCore:
|
||||
osName: 'Mac'
|
||||
testName: 'MacCore'
|
||||
testName: 'osx-x64'
|
||||
imageName: ${{ variables.macImage }}
|
||||
pattern: 'Radarr.*.osx-core-x64.tar.gz'
|
||||
WindowsCore:
|
||||
osName: 'Windows'
|
||||
testName: 'WindowsCore'
|
||||
testName: 'win-x64'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
pattern: 'Radarr.*.windows-core-x64.zip'
|
||||
LinuxCore:
|
||||
osName: 'Linux'
|
||||
testName: 'LinuxCore'
|
||||
testName: 'linux-x64'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
|
||||
@@ -624,7 +645,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: '$(testName)Tests'
|
||||
artifactName: '$(testName)-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
@@ -678,7 +699,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: 'LinuxCoreTests'
|
||||
artifactName: 'linux-x64-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
@@ -732,7 +753,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: 'FreebsdCoreTests'
|
||||
artifactName: 'freebsd-x64-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
@@ -768,10 +789,15 @@ stages:
|
||||
strategy:
|
||||
matrix:
|
||||
alpine:
|
||||
testName: 'Musl Net Core'
|
||||
artifactName: LinuxMuslCoreTests
|
||||
testName: 'linux-musl-x64'
|
||||
artifactName: linux-musl-x64-tests
|
||||
containerImage: ghcr.io/servarr/testimages:alpine
|
||||
pattern: 'Radarr.*.linux-musl-core-x64.tar.gz'
|
||||
linux-x86:
|
||||
testName: 'linux-x86'
|
||||
artifactName: linux-x86-tests
|
||||
containerImage: ghcr.io/servarr/testimages:linux-x86
|
||||
pattern: 'Radarr.*.linux-core-x86.tar.gz'
|
||||
pool:
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
|
||||
@@ -781,9 +807,15 @@ stages:
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
displayName: 'Install .NET'
|
||||
inputs:
|
||||
version: $(dotnetVersion)
|
||||
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
|
||||
- bash: |
|
||||
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
|
||||
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
|
||||
displayName: 'Install .NET'
|
||||
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Test Artifact
|
||||
@@ -829,16 +861,19 @@ stages:
|
||||
matrix:
|
||||
Linux:
|
||||
osName: 'Linux'
|
||||
artifactName: 'linux-x64'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
failBuild: true
|
||||
Mac:
|
||||
osName: 'Mac'
|
||||
artifactName: 'osx-x64'
|
||||
imageName: ${{ variables.macImage }}
|
||||
pattern: 'Radarr.*.osx-core-x64.tar.gz'
|
||||
failBuild: true
|
||||
Windows:
|
||||
osName: 'Windows'
|
||||
artifactName: 'win-x64'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
pattern: 'Radarr.*.windows-core-x64.zip'
|
||||
failBuild: true
|
||||
@@ -856,7 +891,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: '$(osName)CoreTests'
|
||||
artifactName: '$(artifactName)-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
|
||||
44
build.sh
44
build.sh
@@ -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"
|
||||
|
||||
@@ -179,6 +179,16 @@ class HistoryRow extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'sourceTitle') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
>
|
||||
{sourceTitle}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'details') {
|
||||
return (
|
||||
<TableRowCell
|
||||
|
||||
@@ -8,7 +8,7 @@ import AppRoutes from './AppRoutes';
|
||||
|
||||
function App({ store, history }) {
|
||||
return (
|
||||
<DocumentTitle title="Radarr">
|
||||
<DocumentTitle title={window.Radarr.instanceName}>
|
||||
<Provider store={store}>
|
||||
<ConnectedRouter history={history}>
|
||||
<PageConnector>
|
||||
|
||||
@@ -89,12 +89,12 @@ function AppUpdatedModalContent(props) {
|
||||
|
||||
<UpdateChanges
|
||||
title={translate('New')}
|
||||
changes={update.changes.new}
|
||||
changes={Array.from(new Set(update.changes.new))}
|
||||
/>
|
||||
|
||||
<UpdateChanges
|
||||
title={translate('Fixed')}
|
||||
changes={update.changes.fixed}
|
||||
changes={Array.from(new Set(update.changes.fixed))}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class CollectionFooter extends Component {
|
||||
} = this.state;
|
||||
|
||||
const monitoredOptions = [
|
||||
{ key: NO_CHANGE, value: translate('No Change'), disabled: true },
|
||||
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
|
||||
{ key: 'monitored', value: translate('Monitored') },
|
||||
{ key: 'unmonitored', value: translate('Unmonitored') }
|
||||
];
|
||||
|
||||
50
frontend/src/Collection/Overview/CollectionMovieLabel.css
Normal file
50
frontend/src/Collection/Overview/CollectionMovieLabel.css
Normal file
@@ -0,0 +1,50 @@
|
||||
.movie {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
margin: 2px 4px;
|
||||
border: 1px solid $borderColor;
|
||||
border-radius: 4px;
|
||||
background-color: #eee;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.movieTitle {
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.movieStatus {
|
||||
padding: 0 4px;
|
||||
border-left: 4px;
|
||||
border-left-style: solid;
|
||||
background-color: $white;
|
||||
color: $defaultColor;
|
||||
}
|
||||
|
||||
.primary {
|
||||
border-color: $primaryColor;
|
||||
}
|
||||
|
||||
.danger {
|
||||
border-color: $dangerColor;
|
||||
}
|
||||
|
||||
.success {
|
||||
border-color: $successColor;
|
||||
}
|
||||
|
||||
.purple {
|
||||
border-color: $purple;
|
||||
}
|
||||
|
||||
.warning {
|
||||
border-color: $warningColor;
|
||||
}
|
||||
|
||||
.info {
|
||||
border-color: $infoColor;
|
||||
}
|
||||
|
||||
.queue {
|
||||
border-color: $queueColor;
|
||||
}
|
||||
84
frontend/src/Collection/Overview/CollectionMovieLabel.js
Normal file
84
frontend/src/Collection/Overview/CollectionMovieLabel.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import MonitorToggleButton from 'Components/MonitorToggleButton';
|
||||
import getStatusStyle from 'Utilities/Movie/getStatusStyle';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './CollectionMovieLabel.css';
|
||||
|
||||
class CollectionMovieLabel extends Component {
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
id,
|
||||
title,
|
||||
status,
|
||||
monitored,
|
||||
isAvailable,
|
||||
hasFile,
|
||||
onMonitorTogglePress,
|
||||
isSaving
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className={styles.movie}>
|
||||
<div className={styles.movieTitle}>
|
||||
{
|
||||
id &&
|
||||
<MonitorToggleButton
|
||||
monitored={monitored}
|
||||
isSaving={isSaving}
|
||||
onPress={onMonitorTogglePress}
|
||||
/>
|
||||
}
|
||||
|
||||
<span>
|
||||
{
|
||||
title
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{
|
||||
id &&
|
||||
<div
|
||||
className={classNames(
|
||||
styles.movieStatus,
|
||||
styles[getStatusStyle(status, monitored, hasFile, isAvailable, 'kinds')]
|
||||
)}
|
||||
>
|
||||
{
|
||||
hasFile ? translate('Downloaded') : translate('Missing')
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CollectionMovieLabel.propTypes = {
|
||||
id: PropTypes.number,
|
||||
title: PropTypes.string.isRequired,
|
||||
status: PropTypes.string,
|
||||
isAvailable: PropTypes.bool,
|
||||
monitored: PropTypes.bool,
|
||||
hasFile: PropTypes.bool,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
movieFile: PropTypes.object,
|
||||
movieFileId: PropTypes.number,
|
||||
onMonitorTogglePress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
CollectionMovieLabel.defaultProps = {
|
||||
isSaving: false,
|
||||
statistics: {
|
||||
episodeFileCount: 0,
|
||||
totalEpisodeCount: 0,
|
||||
percentOfEpisodes: 0
|
||||
}
|
||||
};
|
||||
|
||||
export default CollectionMovieLabel;
|
||||
@@ -0,0 +1,59 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { toggleMovieMonitored } from 'Store/Actions/movieActions';
|
||||
import createCollectionExistingMovieSelector from 'Store/Selectors/createCollectionExistingMovieSelector';
|
||||
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
||||
import CollectionMovieLabel from './CollectionMovieLabel';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createDimensionsSelector(),
|
||||
createCollectionExistingMovieSelector(),
|
||||
(dimensions, existingMovie) => {
|
||||
return {
|
||||
isSmallScreen: dimensions.isSmallScreen,
|
||||
isExistingMovie: !!existingMovie,
|
||||
...existingMovie
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
toggleMovieMonitored
|
||||
};
|
||||
|
||||
class CollectionMovieLabelConnector extends Component {
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onMonitorTogglePress = (monitored) => {
|
||||
this.props.toggleMovieMonitored({
|
||||
movieId: this.props.id,
|
||||
monitored
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<CollectionMovieLabel
|
||||
{...this.props}
|
||||
onMonitorTogglePress={this.onMonitorTogglePress}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CollectionMovieLabelConnector.propTypes = {
|
||||
id: PropTypes.number,
|
||||
monitored: PropTypes.bool,
|
||||
toggleMovieMonitored: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(CollectionMovieLabelConnector);
|
||||
@@ -32,6 +32,11 @@ $hoverScale: 1.05;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.labelsContainer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.moviesContainer {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Slider from 'react-slick';
|
||||
import TextTruncate from 'react-text-truncate';
|
||||
import EditCollectionModalConnector from 'Collection/Edit/EditCollectionModalConnector';
|
||||
import Carousel from 'Components/Carousel';
|
||||
import CheckInput from 'Components/Form/CheckInput';
|
||||
import Icon from 'Components/Icon';
|
||||
import Label from 'Components/Label';
|
||||
@@ -14,8 +14,12 @@ import dimensions from 'Styles/Variables/dimensions';
|
||||
import fonts from 'Styles/Variables/fonts';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import CollectionMovieConnector from './CollectionMovieConnector';
|
||||
import CollectionMovieLabelConnector from './CollectionMovieLabelConnector';
|
||||
import styles from './CollectionOverview.css';
|
||||
|
||||
import 'slick-carousel/slick/slick.css';
|
||||
import 'slick-carousel/slick/slick-theme.css';
|
||||
|
||||
const columnPadding = parseInt(dimensions.movieIndexColumnPadding);
|
||||
const columnPaddingSmallScreen = parseInt(dimensions.movieIndexColumnPaddingSmallScreen);
|
||||
const defaultFontSize = parseInt(fonts.defaultFontSize);
|
||||
@@ -105,6 +109,7 @@ class CollectionOverview extends Component {
|
||||
const {
|
||||
showDetails,
|
||||
showOverview,
|
||||
showPosters,
|
||||
detailedProgressBar
|
||||
} = this.props.overviewOptions;
|
||||
|
||||
@@ -115,6 +120,15 @@ class CollectionOverview extends Component {
|
||||
const contentHeight = getContentHeight(rowHeight, isSmallScreen);
|
||||
const overviewHeight = contentHeight - titleRowHeight - posterHeight;
|
||||
|
||||
const sliderSettings = {
|
||||
arrows: false,
|
||||
dots: false,
|
||||
infinite: false,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
variableWidth: true
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
@@ -149,21 +163,25 @@ class CollectionOverview extends Component {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.navigationButtons}>
|
||||
<IconButton
|
||||
name={icons.ARROW_LEFT}
|
||||
title={translate('ScrollMovies')}
|
||||
onPress={this.state.slider?.slickPrev}
|
||||
size={20}
|
||||
/>
|
||||
{
|
||||
showPosters &&
|
||||
<div className={styles.navigationButtons}>
|
||||
<IconButton
|
||||
name={icons.ARROW_LEFT}
|
||||
title={translate('ScrollMovies')}
|
||||
onPress={this.state.slider?.slickPrev}
|
||||
size={20}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
name={icons.ARROW_RIGHT}
|
||||
title={translate('ScrollMovies')}
|
||||
onPress={this.state.slider?.slickNext}
|
||||
size={20}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
<IconButton
|
||||
name={icons.ARROW_RIGHT}
|
||||
title={translate('ScrollMovies')}
|
||||
onPress={this.state.slider?.slickNext}
|
||||
size={20}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{
|
||||
@@ -249,22 +267,35 @@ class CollectionOverview extends Component {
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className={styles.sliderContainer}>
|
||||
<Carousel setRef={this.setSliderRef}>
|
||||
{movies.map((movie) => (
|
||||
<div className={styles.movie} key={movie.tmdbId}>
|
||||
<CollectionMovieConnector
|
||||
{
|
||||
showPosters ?
|
||||
<div className={styles.sliderContainer}>
|
||||
<Slider ref={this.setSliderRef} {...sliderSettings}>
|
||||
{movies.map((movie) => (
|
||||
<div className={styles.movie} key={movie.tmdbId}>
|
||||
<CollectionMovieConnector
|
||||
key={movie.tmdbId}
|
||||
posterWidth={posterWidth}
|
||||
posterHeight={posterHeight}
|
||||
detailedProgressBar={detailedProgressBar}
|
||||
collectionId={id}
|
||||
{...movie}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</Slider>
|
||||
</div> :
|
||||
<div className={styles.labelsContainer}>
|
||||
{movies.map((movie) => (
|
||||
<CollectionMovieLabelConnector
|
||||
key={movie.tmdbId}
|
||||
posterWidth={posterWidth}
|
||||
posterHeight={posterHeight}
|
||||
detailedProgressBar={detailedProgressBar}
|
||||
collectionId={id}
|
||||
{...movie}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ function calculatePosterWidth(posterSize, isSmallScreen) {
|
||||
function calculateRowHeight(posterHeight, sortKey, isSmallScreen, overviewOptions) {
|
||||
|
||||
const heights = [
|
||||
posterHeight,
|
||||
overviewOptions.showPosters ? posterHeight : 75,
|
||||
isSmallScreen ? columnPaddingSmallScreen : columnPadding
|
||||
];
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@ class CollectionOverviewOptionsModalContent extends Component {
|
||||
detailedProgressBar: props.detailedProgressBar,
|
||||
size: props.size,
|
||||
showDetails: props.showDetails,
|
||||
showOverview: props.showOverview
|
||||
showOverview: props.showOverview,
|
||||
showPosters: props.showPosters
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,7 +41,8 @@ class CollectionOverviewOptionsModalContent extends Component {
|
||||
detailedProgressBar,
|
||||
size,
|
||||
showDetails,
|
||||
showOverview
|
||||
showOverview,
|
||||
showPosters
|
||||
} = this.props;
|
||||
|
||||
const state = {};
|
||||
@@ -61,6 +63,10 @@ class CollectionOverviewOptionsModalContent extends Component {
|
||||
state.showOverview = showOverview;
|
||||
}
|
||||
|
||||
if (showPosters !== prevProps.showPosters) {
|
||||
state.showPosters = showPosters;
|
||||
}
|
||||
|
||||
if (!_.isEmpty(state)) {
|
||||
this.setState(state);
|
||||
}
|
||||
@@ -99,13 +105,14 @@ class CollectionOverviewOptionsModalContent extends Component {
|
||||
size,
|
||||
detailedProgressBar,
|
||||
showDetails,
|
||||
showPosters,
|
||||
showOverview
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>
|
||||
Overview Options
|
||||
{translate('CollectionOptions')}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
@@ -141,6 +148,7 @@ class CollectionOverviewOptionsModalContent extends Component {
|
||||
type={inputTypes.CHECK}
|
||||
name="showDetails"
|
||||
value={showDetails}
|
||||
helpText={translate('CollectionShowDetailsHelpText')}
|
||||
onChange={this.onChangeOverviewOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
@@ -152,6 +160,19 @@ class CollectionOverviewOptionsModalContent extends Component {
|
||||
type={inputTypes.CHECK}
|
||||
name="showOverview"
|
||||
value={showOverview}
|
||||
helpText={translate('CollectionShowOverviewsHelpText')}
|
||||
onChange={this.onChangeOverviewOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('ShowPosters')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showPosters"
|
||||
value={showPosters}
|
||||
helpText={translate('CollectionShowPostersHelpText')}
|
||||
onChange={this.onChangeOverviewOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
@@ -175,6 +196,7 @@ CollectionOverviewOptionsModalContent.propTypes = {
|
||||
size: PropTypes.string.isRequired,
|
||||
showDetails: PropTypes.bool.isRequired,
|
||||
showOverview: PropTypes.bool.isRequired,
|
||||
showPosters: PropTypes.bool.isRequired,
|
||||
onChangeOverviewOption: PropTypes.func.isRequired,
|
||||
onChangeOption: PropTypes.func.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Slider from 'react-slick';
|
||||
import styles from './Alert.css';
|
||||
|
||||
import 'slick-carousel/slick/slick.css';
|
||||
import 'slick-carousel/slick/slick-theme.css';
|
||||
|
||||
function Carousel({ className, setRef, children, ...otherProps }) {
|
||||
|
||||
const sliderSettings = {
|
||||
arrows: false,
|
||||
dots: false,
|
||||
infinite: false,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
variableWidth: true
|
||||
};
|
||||
|
||||
return (
|
||||
<Slider ref={setRef} {...sliderSettings}>
|
||||
{children}
|
||||
</Slider>
|
||||
);
|
||||
}
|
||||
|
||||
Carousel.propTypes = {
|
||||
className: PropTypes.string.isRequired,
|
||||
setRef: PropTypes.func.isRequired,
|
||||
children: PropTypes.node.isRequired
|
||||
};
|
||||
|
||||
Carousel.defaultProps = {
|
||||
className: styles.alert
|
||||
};
|
||||
|
||||
export default Carousel;
|
||||
@@ -14,7 +14,7 @@ function PageContent(props) {
|
||||
|
||||
return (
|
||||
<ErrorBoundary errorComponent={PageContentError}>
|
||||
<DocumentTitle title={title ? `${title} - Radarr` : 'Radarr'}>
|
||||
<DocumentTitle title={title ? `${title} - ${window.Radarr.instanceName}` : window.Radarr.instanceName}>
|
||||
<div className={className}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import SelectInput from 'Components/Form/SelectInput';
|
||||
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||
import PageContentFooter from 'Components/Page/PageContentFooter';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import monitorOptions from 'Utilities/Movie/monitorOptions';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import DiscoverMovieFooterLabel from './DiscoverMovieFooterLabel';
|
||||
import ExcludeMovieModal from './Exclusion/ExcludeMovieModal';
|
||||
@@ -137,11 +138,6 @@ class DiscoverMovieFooter extends Component {
|
||||
isExcludeMovieModalOpen
|
||||
} = this.state;
|
||||
|
||||
const monitoredOptions = [
|
||||
{ key: true, value: translate('Monitored') },
|
||||
{ key: false, value: translate('Unmonitored') }
|
||||
];
|
||||
|
||||
return (
|
||||
<PageContentFooter>
|
||||
<div className={styles.inputContainer}>
|
||||
@@ -153,7 +149,7 @@ class DiscoverMovieFooter extends Component {
|
||||
<SelectInput
|
||||
name="monitor"
|
||||
value={monitor}
|
||||
values={monitoredOptions}
|
||||
values={monitorOptions}
|
||||
isDisabled={!selectedCount}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
|
||||
@@ -81,6 +81,7 @@ const filterExistingFilesOptions = {
|
||||
};
|
||||
|
||||
const importModeOptions = [
|
||||
{ key: 'chooseImportMode', value: translate('ChooseImportMode'), disabled: true },
|
||||
{ key: 'move', value: translate('MoveFiles') },
|
||||
{ key: 'copy', value: translate('HardlinkCopyFiles') }
|
||||
];
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
@@ -101,9 +100,18 @@ class InteractiveImportModalContentConnector extends Component {
|
||||
};
|
||||
|
||||
onImportSelectedPress = (selected, importMode) => {
|
||||
const {
|
||||
items
|
||||
} = this.props;
|
||||
|
||||
const files = [];
|
||||
|
||||
_.forEach(this.props.items, (item) => {
|
||||
if (importMode === 'chooseImportMode') {
|
||||
this.setState({ interactiveImportErrorMessage: 'An import mode must be selected' });
|
||||
return;
|
||||
}
|
||||
|
||||
items.forEach((item) => {
|
||||
const isSelected = selected.indexOf(item.id) > -1;
|
||||
|
||||
if (isSelected) {
|
||||
|
||||
@@ -7,3 +7,9 @@
|
||||
.filteredMessage {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.blankpad {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 2em;
|
||||
}
|
||||
@@ -2,15 +2,12 @@ import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Icon from 'Components/Icon';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import FilterMenu from 'Components/Menu/FilterMenu';
|
||||
import PageMenuButton from 'Components/Menu/PageMenuButton';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { align, icons, sortDirections } from 'Helpers/Props';
|
||||
import { icons, sortDirections } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import InteractiveSearchFilterModalConnector from './InteractiveSearchFilterModalConnector';
|
||||
import InteractiveSearchRowConnector from './InteractiveSearchRowConnector';
|
||||
import styles from './InteractiveSearch.css';
|
||||
import styles from './InteractiveSearchContent.css';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@@ -25,6 +22,20 @@ const columns = [
|
||||
isSortable: true,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'releaseWeight',
|
||||
label: React.createElement(Icon, { name: icons.DOWNLOAD }),
|
||||
isSortable: true,
|
||||
fixedSortDirection: sortDirections.ASCENDING,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'rejections',
|
||||
label: React.createElement(Icon, { name: icons.DANGER }),
|
||||
isSortable: true,
|
||||
fixedSortDirection: sortDirections.ASCENDING,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
label: translate('Title'),
|
||||
@@ -88,24 +99,10 @@ const columns = [
|
||||
label: React.createElement(Icon, { name: icons.FLAG }),
|
||||
isSortable: true,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'rejections',
|
||||
label: React.createElement(Icon, { name: icons.DANGER }),
|
||||
isSortable: true,
|
||||
fixedSortDirection: sortDirections.ASCENDING,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'releaseWeight',
|
||||
label: React.createElement(Icon, { name: icons.DOWNLOAD }),
|
||||
isSortable: true,
|
||||
fixedSortDirection: sortDirections.ASCENDING,
|
||||
isVisible: true
|
||||
}
|
||||
];
|
||||
|
||||
function InteractiveSearch(props) {
|
||||
function InteractiveSearchContent(props) {
|
||||
const {
|
||||
searchPayload,
|
||||
isFetching,
|
||||
@@ -113,63 +110,44 @@ function InteractiveSearch(props) {
|
||||
error,
|
||||
totalReleasesCount,
|
||||
items,
|
||||
selectedFilterKey,
|
||||
filters,
|
||||
customFilters,
|
||||
sortKey,
|
||||
sortDirection,
|
||||
longDateFormat,
|
||||
timeFormat,
|
||||
onSortPress,
|
||||
onFilterSelect,
|
||||
onGrabPress
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.filterMenuContainer}>
|
||||
<FilterMenu
|
||||
alignMenu={align.RIGHT}
|
||||
selectedFilterKey={selectedFilterKey}
|
||||
filters={filters}
|
||||
customFilters={customFilters}
|
||||
buttonComponent={PageMenuButton}
|
||||
filterModalConnectorComponent={InteractiveSearchFilterModalConnector}
|
||||
filterModalConnectorComponentProps={'movies'}
|
||||
onFilterSelect={onFilterSelect}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{
|
||||
isFetching ? <LoadingIndicator /> : null
|
||||
isFetching &&
|
||||
<LoadingIndicator />
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && error ?
|
||||
<div>
|
||||
!isFetching && !!error &&
|
||||
<div className={styles.blankpad}>
|
||||
{translate('UnableToLoadResultsIntSearch')}
|
||||
</div> :
|
||||
null
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && isPopulated && !totalReleasesCount ?
|
||||
<div>
|
||||
!isFetching && isPopulated && !totalReleasesCount &&
|
||||
<div className={styles.blankpad}>
|
||||
{translate('NoResultsFound')}
|
||||
</div> :
|
||||
null
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!!totalReleasesCount && isPopulated && !items.length ?
|
||||
<div>
|
||||
!!totalReleasesCount && isPopulated && !items.length &&
|
||||
<div className={styles.blankpad}>
|
||||
{translate('AllResultsHiddenFilter')}
|
||||
</div> :
|
||||
null
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
isPopulated && !!items.length ?
|
||||
isPopulated && !!items.length &&
|
||||
<Table
|
||||
columns={columns}
|
||||
sortKey={sortKey}
|
||||
@@ -181,7 +159,7 @@ function InteractiveSearch(props) {
|
||||
items.map((item) => {
|
||||
return (
|
||||
<InteractiveSearchRowConnector
|
||||
key={item.guid}
|
||||
key={`${item.indexerId}-${item.guid}`}
|
||||
{...item}
|
||||
searchPayload={searchPayload}
|
||||
longDateFormat={longDateFormat}
|
||||
@@ -192,38 +170,32 @@ function InteractiveSearch(props) {
|
||||
})
|
||||
}
|
||||
</TableBody>
|
||||
</Table> :
|
||||
null
|
||||
</Table>
|
||||
}
|
||||
|
||||
{
|
||||
totalReleasesCount !== items.length && !!items.length ?
|
||||
totalReleasesCount !== items.length && !!items.length &&
|
||||
<div className={styles.filteredMessage}>
|
||||
{translate('SomeResultsHiddenFilter')}
|
||||
</div> :
|
||||
null
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
InteractiveSearch.propTypes = {
|
||||
InteractiveSearchContent.propTypes = {
|
||||
searchPayload: PropTypes.object.isRequired,
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
totalReleasesCount: PropTypes.number.isRequired,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
filters: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
customFilters: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
sortKey: PropTypes.string,
|
||||
sortDirection: PropTypes.string,
|
||||
longDateFormat: PropTypes.string.isRequired,
|
||||
timeFormat: PropTypes.string.isRequired,
|
||||
onSortPress: PropTypes.func.isRequired,
|
||||
onFilterSelect: PropTypes.func.isRequired,
|
||||
onGrabPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default InteractiveSearch;
|
||||
export default InteractiveSearchContent;
|
||||
@@ -5,7 +5,7 @@ import { createSelector } from 'reselect';
|
||||
import * as releaseActions from 'Store/Actions/releaseActions';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import InteractiveSearch from './InteractiveSearch';
|
||||
import InteractiveSearchContent from './InteractiveSearchContent';
|
||||
|
||||
function createMapStateToProps(appState) {
|
||||
return createSelector(
|
||||
@@ -48,7 +48,7 @@ function createMapDispatchToProps(dispatch, props) {
|
||||
};
|
||||
}
|
||||
|
||||
class InteractiveSearchConnector extends Component {
|
||||
class InteractiveSearchContentConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
@@ -79,18 +79,18 @@ class InteractiveSearchConnector extends Component {
|
||||
|
||||
return (
|
||||
|
||||
<InteractiveSearch
|
||||
<InteractiveSearchContent
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InteractiveSearchConnector.propTypes = {
|
||||
InteractiveSearchContentConnector.propTypes = {
|
||||
searchPayload: PropTypes.object.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
dispatchFetchReleases: PropTypes.func.isRequired,
|
||||
dispatchClearReleases: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(InteractiveSearchConnector);
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(InteractiveSearchContentConnector);
|
||||
@@ -1,20 +1,15 @@
|
||||
.protocol {
|
||||
.cell {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
}
|
||||
|
||||
.protocol {
|
||||
composes: cell;
|
||||
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.title {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.indexer {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
composes: cell;
|
||||
|
||||
width: 85px;
|
||||
}
|
||||
@@ -22,9 +17,7 @@
|
||||
.quality,
|
||||
.customFormat,
|
||||
.language {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
text-align: center;
|
||||
composes: cell;
|
||||
}
|
||||
|
||||
.language {
|
||||
@@ -32,7 +25,7 @@
|
||||
}
|
||||
|
||||
.customFormatScore {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
composes: cell;
|
||||
|
||||
width: 55px;
|
||||
font-weight: bold;
|
||||
@@ -42,26 +35,34 @@
|
||||
.rejected,
|
||||
.indexerFlags,
|
||||
.download {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
composes: cell;
|
||||
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.age,
|
||||
.size {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
composes: cell;
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.peers {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
composes: cell;
|
||||
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
.title {
|
||||
composes: cell;
|
||||
}
|
||||
|
||||
.title div {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.history {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
composes: cell;
|
||||
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
@@ -145,6 +145,46 @@ class InteractiveSearchRow extends Component {
|
||||
{formatAge(age, ageHours, ageMinutes)}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.download}>
|
||||
<SpinnerIconButton
|
||||
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
|
||||
kind={grabError ? kinds.DANGER : kinds.DEFAULT}
|
||||
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
|
||||
isDisabled={isGrabbed}
|
||||
isSpinning={isGrabbing}
|
||||
onPress={downloadAllowed ? this.onGrabPress : this.onConfirmGrabPress}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.rejected}>
|
||||
{
|
||||
!!rejections.length &&
|
||||
<Popover
|
||||
anchor={
|
||||
<Icon
|
||||
name={icons.DANGER}
|
||||
kind={kinds.DANGER}
|
||||
/>
|
||||
}
|
||||
title={translate('ReleaseRejected')}
|
||||
body={
|
||||
<ul>
|
||||
{
|
||||
rejections.map((rejection, index) => {
|
||||
return (
|
||||
<li key={index}>
|
||||
{rejection}
|
||||
</li>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
position={tooltipPositions.BOTTOM}
|
||||
/>
|
||||
}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.title}>
|
||||
<Link
|
||||
to={infoUrl}
|
||||
@@ -257,46 +297,6 @@ class InteractiveSearchRow extends Component {
|
||||
}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.rejected}>
|
||||
{
|
||||
!!rejections.length &&
|
||||
<Popover
|
||||
anchor={
|
||||
<Icon
|
||||
name={icons.DANGER}
|
||||
kind={kinds.DANGER}
|
||||
/>
|
||||
}
|
||||
title={translate('ReleaseRejected')}
|
||||
body={
|
||||
<ul>
|
||||
{
|
||||
rejections.map((rejection, index) => {
|
||||
return (
|
||||
<li key={index}>
|
||||
{rejection}
|
||||
</li>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
position={tooltipPositions.LEFT}
|
||||
/>
|
||||
}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.download}>
|
||||
<SpinnerIconButton
|
||||
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
|
||||
kind={grabError ? kinds.DANGER : kinds.DEFAULT}
|
||||
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
|
||||
isDisabled={isGrabbed}
|
||||
isSpinning={isGrabbing}
|
||||
onPress={downloadAllowed ? this.onGrabPress : this.onConfirmGrabPress}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<ConfirmModal
|
||||
isOpen={this.state.isConfirmGrabModalOpen}
|
||||
kind={kinds.WARNING}
|
||||
|
||||
16
frontend/src/InteractiveSearch/InteractiveSearchTable.js
Normal file
16
frontend/src/InteractiveSearch/InteractiveSearchTable.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import InteractiveSearchContentConnector from './InteractiveSearchContentConnector';
|
||||
|
||||
function InteractiveSearchTable(props) {
|
||||
|
||||
return (
|
||||
<InteractiveSearchContentConnector
|
||||
searchPayload={props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
InteractiveSearchTable.propTypes = {
|
||||
};
|
||||
|
||||
export default InteractiveSearchTable;
|
||||
@@ -69,8 +69,7 @@ class MovieCastPoster extends Component {
|
||||
|
||||
const elementStyle = {
|
||||
width: `${posterWidth}px`,
|
||||
height: `${posterHeight}px`,
|
||||
borderRadius: '5px'
|
||||
height: `${posterHeight}px`
|
||||
};
|
||||
|
||||
const contentStyle = {
|
||||
|
||||
@@ -69,8 +69,7 @@ class MovieCrewPoster extends Component {
|
||||
|
||||
const elementStyle = {
|
||||
width: `${posterWidth}px`,
|
||||
height: `${posterHeight}px`,
|
||||
borderRadius: '5px'
|
||||
height: `${posterHeight}px`
|
||||
};
|
||||
|
||||
const contentStyle = {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
$hoverScale: 1.05;
|
||||
|
||||
.content {
|
||||
border-radius: 5px;
|
||||
transition: all 200ms ease-in;
|
||||
|
||||
&:hover {
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
.movie {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Carousel from 'Components/Carousel';
|
||||
import { Grid, WindowScroller } from 'react-virtualized';
|
||||
import Measure from 'Components/Measure';
|
||||
import dimensions from 'Styles/Variables/dimensions';
|
||||
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
|
||||
import MovieCreditPosterConnector from './MovieCreditPosterConnector';
|
||||
@@ -168,36 +169,56 @@ class MovieCreditPosters extends Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
items,
|
||||
itemComponent
|
||||
items
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
posterWidth,
|
||||
posterHeight
|
||||
width,
|
||||
columnWidth,
|
||||
columnCount,
|
||||
rowHeight
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
const rowCount = Math.ceil(items.length / columnCount);
|
||||
|
||||
<div className={styles.sliderContainer}>
|
||||
<Carousel setRef={this.setSliderRef}>
|
||||
{items.map((movie) => (
|
||||
<div className={styles.movie} key={movie.tmdbId}>
|
||||
<MovieCreditPosterConnector
|
||||
key={movie.order}
|
||||
component={itemComponent}
|
||||
posterWidth={posterWidth}
|
||||
posterHeight={posterHeight}
|
||||
tmdbId={movie.personTmdbId}
|
||||
personName={movie.personName}
|
||||
job={movie.job}
|
||||
character={movie.character}
|
||||
images={movie.images}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
</div>
|
||||
return (
|
||||
<Measure
|
||||
whitelist={['width']}
|
||||
onMeasure={this.onMeasure}
|
||||
>
|
||||
<WindowScroller
|
||||
scrollElement={undefined}
|
||||
>
|
||||
{({ height, registerChild, onChildScroll, scrollTop }) => {
|
||||
if (!height) {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={registerChild}>
|
||||
<Grid
|
||||
ref={this.setGridRef}
|
||||
className={styles.grid}
|
||||
autoHeight={true}
|
||||
height={height}
|
||||
columnCount={columnCount}
|
||||
columnWidth={columnWidth}
|
||||
rowCount={rowCount}
|
||||
rowHeight={rowHeight}
|
||||
width={width}
|
||||
onScroll={onChildScroll}
|
||||
scrollTop={scrollTop}
|
||||
overscanRowCount={2}
|
||||
cellRenderer={this.cellRenderer}
|
||||
scrollToAlignment={'start'}
|
||||
isScrollingOptOut={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
</WindowScroller>
|
||||
</Measure>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
3
frontend/src/Movie/Details/MovieAlternateTitles.css
Normal file
3
frontend/src/Movie/Details/MovieAlternateTitles.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.alternateTitle {
|
||||
white-space: nowrap;
|
||||
}
|
||||
28
frontend/src/Movie/Details/MovieAlternateTitles.js
Normal file
28
frontend/src/Movie/Details/MovieAlternateTitles.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import styles from './MovieAlternateTitles.css';
|
||||
|
||||
function MovieAlternateTitles({ alternateTitles }) {
|
||||
return (
|
||||
<ul>
|
||||
{
|
||||
alternateTitles.filter((x, i, a) => a.indexOf(x) === i).map((alternateTitle) => {
|
||||
return (
|
||||
<li
|
||||
key={alternateTitle}
|
||||
className={styles.alternateTitle}
|
||||
>
|
||||
{alternateTitle}
|
||||
</li>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
MovieAlternateTitles.propTypes = {
|
||||
alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired
|
||||
};
|
||||
|
||||
export default MovieAlternateTitles;
|
||||
@@ -5,7 +5,7 @@
|
||||
.header {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 425px;
|
||||
height: 375px;
|
||||
}
|
||||
|
||||
.errorMessage {
|
||||
@@ -39,11 +39,10 @@
|
||||
}
|
||||
|
||||
.poster {
|
||||
z-index: 2;
|
||||
flex-shrink: 0;
|
||||
margin-right: 35px;
|
||||
width: 250px;
|
||||
height: 368px;
|
||||
width: 217px;
|
||||
height: 319px;
|
||||
}
|
||||
|
||||
.info {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
|
||||
import TextTruncate from 'react-text-truncate';
|
||||
import FieldSet from 'Components/FieldSet';
|
||||
import Icon from 'Components/Icon';
|
||||
import ImdbRating from 'Components/ImdbRating';
|
||||
import InfoLabel from 'Components/InfoLabel';
|
||||
@@ -22,11 +22,12 @@ import Popover from 'Components/Tooltip/Popover';
|
||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
||||
import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props';
|
||||
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
|
||||
import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector';
|
||||
import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable';
|
||||
import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal';
|
||||
import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector';
|
||||
import MovieHistoryTable from 'Movie/History/MovieHistoryTable';
|
||||
import MoviePoster from 'Movie/MoviePoster';
|
||||
import MovieInteractiveSearchModalConnector from 'Movie/Search/MovieInteractiveSearchModalConnector';
|
||||
import MovieFileEditorTable from 'MovieFile/Editor/MovieFileEditorTable';
|
||||
import ExtraFileTable from 'MovieFile/Extras/ExtraFileTable';
|
||||
import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector';
|
||||
@@ -80,10 +81,10 @@ class MovieDetails extends Component {
|
||||
isEditMovieModalOpen: false,
|
||||
isDeleteMovieModalOpen: false,
|
||||
isInteractiveImportModalOpen: false,
|
||||
isInteractiveSearchModalOpen: false,
|
||||
allExpanded: false,
|
||||
allCollapsed: false,
|
||||
expandedState: {},
|
||||
selectedTabIndex: 0,
|
||||
overviewHeight: 0,
|
||||
titleWidth: 0
|
||||
};
|
||||
@@ -136,14 +137,6 @@ class MovieDetails extends Component {
|
||||
this.setState({ isEditMovieModalOpen: false });
|
||||
};
|
||||
|
||||
onInteractiveSearchPress = () => {
|
||||
this.setState({ isInteractiveSearchModalOpen: true });
|
||||
};
|
||||
|
||||
onInteractiveSearchModalClose = () => {
|
||||
this.setState({ isInteractiveSearchModalOpen: false });
|
||||
};
|
||||
|
||||
onDeleteMoviePress = () => {
|
||||
this.setState({
|
||||
isEditMovieModalOpen: false,
|
||||
@@ -305,9 +298,9 @@ class MovieDetails extends Component {
|
||||
isEditMovieModalOpen,
|
||||
isDeleteMovieModalOpen,
|
||||
isInteractiveImportModalOpen,
|
||||
isInteractiveSearchModalOpen,
|
||||
overviewHeight,
|
||||
titleWidth
|
||||
titleWidth,
|
||||
selectedTabIndex
|
||||
} = this.state;
|
||||
|
||||
const marqueeWidth = isSmallScreen ? titleWidth : (titleWidth - 150);
|
||||
@@ -333,14 +326,6 @@ class MovieDetails extends Component {
|
||||
onPress={onSearchPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label={translate('InteractiveSearch')}
|
||||
iconName={icons.INTERACTIVE}
|
||||
isSpinning={isSearching}
|
||||
title={undefined}
|
||||
onPress={this.onInteractiveSearchPress}
|
||||
/>
|
||||
|
||||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
@@ -666,39 +651,101 @@ class MovieDetails extends Component {
|
||||
</div>
|
||||
}
|
||||
|
||||
<FieldSet legend={translate('History')}>
|
||||
<MovieHistoryTable
|
||||
movieId={id}
|
||||
/>
|
||||
</FieldSet>
|
||||
<Tabs selectedIndex={this.state.tabIndex} onSelect={this.onTabSelect}>
|
||||
<TabList
|
||||
className={styles.tabList}
|
||||
>
|
||||
<Tab
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
{translate('History')}
|
||||
</Tab>
|
||||
|
||||
<FieldSet legend={translate('Files')}>
|
||||
<MovieFileEditorTable
|
||||
movieId={id}
|
||||
/>
|
||||
<Tab
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
{translate('Search')}
|
||||
</Tab>
|
||||
|
||||
<ExtraFileTable
|
||||
movieId={id}
|
||||
/>
|
||||
</FieldSet>
|
||||
<Tab
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
{translate('Files')}
|
||||
</Tab>
|
||||
|
||||
<FieldSet legend={translate('Cast')}>
|
||||
<MovieCastPostersConnector
|
||||
isSmallScreen={isSmallScreen}
|
||||
/>
|
||||
</FieldSet>
|
||||
<Tab
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
{translate('Titles')}
|
||||
</Tab>
|
||||
|
||||
<FieldSet legend={translate('Crew')}>
|
||||
<MovieCrewPostersConnector
|
||||
isSmallScreen={isSmallScreen}
|
||||
/>
|
||||
</FieldSet>
|
||||
<Tab
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
{translate('Cast')}
|
||||
</Tab>
|
||||
|
||||
<Tab
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
{translate('Crew')}
|
||||
</Tab>
|
||||
|
||||
{
|
||||
selectedTabIndex === 1 &&
|
||||
<div className={styles.filterIcon}>
|
||||
<InteractiveSearchFilterMenuConnector />
|
||||
</div>
|
||||
}
|
||||
|
||||
</TabList>
|
||||
|
||||
<TabPanel>
|
||||
<MovieHistoryTable
|
||||
movieId={id}
|
||||
/>
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel>
|
||||
<InteractiveSearchTable
|
||||
movieId={id}
|
||||
/>
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel>
|
||||
<MovieFileEditorTable
|
||||
movieId={id}
|
||||
/>
|
||||
<ExtraFileTable
|
||||
movieId={id}
|
||||
/>
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel>
|
||||
<MovieTitlesTable
|
||||
movieId={id}
|
||||
/>
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel>
|
||||
<MovieCastPostersConnector
|
||||
isSmallScreen={isSmallScreen}
|
||||
/>
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel>
|
||||
<MovieCrewPostersConnector
|
||||
isSmallScreen={isSmallScreen}
|
||||
/>
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
|
||||
<FieldSet legend={translate('Titles')}>
|
||||
<MovieTitlesTable
|
||||
movieId={id}
|
||||
/>
|
||||
</FieldSet>
|
||||
</div>
|
||||
|
||||
<OrganizePreviewModalConnector
|
||||
@@ -730,12 +777,6 @@ class MovieDetails extends Component {
|
||||
showImportMode={false}
|
||||
onModalClose={this.onInteractiveImportModalClose}
|
||||
/>
|
||||
|
||||
<MovieInteractiveSearchModalConnector
|
||||
isOpen={isInteractiveSearchModalOpen}
|
||||
movieId={id}
|
||||
onModalClose={this.onInteractiveSearchModalClose}
|
||||
/>
|
||||
</PageContentBody>
|
||||
</PageContent>
|
||||
);
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
.container {
|
||||
border: 1px solid $borderColor;
|
||||
border-radius: 4px;
|
||||
background-color: $white;
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import MovieTitlesTableContentConnector from './MovieTitlesTableContentConnector';
|
||||
import styles from './MovieTitlesTable.css';
|
||||
|
||||
function MovieTitlesTable(props) {
|
||||
const {
|
||||
@@ -8,11 +7,9 @@ function MovieTitlesTable(props) {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<MovieTitlesTableContentConnector
|
||||
{...otherProps}
|
||||
/>
|
||||
</div>
|
||||
<MovieTitlesTableContentConnector
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
.container {
|
||||
border: 1px solid $borderColor;
|
||||
border-radius: 4px;
|
||||
background-color: $white;
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import MovieHistoryTableContentConnector from './MovieHistoryTableContentConnector';
|
||||
import styles from './MovieHistoryTable.css';
|
||||
|
||||
function MovieHistoryTable(props) {
|
||||
const {
|
||||
@@ -8,11 +7,9 @@ function MovieHistoryTable(props) {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<MovieHistoryTableContentConnector
|
||||
{...otherProps}
|
||||
/>
|
||||
</div>
|
||||
<MovieHistoryTableContentConnector
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Modal from 'Components/Modal/Modal';
|
||||
import { sizes } from 'Helpers/Props';
|
||||
import MovieInteractiveSearchModalContent from './MovieInteractiveSearchModalContent';
|
||||
|
||||
function MovieInteractiveSearchModal(props) {
|
||||
const {
|
||||
isOpen,
|
||||
movieId,
|
||||
onModalClose
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
closeOnBackgroundClick={false}
|
||||
onModalClose={onModalClose}
|
||||
size={sizes.EXTRA_LARGE}
|
||||
>
|
||||
<MovieInteractiveSearchModalContent
|
||||
movieId={movieId}
|
||||
onModalClose={onModalClose}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
MovieInteractiveSearchModal.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
movieId: PropTypes.number.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default MovieInteractiveSearchModal;
|
||||
@@ -1,15 +0,0 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { cancelFetchReleases, clearReleases } from 'Store/Actions/releaseActions';
|
||||
import MovieInteractiveSearchModal from './MovieInteractiveSearchModal';
|
||||
|
||||
function createMapDispatchToProps(dispatch, props) {
|
||||
return {
|
||||
onModalClose() {
|
||||
dispatch(cancelFetchReleases());
|
||||
dispatch(clearReleases());
|
||||
props.onModalClose();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(null, createMapDispatchToProps)(MovieInteractiveSearchModal);
|
||||
@@ -1,45 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Button from 'Components/Link/Button';
|
||||
import ModalBody from 'Components/Modal/ModalBody';
|
||||
import ModalContent from 'Components/Modal/ModalContent';
|
||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { scrollDirections } from 'Helpers/Props';
|
||||
import InteractiveSearchConnector from 'InteractiveSearch/InteractiveSearchConnector';
|
||||
|
||||
function MovieInteractiveSearchModalContent(props) {
|
||||
const {
|
||||
movieId,
|
||||
onModalClose
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>
|
||||
Interactive Search
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody scrollDirection={scrollDirections.BOTH}>
|
||||
<InteractiveSearchConnector
|
||||
searchPayload={{
|
||||
movieId
|
||||
}}
|
||||
/>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button onPress={onModalClose}>
|
||||
Close
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
);
|
||||
}
|
||||
|
||||
MovieInteractiveSearchModalContent.propTypes = {
|
||||
movieId: PropTypes.number.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default MovieInteractiveSearchModalContent;
|
||||
@@ -1,4 +1,5 @@
|
||||
.container {
|
||||
margin-top: 20px;
|
||||
border: 1px solid $borderColor;
|
||||
border-radius: 4px;
|
||||
background-color: $white;
|
||||
|
||||
@@ -65,10 +65,10 @@ function DownloadClientOptions(props) {
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
name="checkForFinishedDownloadInterval"
|
||||
min={0}
|
||||
min={1}
|
||||
max={120}
|
||||
unit="minutes"
|
||||
helpText={translate('HelpText')}
|
||||
helpText={translate('RefreshMonitoredIntervalHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...settings.checkForFinishedDownloadInterval}
|
||||
/>
|
||||
|
||||
@@ -20,6 +20,7 @@ function HostSettings(props) {
|
||||
bindAddress,
|
||||
port,
|
||||
urlBase,
|
||||
instanceName,
|
||||
enableSsl,
|
||||
sslPort,
|
||||
sslCertPath,
|
||||
@@ -73,6 +74,22 @@ function HostSettings(props) {
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>{translate('InstanceName')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="instanceName"
|
||||
helpText={translate('InstanceNameHelpText')}
|
||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...instanceName}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
|
||||
@@ -116,7 +116,7 @@ function IndexerOptions(props) {
|
||||
min={0}
|
||||
max={120}
|
||||
unit="minutes"
|
||||
helpText={translate('HelpText')}
|
||||
helpText={translate('RssSyncHelpText')}
|
||||
helpTextWarning={translate('RSSSyncIntervalHelpTextWarning')}
|
||||
helpLink="https://wiki.servarr.com/radarr/faq#how-does-radarr-work"
|
||||
onChange={onInputChange}
|
||||
|
||||
@@ -59,6 +59,7 @@ class Notification extends Component {
|
||||
onDownload,
|
||||
onUpgrade,
|
||||
onRename,
|
||||
onMovieAdded,
|
||||
onMovieDelete,
|
||||
onMovieFileDelete,
|
||||
onMovieFileDeleteForUpgrade,
|
||||
@@ -68,6 +69,7 @@ class Notification extends Component {
|
||||
supportsOnDownload,
|
||||
supportsOnUpgrade,
|
||||
supportsOnRename,
|
||||
supportsOnMovieAdded,
|
||||
supportsOnMovieDelete,
|
||||
supportsOnMovieFileDelete,
|
||||
supportsOnMovieFileDeleteForUpgrade,
|
||||
@@ -117,6 +119,14 @@ class Notification extends Component {
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnMovieAdded && onMovieAdded ?
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
{translate('OnMovieAdded')}
|
||||
</Label> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnHealthIssue && onHealthIssue ?
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
@@ -196,6 +206,7 @@ Notification.propTypes = {
|
||||
onDownload: PropTypes.bool.isRequired,
|
||||
onUpgrade: PropTypes.bool.isRequired,
|
||||
onRename: PropTypes.bool.isRequired,
|
||||
onMovieAdded: PropTypes.bool.isRequired,
|
||||
onMovieDelete: PropTypes.bool.isRequired,
|
||||
onMovieFileDelete: PropTypes.bool.isRequired,
|
||||
onMovieFileDeleteForUpgrade: PropTypes.bool.isRequired,
|
||||
@@ -208,6 +219,7 @@ Notification.propTypes = {
|
||||
supportsOnMovieFileDeleteForUpgrade: PropTypes.bool.isRequired,
|
||||
supportsOnUpgrade: PropTypes.bool.isRequired,
|
||||
supportsOnRename: PropTypes.bool.isRequired,
|
||||
supportsOnMovieAdded: PropTypes.bool.isRequired,
|
||||
supportsOnHealthIssue: PropTypes.bool.isRequired,
|
||||
supportsOnApplicationUpdate: PropTypes.bool.isRequired,
|
||||
onConfirmDeleteNotification: PropTypes.func.isRequired
|
||||
|
||||
@@ -19,6 +19,7 @@ function NotificationEventItems(props) {
|
||||
onDownload,
|
||||
onUpgrade,
|
||||
onRename,
|
||||
onMovieAdded,
|
||||
onMovieDelete,
|
||||
onMovieFileDelete,
|
||||
onMovieFileDeleteForUpgrade,
|
||||
@@ -28,6 +29,7 @@ function NotificationEventItems(props) {
|
||||
supportsOnDownload,
|
||||
supportsOnUpgrade,
|
||||
supportsOnRename,
|
||||
supportsOnMovieAdded,
|
||||
supportsOnMovieDelete,
|
||||
supportsOnMovieFileDelete,
|
||||
supportsOnMovieFileDeleteForUpgrade,
|
||||
@@ -92,6 +94,17 @@ function NotificationEventItems(props) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onMovieAdded"
|
||||
helpText={translate('OnMovieAddedHelpText')}
|
||||
isDisabled={!supportsOnMovieAdded.value}
|
||||
{...onMovieAdded}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
||||
@@ -106,6 +106,7 @@ export default {
|
||||
selectedSchema.onDownload = selectedSchema.supportsOnDownload;
|
||||
selectedSchema.onUpgrade = selectedSchema.supportsOnUpgrade;
|
||||
selectedSchema.onRename = selectedSchema.supportsOnRename;
|
||||
selectedSchema.onMovieAdded = selectedSchema.supportsOnMovieAdded;
|
||||
selectedSchema.onMovieDelete = selectedSchema.supportsOnMovieDelete;
|
||||
selectedSchema.onMovieFileDelete = selectedSchema.supportsOnMovieFileDelete;
|
||||
selectedSchema.onMovieFileDeleteForUpgrade = selectedSchema.supportsOnMovieFileDeleteForUpgrade;
|
||||
|
||||
@@ -79,6 +79,11 @@ export const defaultState = {
|
||||
label: translate('ReleaseGroup'),
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'sourceTitle',
|
||||
label: translate('SourceTitle'),
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'details',
|
||||
columnLabel: translate('Details'),
|
||||
|
||||
@@ -30,7 +30,7 @@ export const defaultState = {
|
||||
sortKey: 'quality',
|
||||
sortDirection: sortDirections.DESCENDING,
|
||||
recentFolders: [],
|
||||
importMode: 'move',
|
||||
importMode: 'chooseImportMode',
|
||||
sortPredicates: {
|
||||
relativePath: function(item, direction) {
|
||||
const relativePath = item.relativePath;
|
||||
|
||||
@@ -40,7 +40,8 @@ export const defaultState = {
|
||||
detailedProgressBar: false,
|
||||
size: 'medium',
|
||||
showDetails: true,
|
||||
showOverview: true
|
||||
showOverview: true,
|
||||
showPosters: true
|
||||
},
|
||||
|
||||
defaults: {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import migrateBlacklistToBlocklist from './migrateBlacklistToBlocklist';
|
||||
import migrateMonitorToEnum from './migrateMonitorToEnum';
|
||||
import migratePreDbToReleased from './migratePreDbToReleased';
|
||||
|
||||
export default function migrate(persistedState) {
|
||||
migrateBlacklistToBlocklist(persistedState);
|
||||
migratePreDbToReleased(persistedState);
|
||||
migrateMonitorToEnum(persistedState);
|
||||
}
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import get from 'lodash';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default function migrateMonitorToEnum(persistedState) {
|
||||
const addMovie = get(persistedState, 'addMovie.defaults.monitor');
|
||||
const discoverMovie = get(persistedState, 'discoverMovie.defaults.monitor');
|
||||
const addMovie = _.get(persistedState, 'addMovie.defaults.monitor');
|
||||
const discoverMovie = _.get(persistedState, 'discoverMovie.defaults.monitor');
|
||||
|
||||
if (!addMovie && !discoverMovie) {
|
||||
return;
|
||||
if (addMovie) {
|
||||
if (addMovie === 'true') {
|
||||
persistedState.addMovie.defaults.monitor = 'movieOnly';
|
||||
}
|
||||
|
||||
if (addMovie === 'false') {
|
||||
persistedState.addMovie.defaults.monitor = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
if (addMovie === true) {
|
||||
persistedState.addMovie.defaults.monitor = 'movieOnly';
|
||||
}
|
||||
if (discoverMovie) {
|
||||
if (discoverMovie === 'true') {
|
||||
persistedState.discoverMovie.defaults.monitor = 'movieOnly';
|
||||
}
|
||||
|
||||
if (discoverMovie === true) {
|
||||
persistedState.discoverMovie.defaults.monitor = 'movieOnly';
|
||||
}
|
||||
|
||||
if (addMovie === false) {
|
||||
persistedState.addMovie.defaults.minimumAvailability = 'none';
|
||||
}
|
||||
|
||||
if (discoverMovie === false) {
|
||||
persistedState.discoverMovie.defaults.minimumAvailability = 'none';
|
||||
if (discoverMovie === 'false') {
|
||||
persistedState.discoverMovie.defaults.monitor = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import get from 'lodash';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default function migratePreDbToReleased(persistedState) {
|
||||
const addMovie = get(persistedState, 'addMovie.defaults.minimumAvailability');
|
||||
const discoverMovie = get(persistedState, 'discoverMovie.defaults.minimumAvailability');
|
||||
const addMovie = _.get(persistedState, 'addMovie.defaults.minimumAvailability');
|
||||
const discoverMovie = _.get(persistedState, 'discoverMovie.defaults.minimumAvailability');
|
||||
|
||||
if (!addMovie && !discoverMovie) {
|
||||
return;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
22
package.json
22
package.json
@@ -30,7 +30,7 @@
|
||||
"@fortawesome/free-regular-svg-icons": "6.1.0",
|
||||
"@fortawesome/free-solid-svg-icons": "6.1.0",
|
||||
"@fortawesome/react-fontawesome": "0.1.18",
|
||||
"@microsoft/signalr": "6.0.3",
|
||||
"@microsoft/signalr": "6.0.5",
|
||||
"@sentry/browser": "6.18.2",
|
||||
"@sentry/integrations": "6.18.2",
|
||||
"classnames": "2.3.1",
|
||||
@@ -45,7 +45,7 @@
|
||||
"jquery": "3.6.0",
|
||||
"lodash": "4.17.21",
|
||||
"mobile-detect": "1.4.5",
|
||||
"moment": "2.29.1",
|
||||
"moment": "2.29.2",
|
||||
"mousetrap": "1.6.5",
|
||||
"normalize.css": "8.0.1",
|
||||
"prop-types": "15.7.2",
|
||||
@@ -101,8 +101,8 @@
|
||||
"babel-loader": "8.2.3",
|
||||
"babel-plugin-inline-classnames": "2.0.1",
|
||||
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
|
||||
"core-js": "3.11.0",
|
||||
"css-loader": "5.2.4",
|
||||
"core-js": "3.12.1",
|
||||
"css-loader": "6.5.1",
|
||||
"eslint": "8.11.0",
|
||||
"eslint-plugin-filenames": "1.3.2",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
@@ -117,22 +117,22 @@
|
||||
"mini-css-extract-plugin": "1.5.0",
|
||||
"postcss": "8.2.12",
|
||||
"postcss-color-function": "4.1.0",
|
||||
"postcss-loader": "5.2.0",
|
||||
"postcss-mixins": "7.0.3",
|
||||
"postcss-nested": "5.0.5",
|
||||
"postcss-loader": "6.2.0",
|
||||
"postcss-mixins": "8.1.0",
|
||||
"postcss-nested": "5.0.6",
|
||||
"postcss-simple-vars": "6.0.3",
|
||||
"postcss-url": "10.1.3",
|
||||
"require-nocache": "1.0.0",
|
||||
"rimraf": "3.0.2",
|
||||
"run-sequence": "2.2.1",
|
||||
"streamqueue": "1.1.2",
|
||||
"style-loader": "2.0.0",
|
||||
"style-loader": "3.3.1",
|
||||
"stylelint": "14.6.0",
|
||||
"stylelint-order": "5.0.0",
|
||||
"url-loader": "4.1.1",
|
||||
"webpack": "5.35.1",
|
||||
"webpack-cli": "4.6.0",
|
||||
"webpack-livereload-plugin": "3.0.1",
|
||||
"webpack": "5.64.2",
|
||||
"webpack-cli": "4.9.1",
|
||||
"webpack-livereload-plugin": "3.0.2",
|
||||
"worker-loader": "3.0.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
|
||||
<!-- Standard testing packages -->
|
||||
<ItemGroup Condition="'$(TestProject)'=='true'">
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Include="NunitXml.TestLogger" Version="3.0.117" />
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,13 @@
|
||||
<PackageReference Include="Sentry" Version="3.15.0" />
|
||||
<PackageReference Include="NLog.Targets.Syslog" Version="6.0.3" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||
<PackageReference Include="System.Text.Json" Version="6.0.2" />
|
||||
<PackageReference Include="System.Text.Json" Version="6.0.4" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="EnsureThat\Resources\ExceptionMessages.Designer.cs">
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
66
src/NzbDrone.Core.Test/Files/Indexers/Nyaa/Nyaa2021.xml
Normal file
66
src/NzbDrone.Core.Test/Files/Indexers/Nyaa/Nyaa2021.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<rss xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:nyaa="https://nyaa.si/xmlns/nyaa" version="2.0">
|
||||
<channel>
|
||||
<title>Nyaa - Home - Torrent File RSS</title>
|
||||
<description>RSS Feed for Home</description>
|
||||
<link>https://nyaa.si/</link>
|
||||
<atom:link href="https://nyaa.si/?page=rss" rel="self" type="application/rss+xml"/>
|
||||
<item>
|
||||
<title>[Foxy-Subs] Mahouka Koukou no Yuutousei - 08 [720p] [3194D881].mkv</title>
|
||||
<link>https://nyaa.si/download/1424896.torrent</link>
|
||||
<guid isPermaLink="true">https://nyaa.si/view/1424896</guid>
|
||||
<pubDate>Tue, 24 Aug 2021 22:18:46 -0000</pubDate>
|
||||
<nyaa:seeders>4</nyaa:seeders>
|
||||
<nyaa:leechers>3</nyaa:leechers>
|
||||
<nyaa:downloads>2</nyaa:downloads>
|
||||
<nyaa:infoHash>e8ca5e20eca876339f41c3d9e95ea66c1d7caaee</nyaa:infoHash>
|
||||
<nyaa:categoryId>1_3</nyaa:categoryId>
|
||||
<nyaa:category>Anime - Non-English-translated</nyaa:category>
|
||||
<nyaa:size>609.6 MiB</nyaa:size>
|
||||
<nyaa:comments>0</nyaa:comments>
|
||||
<nyaa:trusted>No</nyaa:trusted>
|
||||
<nyaa:remake>No</nyaa:remake>
|
||||
<description>
|
||||
<![CDATA[ <a href="https://nyaa.si/view/1424896">#1424896 | [Foxy-Subs] Mahouka Koukou no Yuutousei - 08 [720p] [3194D881].mkv</a> | 609.6 MiB | Anime - Non-English-translated | E8CA5E20ECA876339F41C3D9E95EA66C1D7CAAEE ]]>
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Macross Zero (BDRip 1920x1080p x265 HEVC TrueHD, FLAC 5.1+2.0)[sxales]</title>
|
||||
<link>https://nyaa.si/download/1424895.torrent</link>
|
||||
<guid isPermaLink="true">https://nyaa.si/view/1424895</guid>
|
||||
<pubDate>Tue, 24 Aug 2021 22:03:11 -0000</pubDate>
|
||||
<nyaa:seeders>23</nyaa:seeders>
|
||||
<nyaa:leechers>32</nyaa:leechers>
|
||||
<nyaa:downloads>17</nyaa:downloads>
|
||||
<nyaa:infoHash>26f37f26d5b3475b41a98dc575fabfa6f8d32a76</nyaa:infoHash>
|
||||
<nyaa:categoryId>1_2</nyaa:categoryId>
|
||||
<nyaa:category>Anime - English-translated</nyaa:category>
|
||||
<nyaa:size>5.7 GiB</nyaa:size>
|
||||
<nyaa:comments>2</nyaa:comments>
|
||||
<nyaa:trusted>No</nyaa:trusted>
|
||||
<nyaa:remake>No</nyaa:remake>
|
||||
<description>
|
||||
<![CDATA[ <a href="https://nyaa.si/view/1424895">#1424895 | Macross Zero (BDRip 1920x1080p x265 HEVC TrueHD, FLAC 5.1+2.0)[sxales]</a> | 5.7 GiB | Anime - English-translated | 26F37F26D5B3475B41A98DC575FABFA6F8D32A76 ]]>
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Fumetsu no Anata e - 19 [WEBDL 1080p] Ukr DVO</title>
|
||||
<link>https://nyaa.si/download/1424887.torrent</link>
|
||||
<guid isPermaLink="true">https://nyaa.si/view/1424887</guid>
|
||||
<pubDate>Tue, 24 Aug 2021 21:23:06 -0000</pubDate>
|
||||
<nyaa:seeders>5</nyaa:seeders>
|
||||
<nyaa:leechers>4</nyaa:leechers>
|
||||
<nyaa:downloads>4</nyaa:downloads>
|
||||
<nyaa:infoHash>3e4300e24b39983802162877755aab4380bd137a</nyaa:infoHash>
|
||||
<nyaa:categoryId>1_3</nyaa:categoryId>
|
||||
<nyaa:category>Anime - Non-English-translated</nyaa:category>
|
||||
<nyaa:size>1.4 GiB</nyaa:size>
|
||||
<nyaa:comments>0</nyaa:comments>
|
||||
<nyaa:trusted>No</nyaa:trusted>
|
||||
<nyaa:remake>No</nyaa:remake>
|
||||
<description>
|
||||
<![CDATA[ <a href="https://nyaa.si/view/1424887">#1424887 | Fumetsu no Anata e - 19 [WEBDL 1080p] Ukr DVO</a> | 1.4 GiB | Anime - Non-English-translated | 3E4300E24B39983802162877755AAB4380BD137A ]]>
|
||||
</description>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -35,6 +35,11 @@
|
||||
"title": "Avengers: Endgame",
|
||||
"year": 2019,
|
||||
"Guid": []
|
||||
},
|
||||
{
|
||||
"type": "movie",
|
||||
"title": "Avengers",
|
||||
"year": 2005
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_delete_unorphaned_credit_items()
|
||||
public void should_not_delete_unorphaned_collection_items()
|
||||
{
|
||||
var collection = Builder<MovieCollection>.CreateNew()
|
||||
.With(h => h.Id = 3)
|
||||
|
||||
@@ -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>());
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ namespace NzbDrone.Core.Test.IndexerTests.NyaaTests
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
/* [Test]
|
||||
// Legacy Nyaa feed test
|
||||
|
||||
public void should_parse_recent_feed_from_Nyaa()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Nyaa/Nyaa.xml");
|
||||
@@ -53,6 +55,35 @@ namespace NzbDrone.Core.Test.IndexerTests.NyaaTests
|
||||
torrentInfo.MagnetUrl.Should().Be(null);
|
||||
torrentInfo.Peers.Should().Be(2 + 1);
|
||||
torrentInfo.Seeders.Should().Be(1);
|
||||
}*/
|
||||
|
||||
[Test]
|
||||
public void should_parse_2021_recent_feed_from_Nyaa()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Nyaa/Nyaa2021.xml");
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(3);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
var torrentInfo = releases.First() as TorrentInfo;
|
||||
|
||||
torrentInfo.Title.Should().Be("[Foxy-Subs] Mahouka Koukou no Yuutousei - 08 [720p] [3194D881].mkv");
|
||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
torrentInfo.DownloadUrl.Should().Be("https://nyaa.si/download/1424896.torrent");
|
||||
torrentInfo.InfoUrl.Should().Be("https://nyaa.si/view/1424896");
|
||||
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
|
||||
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("Tue, 24 Aug 2021 22:18:46"));
|
||||
torrentInfo.Size.Should().Be(639211930); //609.6 MiB
|
||||
torrentInfo.MagnetUrl.Should().Be(null);
|
||||
torrentInfo.Seeders.Should().Be(4);
|
||||
torrentInfo.Peers.Should().Be(3 + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Exceptions;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Movies.Collections;
|
||||
using NzbDrone.Core.Movies.Commands;
|
||||
using NzbDrone.Core.Movies.Credits;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
@@ -19,6 +20,7 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
public class RefreshMovieServiceFixture : CoreTest<RefreshMovieService>
|
||||
{
|
||||
private MovieMetadata _movie;
|
||||
private MovieCollection _movieCollection;
|
||||
private Movie _existingMovie;
|
||||
|
||||
[SetUp]
|
||||
@@ -28,6 +30,9 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
.With(s => s.Status = MovieStatusType.Released)
|
||||
.Build();
|
||||
|
||||
_movieCollection = Builder<MovieCollection>.CreateNew()
|
||||
.Build();
|
||||
|
||||
_existingMovie = Builder<Movie>.CreateNew()
|
||||
.With(s => s.MovieMetadata.Value.Status = MovieStatusType.Released)
|
||||
.Build();
|
||||
@@ -40,6 +45,10 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
.Setup(s => s.Get(_movie.Id))
|
||||
.Returns(_movie);
|
||||
|
||||
Mocker.GetMock<IAddMovieCollectionService>()
|
||||
.Setup(v => v.AddMovieCollection(It.IsAny<MovieCollection>()))
|
||||
.Returns(_movieCollection);
|
||||
|
||||
Mocker.GetMock<IProvideMovieInfo>()
|
||||
.Setup(s => s.GetMovieInfo(It.IsAny<int>()))
|
||||
.Callback<int>((i) => { throw new MovieNotFoundException(i); });
|
||||
|
||||
@@ -64,6 +64,11 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||
TestLogger.Info("OnRename was called");
|
||||
}
|
||||
|
||||
public override void OnMovieAdded(Movie movie)
|
||||
{
|
||||
TestLogger.Info("OnMovieAdded was called");
|
||||
}
|
||||
|
||||
public override void OnMovieFileDelete(MovieFileDeleteMessage message)
|
||||
{
|
||||
TestLogger.Info("OnMovieFileDelete was called");
|
||||
@@ -117,6 +122,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||
notification.SupportsOnDownload.Should().BeTrue();
|
||||
notification.SupportsOnUpgrade.Should().BeTrue();
|
||||
notification.SupportsOnRename.Should().BeTrue();
|
||||
notification.SupportsOnMovieAdded.Should().BeTrue();
|
||||
notification.SupportsOnMovieDelete.Should().BeTrue();
|
||||
notification.SupportsOnMovieFileDelete.Should().BeTrue();
|
||||
notification.SupportsOnMovieFileDeleteForUpgrade.Should().BeTrue();
|
||||
@@ -133,6 +139,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||
notification.SupportsOnDownload.Should().BeFalse();
|
||||
notification.SupportsOnUpgrade.Should().BeFalse();
|
||||
notification.SupportsOnRename.Should().BeFalse();
|
||||
notification.SupportsOnMovieAdded.Should().BeFalse();
|
||||
notification.SupportsOnMovieDelete.Should().BeFalse();
|
||||
notification.SupportsOnMovieFileDelete.Should().BeFalse();
|
||||
notification.SupportsOnMovieFileDeleteForUpgrade.Should().BeFalse();
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
||||
.Returns(new List<CustomFormat>());
|
||||
|
||||
Mocker.GetMock<IMovieTranslationService>()
|
||||
.Setup(v => v.GetAllTranslationsForMovie(It.IsAny<int>()))
|
||||
.Setup(v => v.GetAllTranslationsForMovieMetadata(It.IsAny<int>()))
|
||||
.Returns(_movieTranslations);
|
||||
}
|
||||
|
||||
|
||||
@@ -163,6 +163,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
|
||||
[TestCase("Movie.Title.1994.Dublado.1080p.XviD-LOL")]
|
||||
[TestCase("Movie.Title.2.2019.1080p.Bluray.Dublado.WWW.TPF.GRATIS")]
|
||||
[TestCase("Movie.Title.2014.1080p.Bluray.Brazilian.WWW.TPF.GRATIS")]
|
||||
public void should_parse_language_brazilian_portuguese(string postTitle)
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
@@ -261,6 +261,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
[TestCase("Movie.Name.2016.German.DTS.DL.1080p.UHDBD.x265-TDO.mkv", false)]
|
||||
[TestCase("Movie.Name.2021.1080p.BDLight.x265-AVCDVD", false)]
|
||||
[TestCase("Random.Title.2010.1080p.HD.DVD.AVC.DDP.5.1-GRouP", false)]
|
||||
[TestCase("Movie.Title.2012.German.DL.1080p.UHD2BD.x264-QfG", false)]
|
||||
public void should_parse_bluray1080p_quality(string title, bool proper)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Source.BLURAY, proper, Resolution.R1080p);
|
||||
|
||||
@@ -99,6 +99,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
[TestCase("Crappy Anime Movie Name 2017 [RH] [Blu-ray][MKV][h264 10-bit][1080p][FLAC 5.1][Dual Audio][Softsubs (RH)]", "RH")]
|
||||
[TestCase("Yet Another Anime Movie 2012 [Kametsu] [Blu-ray][MKV][h264 10-bit][1080p][FLAC 5.1][Dual Audio][Softsubs (Kametsu)]", "Kametsu")]
|
||||
[TestCase("Another.Anime.Film.Name.2016.JPN.Blu-Ray.Remux.AVC.DTS-MA.BluDragon", "BluDragon")]
|
||||
[TestCase("A Movie in the Name (1964) (1080p BluRay x265 r00t)", "r00t")]
|
||||
public void should_parse_exception_release_group(string title, string expected)
|
||||
{
|
||||
Parser.Parser.ParseReleaseGroup(title).Should().Be(expected);
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -45,11 +45,13 @@ namespace NzbDrone.Core.Configuration
|
||||
string SslCertPassword { get; }
|
||||
string UrlBase { get; }
|
||||
string UiFolder { get; }
|
||||
string InstanceName { get; }
|
||||
bool UpdateAutomatically { get; }
|
||||
UpdateMechanism UpdateMechanism { get; }
|
||||
string UpdateScriptPath { get; }
|
||||
string SyslogServer { get; }
|
||||
int SyslogPort { get; }
|
||||
string SyslogLevel { get; }
|
||||
string PostgresHost { get; }
|
||||
int PostgresPort { get; }
|
||||
string PostgresUser { get; }
|
||||
@@ -223,6 +225,7 @@ namespace NzbDrone.Core.Configuration
|
||||
}
|
||||
|
||||
public string UiFolder => BuildInfo.IsDebug ? Path.Combine("..", "UI") : "UI";
|
||||
public string InstanceName => GetValue("InstanceName", BuildInfo.AppName);
|
||||
|
||||
public bool UpdateAutomatically => GetValueBoolean("UpdateAutomatically", false, false);
|
||||
|
||||
@@ -231,8 +234,11 @@ namespace NzbDrone.Core.Configuration
|
||||
public string UpdateScriptPath => GetValue("UpdateScriptPath", "", false);
|
||||
|
||||
public string SyslogServer => GetValue("SyslogServer", "", persist: false);
|
||||
|
||||
public int SyslogPort => GetValueInt("SyslogPort", 514, persist: false);
|
||||
|
||||
public string SyslogLevel => GetValue("SyslogLevel", LogLevel, false).ToLowerInvariant();
|
||||
|
||||
public int GetValueInt(string key, int defaultValue, bool persist = true)
|
||||
{
|
||||
return Convert.ToInt32(GetValue(key, defaultValue, persist));
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class ReleaseGroupSpecification : RegexSpecificationBase
|
||||
{
|
||||
public override int Order => 9;
|
||||
public override string ImplementationName => "Release Group";
|
||||
public override string InfoLink => "https://wiki.servarr.com/radarr/settings#custom-formats-2";
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
{
|
||||
return MatchString(movieInfo?.ReleaseGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,9 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
.WithColumn("Genres").AsString().Nullable()
|
||||
.WithColumn("Title").AsString()
|
||||
.WithColumn("SortTitle").AsString().Nullable()
|
||||
.WithColumn("CleanTitle").AsString().Indexed()
|
||||
.WithColumn("OriginalTitle").AsString()
|
||||
.WithColumn("CleanOriginalTitle").AsString().Indexed()
|
||||
.WithColumn("CleanTitle").AsString().Nullable().Indexed()
|
||||
.WithColumn("OriginalTitle").AsString().Nullable()
|
||||
.WithColumn("CleanOriginalTitle").AsString().Nullable().Indexed()
|
||||
.WithColumn("OriginalLanguage").AsInt32()
|
||||
.WithColumn("Status").AsInt32()
|
||||
.WithColumn("LastInfoSync").AsDateTime().Nullable()
|
||||
@@ -28,7 +28,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
.WithColumn("Year").AsInt32().Nullable()
|
||||
.WithColumn("SecondaryYear").AsInt32().Nullable()
|
||||
.WithColumn("Ratings").AsString().Nullable()
|
||||
.WithColumn("Recommendations").AsString().Nullable()
|
||||
.WithColumn("Recommendations").AsString()
|
||||
.WithColumn("Certification").AsString().Nullable()
|
||||
.WithColumn("YouTubeTrailerId").AsString().Nullable()
|
||||
.WithColumn("Collection").AsString().Nullable()
|
||||
@@ -43,10 +43,11 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
FROM ""Movies""");
|
||||
|
||||
// Transfer metadata from ImportListMovies to MovieMetadata if not already in
|
||||
Execute.Sql(@"INSERT INTO ""MovieMetadata"" (""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""CleanTitle"", ""OriginalTitle"", ""CleanOriginalTitle"", ""OriginalLanguage"", ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website"")
|
||||
SELECT ""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""Title"", ""OriginalTitle"", ""OriginalTitle"", 1, ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website""
|
||||
Execute.Sql(@"INSERT INTO ""MovieMetadata"" (""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""CleanTitle"", ""OriginalTitle"", ""CleanOriginalTitle"", ""OriginalLanguage"", ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", ""Recommendations"", ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website"")
|
||||
SELECT ""TmdbId"", ""ImdbId"", ""Title"", ""SortTitle"", ""Title"", ""OriginalTitle"", ""OriginalTitle"", 1, ""Overview"", ""Status"", ""LastInfoSync"", ""Images"", ""Genres"", ""Ratings"", ""Runtime"", ""InCinemas"", ""PhysicalRelease"", ""DigitalRelease"", ""Year"", '[]', ""Certification"", ""YouTubeTrailerId"", ""Studio"", ""Collection"", ""Website""
|
||||
FROM ""ImportListMovies""
|
||||
WHERE ""ImportListMovies"".""TmdbId"" NOT IN ( SELECT ""MovieMetadata"".""TmdbId"" FROM ""MovieMetadata"" )");
|
||||
WHERE ""ImportListMovies"".""TmdbId"" NOT IN ( SELECT ""MovieMetadata"".""TmdbId"" FROM ""MovieMetadata"" )
|
||||
AND ""ImportListMovies"".""Id"" IN ( SELECT MIN(""Id"") FROM ""ImportListMovies"" GROUP BY ""TmdbId"" )");
|
||||
|
||||
// Add an MovieMetadataId column to Movies
|
||||
Alter.Table("Movies").AddColumn("MovieMetadataId").AsInt32().WithDefaultValue(0);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(209)]
|
||||
public class movie_meta_collection_index : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Create.Index("IX_MovieMetadata_CollectionTmdbId").OnTable("MovieMetadata").OnColumn("CollectionTmdbId");
|
||||
Create.Index("IX_MovieTranslations_MovieMetadataId").OnTable("MovieTranslations").OnColumn("MovieMetadataId");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(210)]
|
||||
public class movie_added_notifications : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Notifications").AddColumn("OnMovieAdded").AsBoolean().WithDefaultValue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,7 @@ namespace NzbDrone.Core.Datastore
|
||||
.Ignore(i => i.SupportsOnDownload)
|
||||
.Ignore(i => i.SupportsOnUpgrade)
|
||||
.Ignore(i => i.SupportsOnRename)
|
||||
.Ignore(i => i.SupportsOnMovieAdded)
|
||||
.Ignore(i => i.SupportsOnMovieDelete)
|
||||
.Ignore(i => i.SupportsOnMovieFileDelete)
|
||||
.Ignore(i => i.SupportsOnMovieFileDeleteForUpgrade)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace NzbDrone.Core.Download
|
||||
return;
|
||||
}
|
||||
|
||||
var importResults = _downloadedMovieImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteMovie.Movie, trackedDownload.DownloadItem);
|
||||
var importResults = _downloadedMovieImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteMovie.Movie, trackedDownload.ImportItem);
|
||||
|
||||
if (VerifyImport(trackedDownload, importResults))
|
||||
{
|
||||
|
||||
@@ -126,11 +126,11 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||
(int)movie.MovieMetadata.Value.OriginalLanguage :
|
||||
Settings.MovieMetadataLanguage;
|
||||
|
||||
var movieTranslations = _movieTranslationsService.GetAllTranslationsForMovie(movie.Id);
|
||||
var movieTranslations = _movieTranslationsService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId);
|
||||
var selectedSettingsLanguage = Language.FindById(movieMetadataLanguage);
|
||||
var movieTranslation = movieTranslations.FirstOrDefault(mt => mt.Language == selectedSettingsLanguage);
|
||||
|
||||
var credits = _creditService.GetAllCreditsForMovie(movie.MovieMetadataId);
|
||||
var credits = _creditService.GetAllCreditsForMovieMetadata(movie.MovieMetadataId);
|
||||
|
||||
var watched = GetExistingWatchedStatus(movie, movieFile.RelativePath);
|
||||
|
||||
|
||||
@@ -20,8 +20,9 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||
WHERE ""Id"" IN (
|
||||
SELECT ""MovieMetadata"".""Id"" FROM ""MovieMetadata""
|
||||
LEFT OUTER JOIN ""Movies"" ON ""Movies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
|
||||
LEFT OUTER JOIN ""Collections"" ON ""Collections"".""TmdbId"" = ""MovieMetadata"".""CollectionTmdbId""
|
||||
LEFT OUTER JOIN ""ImportListMovies"" ON ""ImportListMovies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
|
||||
WHERE ""Movies"".""Id"" IS NULL AND ""ImportListMovies"".""Id"" IS NULL)");
|
||||
WHERE ""Movies"".""Id"" IS NULL AND ""ImportListMovies"".""Id"" IS NULL AND ""Collections"".""Id"" IS NULL)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,12 +177,12 @@ namespace NzbDrone.Core.ImportLists
|
||||
{
|
||||
var mappedMovie = _movieSearch.MapMovieToTmdbMovie(new MovieMetadata { Title = report.Title, TmdbId = report.TmdbId, ImdbId = report.ImdbId, Year = report.Year });
|
||||
|
||||
_movieMetadataService.Upsert(mappedMovie);
|
||||
|
||||
var mappedListMovie = new ImportListMovie { ListId = report.ListId };
|
||||
|
||||
if (mappedMovie != null)
|
||||
{
|
||||
_movieMetadataService.Upsert(mappedMovie);
|
||||
|
||||
mappedListMovie.MovieMetadata = mappedMovie;
|
||||
mappedListMovie.MovieMetadataId = mappedMovie.Id;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,8 @@ namespace NzbDrone.Core.ImportLists
|
||||
AddOptions = new AddMovieOptions
|
||||
{
|
||||
SearchForMovie = monitorType != MonitorTypes.None && importList.SearchOnAdd,
|
||||
Monitor = monitorType
|
||||
Monitor = monitorType,
|
||||
AddMethod = AddMovieMethod.List
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
public List<DownloadDecision> MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch)
|
||||
{
|
||||
var movie = _movieService.GetMovie(movieId);
|
||||
movie.MovieMetadata.Value.Translations = _movieTranslationService.GetAllTranslationsForMovie(movie.Id);
|
||||
movie.MovieMetadata.Value.Translations = _movieTranslationService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId);
|
||||
|
||||
return MovieSearch(movie, userInvokedSearch, interactiveSearch);
|
||||
}
|
||||
@@ -77,7 +77,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
};
|
||||
|
||||
var wantedLanguages = _profileService.GetAcceptableLanguages(movie.ProfileId);
|
||||
var translations = _movieTranslationService.GetAllTranslationsForMovie(movie.Id);
|
||||
var translations = _movieTranslationService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId);
|
||||
|
||||
var queryTranlations = new List<string>
|
||||
{
|
||||
|
||||
@@ -12,6 +12,10 @@ namespace NzbDrone.Core.Indexers
|
||||
UseGuidInfoUrl = true;
|
||||
UseEnclosureLength = false;
|
||||
UseEnclosureUrl = true;
|
||||
SeedsElementName = "seeds";
|
||||
InfoHashElementName = "infoHash";
|
||||
SizeElementName = "contentLength";
|
||||
MagnetElementName = "magnetURI";
|
||||
}
|
||||
|
||||
protected override bool PreProcess(IndexerResponse indexerResponse)
|
||||
@@ -26,51 +30,5 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
return base.PreProcess(indexerResponse);
|
||||
}
|
||||
|
||||
protected override long GetSize(XElement item)
|
||||
{
|
||||
var contentLength = item.FindDecendants("contentLength").SingleOrDefault();
|
||||
|
||||
if (contentLength != null)
|
||||
{
|
||||
return (long)contentLength;
|
||||
}
|
||||
|
||||
return base.GetSize(item);
|
||||
}
|
||||
|
||||
protected override string GetInfoHash(XElement item)
|
||||
{
|
||||
var infoHash = item.FindDecendants("infoHash").SingleOrDefault();
|
||||
return (string)infoHash;
|
||||
}
|
||||
|
||||
protected override string GetMagnetUrl(XElement item)
|
||||
{
|
||||
var magnetURI = item.FindDecendants("magnetURI").SingleOrDefault();
|
||||
return (string)magnetURI;
|
||||
}
|
||||
|
||||
protected override int? GetSeeders(XElement item)
|
||||
{
|
||||
var seeds = item.FindDecendants("seeds").SingleOrDefault();
|
||||
if (seeds != null)
|
||||
{
|
||||
return (int)seeds;
|
||||
}
|
||||
|
||||
return base.GetSeeders(item);
|
||||
}
|
||||
|
||||
protected override int? GetPeers(XElement item)
|
||||
{
|
||||
var peers = item.FindDecendants("peers").SingleOrDefault();
|
||||
if (peers != null)
|
||||
{
|
||||
return (int)peers;
|
||||
}
|
||||
|
||||
return base.GetPeers(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace NzbDrone.Core.Indexers.Nyaa
|
||||
|
||||
public override IParseIndexerResponse GetParser()
|
||||
{
|
||||
return new TorrentRssParser() { UseGuidInfoUrl = true, ParseSizeInDescription = true, ParseSeedersInDescription = true };
|
||||
return new TorrentRssParser() { UseGuidInfoUrl = true, SizeElementName = "size", InfoHashElementName = "infoHash", PeersElementName = "leechers", CalculatePeersAsSum = true, SeedsElementName = "seeders" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using MonoTorrent;
|
||||
@@ -9,12 +10,27 @@ namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
public class TorrentRssParser : RssParser
|
||||
{
|
||||
// Use to sum/calculate Peers as Leechers+Seeders
|
||||
public bool CalculatePeersAsSum { get; set; } = false;
|
||||
|
||||
// Use the specified element name to determine the Infohash
|
||||
public string InfoHashElementName { get; set; }
|
||||
|
||||
// Parse various seeder/leecher/peers formats in the description element to determine number of seeders.
|
||||
public bool ParseSeedersInDescription { get; set; }
|
||||
|
||||
// Use the specified element name to determine the size
|
||||
// Use the specified element name to determine the Peers
|
||||
public string PeersElementName { get; set; }
|
||||
|
||||
// Use the specified element name to determine the Seeds
|
||||
public string SeedsElementName { get; set; }
|
||||
|
||||
// Use the specified element name to determine the Size
|
||||
public string SizeElementName { get; set; }
|
||||
|
||||
// Use the specified element name to determine the Magnet link
|
||||
public string MagnetElementName { get; set; }
|
||||
|
||||
public TorrentRssParser()
|
||||
{
|
||||
PreferredEnclosureMimeTypes = TorrentEnclosureMimeTypes;
|
||||
@@ -40,14 +56,28 @@ namespace NzbDrone.Core.Indexers
|
||||
result.InfoHash = GetInfoHash(item);
|
||||
result.MagnetUrl = GetMagnetUrl(item);
|
||||
result.Seeders = GetSeeders(item);
|
||||
result.Peers = GetPeers(item);
|
||||
|
||||
if (CalculatePeersAsSum)
|
||||
{
|
||||
result.Peers = GetPeers(item) + result.Seeders;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Peers = GetPeers(item);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected virtual string GetInfoHash(XElement item)
|
||||
{
|
||||
if (InfoHashElementName.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return item.FindDecendants(InfoHashElementName).FirstOrDefault().Value;
|
||||
}
|
||||
|
||||
var magnetUrl = GetMagnetUrl(item);
|
||||
|
||||
if (magnetUrl.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
try
|
||||
@@ -64,10 +94,21 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
protected virtual string GetMagnetUrl(XElement item)
|
||||
{
|
||||
var downloadUrl = GetDownloadUrl(item);
|
||||
if (downloadUrl.IsNotNullOrWhiteSpace() && downloadUrl.StartsWith("magnet:"))
|
||||
if (MagnetElementName.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return downloadUrl;
|
||||
var magnetURL = item.FindDecendants(MagnetElementName).FirstOrDefault().Value;
|
||||
if (magnetURL.IsNotNullOrWhiteSpace() && magnetURL.StartsWith("magnet:"))
|
||||
{
|
||||
return magnetURL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var downloadUrl = GetDownloadUrl(item);
|
||||
if (downloadUrl.IsNotNullOrWhiteSpace() && downloadUrl.StartsWith("magnet:"))
|
||||
{
|
||||
return downloadUrl;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -75,6 +116,8 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
protected virtual int? GetSeeders(XElement item)
|
||||
{
|
||||
// safe to always use the element if it's present (and valid)
|
||||
// fall back to description if ParseSeedersInDescription is enabled
|
||||
if (ParseSeedersInDescription && item.Element("description") != null)
|
||||
{
|
||||
var matchSeeders = ParseSeedersRegex.Match(item.Element("description").Value);
|
||||
@@ -93,6 +136,12 @@ namespace NzbDrone.Core.Indexers
|
||||
}
|
||||
}
|
||||
|
||||
var seeds = item.FindDecendants(SeedsElementName).SingleOrDefault();
|
||||
if (seeds != null)
|
||||
{
|
||||
return (int)seeds;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -116,6 +165,12 @@ namespace NzbDrone.Core.Indexers
|
||||
}
|
||||
}
|
||||
|
||||
if (PeersElementName.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
var itempeers = item.FindDecendants(PeersElementName).SingleOrDefault();
|
||||
return int.Parse(itempeers.Value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -124,9 +179,10 @@ namespace NzbDrone.Core.Indexers
|
||||
var size = base.GetSize(item);
|
||||
if (size == 0 && SizeElementName.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
if (item.Element(SizeElementName) != null)
|
||||
var itemsize = item.FindDecendants(SizeElementName).SingleOrDefault();
|
||||
if (itemsize != null)
|
||||
{
|
||||
size = ParseSize(item.Element(SizeElementName).Value, true);
|
||||
size = ParseSize(itemsize.Value, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ namespace NzbDrone.Core.Instrumentation
|
||||
|
||||
if (_configFileProvider.SyslogServer.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
SetSyslogParameters(_configFileProvider.SyslogServer, _configFileProvider.SyslogPort, minimumLogLevel);
|
||||
var syslogLevel = LogLevel.FromString(_configFileProvider.SyslogLevel);
|
||||
SetSyslogParameters(_configFileProvider.SyslogServer, _configFileProvider.SyslogPort, syslogLevel);
|
||||
}
|
||||
|
||||
var rules = LogManager.Configuration.LoggingRules;
|
||||
@@ -118,7 +119,7 @@ namespace NzbDrone.Core.Instrumentation
|
||||
syslogTarget.MessageSend.Udp.Server = syslogServer;
|
||||
syslogTarget.MessageSend.Udp.ReconnectInterval = 500;
|
||||
syslogTarget.MessageCreation.Rfc = RfcNumber.Rfc5424;
|
||||
syslogTarget.MessageCreation.Rfc5424.AppName = BuildInfo.AppName;
|
||||
syslogTarget.MessageCreation.Rfc5424.AppName = _configFileProvider.InstanceName;
|
||||
|
||||
var loggingRule = new LoggingRule("*", minimumLogLevel, syslogTarget);
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace NzbDrone.Core.Jobs
|
||||
|
||||
new ScheduledTask
|
||||
{
|
||||
Interval = Math.Max(_configService.CheckForFinishedDownloadInterval, 1),
|
||||
Interval = GetRefreshMonitoredInterval(),
|
||||
TypeName = typeof(RefreshMonitoredDownloadsCommand).FullName,
|
||||
Priority = CommandPriority.High
|
||||
}
|
||||
@@ -198,6 +198,18 @@ namespace NzbDrone.Core.Jobs
|
||||
return interval;
|
||||
}
|
||||
|
||||
private int GetRefreshMonitoredInterval()
|
||||
{
|
||||
var interval = _configService.CheckForFinishedDownloadInterval;
|
||||
|
||||
if (interval < 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
private int GetImportListSyncInterval()
|
||||
{
|
||||
//Enforce 6 hour min on list sync
|
||||
@@ -218,6 +230,7 @@ namespace NzbDrone.Core.Jobs
|
||||
|
||||
_scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, lastExecution, message.Command.StartedAt.Value);
|
||||
_cache.Find(scheduledTask.TypeName).LastExecution = lastExecution;
|
||||
_cache.Find(scheduledTask.TypeName).LastStartTime = message.Command.StartedAt.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,13 +246,14 @@ namespace NzbDrone.Core.Jobs
|
||||
backup.Interval = GetBackupInterval();
|
||||
|
||||
var refreshMonitoredDownloads = _scheduledTaskRepository.GetDefinition(typeof(RefreshMonitoredDownloadsCommand));
|
||||
refreshMonitoredDownloads.Interval = _configService.CheckForFinishedDownloadInterval;
|
||||
refreshMonitoredDownloads.Interval = GetRefreshMonitoredInterval();
|
||||
|
||||
_scheduledTaskRepository.UpdateMany(new List<ScheduledTask> { rss, importList, refreshMonitoredDownloads, backup });
|
||||
|
||||
_cache.Find(rss.TypeName).Interval = rss.Interval;
|
||||
_cache.Find(importList.TypeName).Interval = importList.Interval;
|
||||
_cache.Find(backup.TypeName).Interval = backup.Interval;
|
||||
_cache.Find(refreshMonitoredDownloads.TypeName).Interval = refreshMonitoredDownloads.Interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"Yesterday": "في الامس",
|
||||
"YesMoveFiles": "نعم ، انقل الملفات",
|
||||
"YesCancel": "نعم إلغاء",
|
||||
"Yes": "نعم",
|
||||
"Year": "عام",
|
||||
"WouldYouLikeToRestoreBackup": "هل ترغب في استعادة النسخة الاحتياطية {0}؟",
|
||||
"Wiki": "ويكي",
|
||||
@@ -294,7 +293,6 @@
|
||||
"NoChange": "لا تغيير",
|
||||
"NoBackupsAreAvailable": "لا توجد نسخ احتياطية متاحة",
|
||||
"NoAltTitle": "لا توجد عناوين بديلة.",
|
||||
"No": "لا",
|
||||
"NextExecution": "التنفيذ القادم",
|
||||
"New": "جديد",
|
||||
"NetCore": ".شبكة",
|
||||
@@ -437,7 +435,6 @@
|
||||
"History": "التاريخ",
|
||||
"HideAdvanced": "إخفاء الإعدادات المتقدمة",
|
||||
"HiddenClickToShow": "مخفي ، انقر للعرض",
|
||||
"HelpText": "الفاصل بالدقائق. اضبط على صفر للتعطيل (سيؤدي هذا إلى إيقاف كل عمليات الاستيلاء على التحرير التلقائي)",
|
||||
"HealthNoIssues": "لا مشاكل مع التكوين الخاص بك",
|
||||
"Health": "الصحة",
|
||||
"HaveNotAddedMovies": "لم تقم بإضافة أي أفلام بعد ، هل تريد استيراد بعض أو كل أفلامك أولاً؟",
|
||||
@@ -1016,7 +1013,6 @@
|
||||
"DownloadClientCheckNoneAvailableMessage": "لا يوجد عميل تنزيل متاح",
|
||||
"AddNewMessage": "من السهل إضافة فيلم جديد ، فقط ابدأ بكتابة اسم الفيلم الذي تريد إضافته",
|
||||
"AddNew": "اضف جديد",
|
||||
"AddMoviesMonitored": "إضافة أفلام مراقبتها",
|
||||
"AddMovies": "اضافة افلام",
|
||||
"AddMovie": "اضافة فيلم",
|
||||
"AddListExclusion": "إضافة استبعاد قائمة",
|
||||
@@ -1062,5 +1058,10 @@
|
||||
"Rating": "التقييمات",
|
||||
"RemotePath": "مسار بعيد",
|
||||
"Filters": "منقي",
|
||||
"LocalPath": "مسار محلي"
|
||||
"LocalPath": "مسار محلي",
|
||||
"MonitorMovies": "مراقبة الفيلم",
|
||||
"NoCollections": "لم يتم العثور على أفلام ، للبدء ، ستحتاج إلى إضافة فيلم جديد أو استيراد بعض الأفلام الموجودة.",
|
||||
"RssSyncHelpText": "الفاصل بالدقائق. اضبط على صفر للتعطيل (سيؤدي هذا إلى إيقاف كل عمليات الاستيلاء على التحرير التلقائي)",
|
||||
"AllCollectionsHiddenDueToFilter": "جميع الأفلام مخفية بسبب الفلتر المطبق.",
|
||||
"Collections": "مجموعة"
|
||||
}
|
||||
|
||||
@@ -285,7 +285,6 @@
|
||||
"HardlinkCopyFiles": "Твърда връзка / копиране на файлове",
|
||||
"Health": "Здраве",
|
||||
"HealthNoIssues": "Няма проблеми с вашата конфигурация",
|
||||
"HelpText": "Интервал за минути. Задайте на нула, за да деактивирате (това ще спре всички автоматично хващане на освобождаване)",
|
||||
"HiddenClickToShow": "Скрито, кликнете за показване",
|
||||
"ImportExtraFiles": "Импортиране на допълнителни файлове",
|
||||
"ImportFailed": "Неуспешно импортиране: {0}",
|
||||
@@ -712,7 +711,6 @@
|
||||
"Wiki": "Wiki",
|
||||
"WouldYouLikeToRestoreBackup": "Искате ли да възстановите архива {0}?",
|
||||
"Year": "Година",
|
||||
"Yes": "Да",
|
||||
"YesCancel": "Да, Отказ",
|
||||
"YesMoveFiles": "Да, премести файловете",
|
||||
"Yesterday": "Вчера",
|
||||
@@ -769,7 +767,6 @@
|
||||
"MovieIsMonitored": "Филмът се следи",
|
||||
"RadarrUpdated": "Радар актуализиран",
|
||||
"AddListExclusion": "Добавяне на изключване от списъка",
|
||||
"AddMoviesMonitored": "Добавяне на контролирани филми",
|
||||
"AddNewMovie": "Добавяне на нов филм",
|
||||
"AddNewTmdbIdMessage": "Можете също да търсите с помощта на TMDb Id на филм. напр. 'tmdb: 71663'",
|
||||
"AddRemotePathMapping": "Добавете отдалечено картографиране на пътя",
|
||||
@@ -964,7 +961,6 @@
|
||||
"MustNotContain": "Не трябва да съдържа",
|
||||
"NamingSettings": "Настройки за именуване",
|
||||
"NetCore": ".NET Core",
|
||||
"No": "Не",
|
||||
"NoBackupsAreAvailable": "Няма налични резервни копия",
|
||||
"NoChange": "Няма промяна",
|
||||
"NoHistory": "Няма история",
|
||||
@@ -1061,5 +1057,10 @@
|
||||
"RemotePath": "Отдалечен път",
|
||||
"List": "Списъци",
|
||||
"LocalPath": "Местен път",
|
||||
"SelectLanguages": "Избери език"
|
||||
"SelectLanguages": "Избери език",
|
||||
"MonitorMovies": "Монитор на филм",
|
||||
"AllCollectionsHiddenDueToFilter": "Всички филми са скрити поради приложен филтър.",
|
||||
"Collections": "колекция",
|
||||
"NoCollections": "Не са намерени филми, за да започнете, ще искате да добавите нов филм или да импортирате някои съществуващи.",
|
||||
"RssSyncHelpText": "Интервал за минути. Задайте на нула, за да деактивирате (това ще спре всички автоматично хващане на освобождаване)"
|
||||
}
|
||||
|
||||
@@ -292,7 +292,6 @@
|
||||
"ImportNotForDownloads": "Nepoužívejte k importu souborů ke stažení z vašeho klienta pro stahování, toto je pouze pro existující organizované knihovny, nikoli pro netříděné soubory.",
|
||||
"GrabReleaseMessageText": "Radarr nebyl schopen určit, pro který film je toto vydání určeno. Radarr nemusí být schopen toto vydání automaticky importovat. Chcete chytit „{0}“?",
|
||||
"GrabSelected": "Chyťte vybrané",
|
||||
"HelpText": "Interval v minutách. Nastavením na nulu deaktivujete (tím se zastaví veškeré automatické uvolnění uvolnění)",
|
||||
"HiddenClickToShow": "Skryté, kliknutím zobrazíte",
|
||||
"ImportMechanismHealthCheckMessage": "Povolit zpracování dokončeného stahování",
|
||||
"NoResultsFound": "Nebyly nalezeny žádné výsledky",
|
||||
@@ -421,7 +420,6 @@
|
||||
"MustNotContain": "Nesmí obsahovat",
|
||||
"NamingSettings": "Nastavení pojmenování",
|
||||
"NetCore": ".NET Core",
|
||||
"No": "Ne",
|
||||
"NoBackupsAreAvailable": "Nejsou k dispozici žádné zálohy",
|
||||
"NoChange": "Žádná změna",
|
||||
"NoHistory": "Žádná historie",
|
||||
@@ -438,7 +436,6 @@
|
||||
"Overview": "Přehled",
|
||||
"Failed": "Selhalo",
|
||||
"AddMovies": "Přidat filmy",
|
||||
"AddMoviesMonitored": "Přidat sledované filmy",
|
||||
"AddingTag": "Přidávání značky",
|
||||
"AlternativeTitle": "Alternativní název",
|
||||
"AnalyseVideoFiles": "Analyzujte video soubory",
|
||||
@@ -1016,7 +1013,6 @@
|
||||
"Wiki": "Wiki",
|
||||
"WouldYouLikeToRestoreBackup": "Chcete obnovit zálohu {0}?",
|
||||
"Year": "Rok",
|
||||
"Yes": "Ano",
|
||||
"YesCancel": "Ano, zrušit",
|
||||
"YesMoveFiles": "Ano, přesuňte soubory",
|
||||
"Yesterday": "Včera",
|
||||
@@ -1061,5 +1057,10 @@
|
||||
"RemotePath": "Vzdálená cesta",
|
||||
"Rating": "Hodnocení",
|
||||
"List": "Seznamy",
|
||||
"SelectLanguages": "Zvolte jazyk"
|
||||
"SelectLanguages": "Zvolte jazyk",
|
||||
"AllCollectionsHiddenDueToFilter": "Všechny filmy jsou skryty kvůli použitému filtru.",
|
||||
"Collections": "Sbírka",
|
||||
"MonitorMovies": "Monitorujte film",
|
||||
"NoCollections": "Nebyly nalezeny žádné filmy. Chcete-li začít, budete chtít přidat nový film nebo importovat některé stávající.",
|
||||
"RssSyncHelpText": "Interval v minutách. Nastavením na nulu deaktivujete (tím se zastaví veškeré automatické uvolnění uvolnění)"
|
||||
}
|
||||
|
||||
@@ -408,7 +408,6 @@
|
||||
"MovieIsUnmonitored": "Filmen overvåges ikke",
|
||||
"Movies": "Film",
|
||||
"NetCore": ".NET Core",
|
||||
"No": "Ingen",
|
||||
"OnHealthIssueHelpText": "Om sundhedsspørgsmål",
|
||||
"OnRenameHelpText": "Om omdøb",
|
||||
"OnUpgradeHelpText": "Ved opgradering",
|
||||
@@ -457,7 +456,6 @@
|
||||
"AlreadyInYourLibrary": "Allerede i dit bibliotek",
|
||||
"RecycleBinCleanupDaysHelpTextWarning": "Filer i papirkurven, der er ældre end det valgte antal dage, renses automatisk",
|
||||
"AddListExclusion": "Tilføj ekskludering af liste",
|
||||
"AddMoviesMonitored": "Tilføj overvågede film",
|
||||
"AddingTag": "Tilføjer tag",
|
||||
"AgeWhenGrabbed": "Alder (når grebet)",
|
||||
"RefreshAndScan": "Opdater & Scan",
|
||||
@@ -641,7 +639,6 @@
|
||||
"GrabRelease": "Grab Release",
|
||||
"GrabReleaseMessageText": "Radarr var ikke i stand til at bestemme, hvilken film denne udgivelse var til. Radarr kan muligvis ikke automatisk importere denne udgivelse. Vil du hente '{0}'?",
|
||||
"Group": "Gruppe",
|
||||
"HelpText": "Interval på få minutter. Sæt til nul for at deaktivere (dette stopper al automatisk frigivelse)",
|
||||
"HiddenClickToShow": "Skjult, klik for at vise",
|
||||
"Host": "Vært",
|
||||
"iCalLink": "iCal Link",
|
||||
@@ -1016,7 +1013,6 @@
|
||||
"Wiki": "Wiki",
|
||||
"WouldYouLikeToRestoreBackup": "Vil du gendanne sikkerhedskopien {0}?",
|
||||
"Year": "År",
|
||||
"Yes": "Ja",
|
||||
"YesCancel": "Ja, Annuller",
|
||||
"YesMoveFiles": "Ja, flyt filerne",
|
||||
"Yesterday": "I går",
|
||||
@@ -1061,5 +1057,10 @@
|
||||
"RemotePath": "Fjern sti",
|
||||
"SelectLanguages": "Vælg sprog",
|
||||
"List": "Lister",
|
||||
"Rating": "Bedømmelser"
|
||||
"Rating": "Bedømmelser",
|
||||
"RssSyncHelpText": "Interval på få minutter. Sæt til nul for at deaktivere (dette stopper al automatisk frigivelse)",
|
||||
"MonitorMovies": "Overvåg film",
|
||||
"NoCollections": "Ingen film fundet. For at komme i gang vil du tilføje en ny film eller importere nogle eksisterende.",
|
||||
"AllCollectionsHiddenDueToFilter": "Alle film er gemt på grund af aktivt filter.",
|
||||
"Collections": "Samling"
|
||||
}
|
||||
|
||||
@@ -572,8 +572,6 @@
|
||||
"EnableMediaInfoHelpText": "Videoinformationen wie Auflösung, Laufzeit und Codec aus Datien erkennen. Dazu ist es erforderlich, dass Radarr Teile der Datei liest, was zu hoher Festplatten- oder Netzwerkaktivität während der Scans führen kann.",
|
||||
"ImportListSyncIntervalHelpText": "Wie oft die Listen synchronisiert werden sollen. Minimum 6 Stunden",
|
||||
"AddListExclusion": "Listenausschluss hinzufügen",
|
||||
"AddMoviesMonitored": "Filme beobachtet hinzufügen",
|
||||
"HelpText": "Intervall in Minuten. Zum deaktivieren auf 0 setzen ( Dies wird das automatische Release erfassen deaktivieren )",
|
||||
"RequiredHelpText": "Diese {0} Bedingungen müsen zutreffen damit das eigene Format zutrifft. Ansonsten reicht ein einzelner {1} Treffer.",
|
||||
"AllowHardcodedSubsHelpText": "Filme mit hartcodierten Untertiteln werden auch automatisch heruntergeladen",
|
||||
"ICalHttpUrlHelpText": "Füge diese URL in deinen Client ein oder klicke auf abonnieren wenn dein Browser Webcal untertützt",
|
||||
@@ -823,8 +821,6 @@
|
||||
"ListSyncLevelHelpTextWarning": "Filmdateien werden dauerhaft gelöcht, dies kann deine ganze Mediathek leeren wenn deine Listen leer sind",
|
||||
"ConsideredAvailable": "Verfügbarkeit angenommen",
|
||||
"Announced": "Angekündigt",
|
||||
"Yes": "Ja",
|
||||
"No": "Nein",
|
||||
"MappedDrivesRunningAsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Radarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen",
|
||||
"CouldNotConnectSignalR": "Es konnte keine Verbindung zu SignalR hergestellt werden, die Benutzeroberfläche wird nicht aktualisiert",
|
||||
"ChmodGroupHelpTextWarning": "Dies funktioniert nur, wenn der Benutzer, der Radarr ausführt, der Eigentümer der Datei ist. Es ist besser, sicherzustellen, dass der Download-Client die gleiche Gruppe wie Radarr verwendet.",
|
||||
@@ -1115,5 +1111,10 @@
|
||||
"Waiting": "warten",
|
||||
"OriginalTitle": "Originaler Titel",
|
||||
"OriginalLanguage": "Originale Sprache",
|
||||
"Database": "Datenbank"
|
||||
"Database": "Datenbank",
|
||||
"AllCollectionsHiddenDueToFilter": "Alle Filme sind wegen dem Filter ausgeblendet.",
|
||||
"Collections": "Sammlung",
|
||||
"MonitorMovies": "Film beobachten",
|
||||
"NoCollections": "Keine Filme gefunden. Zum Starten solltest du einen Film hinzufügen oder vorhandene Importieren.",
|
||||
"RssSyncHelpText": "Intervall in Minuten. Zum deaktivieren auf 0 setzen ( Dies wird das automatische Release erfassen deaktivieren )"
|
||||
}
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
"ForMoreInformationOnTheIndividualDownloadClients": "Για περισσότερες πληροφορίες σχετικά με τους μεμονωμένους πελάτες λήψης, κάντε κλικ στα κουμπιά πληροφοριών.",
|
||||
"GrabReleaseMessageText": "Ο Radarr δεν μπόρεσε να προσδιορίσει ποια ταινία ήταν αυτή η κυκλοφορία. Το Radarr ενδέχεται να μην μπορεί να εισαγάγει αυτόματα αυτήν την κυκλοφορία. Θέλετε να τραβήξετε το \"{0}\";",
|
||||
"HardlinkCopyFiles": "Hardlink / Αντιγραφή αρχείων",
|
||||
"HelpText": "Διάστημα σε λεπτά. Ρυθμίστε στο μηδέν για απενεργοποίηση (αυτό θα σταματήσει όλες τις αυτόματες αρπάξεις απελευθέρωσης)",
|
||||
"ImportRootPath": "Τοποθετήστε το Radarr στο φάκελο που περιέχει όλες τις ταινίες σας και όχι μια συγκεκριμένη ταινία. π.χ. {0} και όχι {1}. Επιπλέον, κάθε ταινία πρέπει να βρίσκεται στον δικό της φάκελο στον φάκελο root / library.",
|
||||
"InCinemasDate": "Στους κινηματογράφους Ημερομηνία",
|
||||
"IncludeRadarrRecommendations": "Συμπεριλάβετε τις προτάσεις Radarr",
|
||||
@@ -416,7 +415,6 @@
|
||||
"MustNotContain": "Δεν πρέπει να περιέχει",
|
||||
"NamingSettings": "Ρυθμίσεις ονομάτων",
|
||||
"NetCore": ".NET Core",
|
||||
"No": "Οχι",
|
||||
"NoBackupsAreAvailable": "Δεν υπάρχουν διαθέσιμα αντίγραφα ασφαλείας",
|
||||
"NoChange": "Καμία αλλαγή",
|
||||
"NoHistory": "Χωρίς ιστορία",
|
||||
@@ -425,7 +423,6 @@
|
||||
"OAuthPopupMessage": "Τα αναδυόμενα παράθυρα αποκλείονται από το πρόγραμμα περιήγησής σας",
|
||||
"Ok": "Εντάξει",
|
||||
"AddListExclusion": "Προσθήκη εξαίρεσης λίστας",
|
||||
"AddMoviesMonitored": "Προσθήκη ταινιών που παρακολουθούνται",
|
||||
"AgeWhenGrabbed": "Ηλικία (όταν αρπαχτεί)",
|
||||
"OrganizeAndRename": "Οργάνωση & Μετονομασία",
|
||||
"AllowHardcodedSubs": "Να επιτρέπονται οι συνδρομητές με κωδικοποίηση",
|
||||
@@ -1016,7 +1013,6 @@
|
||||
"Wiki": "Wiki",
|
||||
"WouldYouLikeToRestoreBackup": "Θέλετε να επαναφέρετε το αντίγραφο ασφαλείας {0};",
|
||||
"Year": "Ετος",
|
||||
"Yes": "Ναί",
|
||||
"YesCancel": "Ναι, Ακύρωση",
|
||||
"YesMoveFiles": "Ναι, Μετακινήστε τα αρχεία",
|
||||
"Yesterday": "Εχθές",
|
||||
@@ -1061,5 +1057,10 @@
|
||||
"SelectLanguages": "Επιλέξτε γλώσσα",
|
||||
"List": "Τόπος αγώνων",
|
||||
"Rating": "Ακροαματικότητα",
|
||||
"Filters": "Φίλτρο"
|
||||
"Filters": "Φίλτρο",
|
||||
"AllCollectionsHiddenDueToFilter": "Όλες οι ταινίες έχουν κρυφτεί λόγω εφαρμογής φίλτρου",
|
||||
"Collections": "Συλλογή",
|
||||
"MonitorMovies": "Παρακολούθηση ταινίας",
|
||||
"NoCollections": "Δεν βρέθηκαν ταινίες, για να ξεκινήσετε θα θέλετε να προσθέσετε μια νέα ταινία ή να εισαγάγετε ορισμένες υπάρχουσες.",
|
||||
"RssSyncHelpText": "Διάστημα σε λεπτά. Ρυθμίστε στο μηδέν για απενεργοποίηση (αυτό θα σταματήσει όλες τις αυτόματες αρπάξεις απελευθέρωσης)"
|
||||
}
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
"AddingTag": "Adding tag",
|
||||
"AddList": "Add List",
|
||||
"AddListExclusion": "Add List Exclusion",
|
||||
"AddMissingMovies": "Add Missing Movies",
|
||||
"AddMovie": "Add Movie",
|
||||
"AddMovies": "Add Movies",
|
||||
"AddMoviesMonitored": "Add Movies Monitored",
|
||||
"AddNew": "Add New",
|
||||
"AddNewMessage": "It's easy to add a new movie, just start typing the name of the movie you want to add",
|
||||
"AddNewMovie": "Add New Movie",
|
||||
@@ -125,6 +123,7 @@
|
||||
"ChmodGroupHelpText": "Group name or gid. Use gid for remote file systems.",
|
||||
"ChmodGroupHelpTextWarning": "This only works if the user running Radarr is the owner of the file. It's better to ensure the download client uses the same group as Radarr.",
|
||||
"ChooseAnotherFolder": "Choose Another Folder",
|
||||
"ChooseImportMode": "Choose Import Mode",
|
||||
"CleanLibraryLevel": "Clean Library Level",
|
||||
"Clear": "Clear",
|
||||
"ClickToChangeLanguage": "Click to change language",
|
||||
@@ -139,6 +138,11 @@
|
||||
"Close": "Close",
|
||||
"CloseCurrentModal": "Close Current Modal",
|
||||
"Collection": "Collection",
|
||||
"CollectionOptions": "Collection Options",
|
||||
"Collections": "Collections",
|
||||
"CollectionShowDetailsHelpText": "Show collection status and properties",
|
||||
"CollectionShowOverviewsHelpText": "Show collection overviews",
|
||||
"CollectionShowPostersHelpText": "Show Collection item posters",
|
||||
"CollectionsSelectedInterp": "{0} Collections(s) Selected",
|
||||
"ColonReplacement": "Colon Replacement",
|
||||
"ColonReplacementFormatHelpText": "Change how Radarr handles colon replacement",
|
||||
@@ -269,6 +273,7 @@
|
||||
"DownloadWarningCheckDownloadClientForMoreDetails": "Download warning: check download client for more details",
|
||||
"Duration": "Duration",
|
||||
"Edit": "Edit",
|
||||
"EditCollection": "Edit Collection",
|
||||
"EditCustomFormat": "Edit Custom Format",
|
||||
"EditDelayProfile": "Edit Delay Profile",
|
||||
"EditGroups": "Edit Groups",
|
||||
@@ -367,7 +372,6 @@
|
||||
"HaveNotAddedMovies": "You haven't added any movies yet, do you want to import some or all of your movies first?",
|
||||
"Health": "Health",
|
||||
"HealthNoIssues": "No issues with your configuration",
|
||||
"HelpText": "Interval in minutes. Set to zero to disable (this will stop all automatic release grabbing)",
|
||||
"HiddenClickToShow": "Hidden, click to show",
|
||||
"HideAdvanced": "Hide Advanced",
|
||||
"History": "History",
|
||||
@@ -445,6 +449,8 @@
|
||||
"IndexerTagHelpText": "Only use this indexer for movies with at least one matching tag. Leave blank to use with all movies.",
|
||||
"Info": "Info",
|
||||
"InstallLatest": "Install Latest",
|
||||
"InstanceName": "Instance Name",
|
||||
"InstanceNameHelpText": "Instance name in tab and for Syslog app name",
|
||||
"InteractiveImport": "Interactive Import",
|
||||
"InteractiveImportErrLanguage": "Language must be chosen for each selected file",
|
||||
"InteractiveImportErrMovie": "Movie must be chosen for each selected file",
|
||||
@@ -604,7 +610,6 @@
|
||||
"Never": "Never",
|
||||
"New": "New",
|
||||
"NextExecution": "Next Execution",
|
||||
"No": "No",
|
||||
"NoAltTitle": "No alternative titles.",
|
||||
"NoBackupsAreAvailable": "No backups are available",
|
||||
"NoChange": "No Change",
|
||||
@@ -643,6 +648,8 @@
|
||||
"OnLatestVersion": "The latest version of Radarr is already installed",
|
||||
"OnlyTorrent": "Only Torrent",
|
||||
"OnlyUsenet": "Only Usenet",
|
||||
"OnMovieAdded": "On Movie Added",
|
||||
"OnMovieAddedHelpText": "On Movie Added",
|
||||
"OnMovieDelete": "On Movie Delete",
|
||||
"OnMovieDeleteHelpText": "On Movie Delete",
|
||||
"OnMovieFileDelete": "On Movie File Delete",
|
||||
@@ -762,6 +769,7 @@
|
||||
"RefreshCollections": "Refresh Collections",
|
||||
"RefreshInformationAndScanDisk": "Refresh information and scan disk",
|
||||
"RefreshLists": "Refresh Lists",
|
||||
"RefreshMonitoredIntervalHelpText": "How often to refresh monitored downloads from download clients, minimum 1 minute",
|
||||
"RefreshMovie": "Refresh movie",
|
||||
"RegularExpressionsCanBeTested": "Regular expressions can be tested ",
|
||||
"RejectionCount": "Rejection Count",
|
||||
@@ -854,6 +862,7 @@
|
||||
"RSS": "RSS",
|
||||
"RSSIsNotSupportedWithThisIndexer": "RSS is not supported with this indexer",
|
||||
"RSSSync": "RSS Sync",
|
||||
"RssSyncHelpText": "Interval in minutes. Set to zero to disable (this will stop all automatic release grabbing)",
|
||||
"RSSSyncInterval": "RSS Sync Interval",
|
||||
"RSSSyncIntervalHelpTextWarning": "This will apply to all indexers, please follow the rules set forth by them",
|
||||
"Runtime": "Runtime",
|
||||
@@ -864,6 +873,7 @@
|
||||
"Score": "Score",
|
||||
"Script": "Script",
|
||||
"ScriptPath": "Script Path",
|
||||
"ScrollMovies": "Scroll Movies",
|
||||
"Search": "Search",
|
||||
"SearchAll": "Search All",
|
||||
"SearchCutoffUnmet": "Search Cutoff Unmet",
|
||||
@@ -928,6 +938,7 @@
|
||||
"ShownClickToHide": "Shown, click to hide",
|
||||
"ShowOverview": "Show Overview",
|
||||
"ShowPath": "Show Path",
|
||||
"ShowPosters": "Show Posters",
|
||||
"ShowQualityProfile": "Show Quality Profile",
|
||||
"ShowQualityProfileHelpText": "Show quality profile under poster",
|
||||
"ShowRatings": "Show Ratings",
|
||||
@@ -1127,7 +1138,6 @@
|
||||
"Wiki": "Wiki",
|
||||
"WouldYouLikeToRestoreBackup": "Would you like to restore the backup {0} ?",
|
||||
"Year": "Year",
|
||||
"Yes": "Yes",
|
||||
"YesCancel": "Yes, Cancel",
|
||||
"YesMoveFiles": "Yes, Move the Files",
|
||||
"Yesterday": "Yesterday",
|
||||
|
||||
@@ -396,7 +396,6 @@
|
||||
"AllowHardcodedSubs": "Permitir Hardcoded Subs",
|
||||
"AgeWhenGrabbed": "Edad (cuando capturada)",
|
||||
"AddImportExclusionHelpText": "Prevenir que la película sea añadida a Radarr mediante listas",
|
||||
"AddMoviesMonitored": "Añadir Películas Monitoreadas",
|
||||
"AddListExclusion": "Añadir Exclusión De Lista",
|
||||
"YesCancel": "Si, cancelar",
|
||||
"WhitelistedSubtitleTags": "Etiquetas de Subtítulos Permitidas",
|
||||
@@ -596,7 +595,6 @@
|
||||
"ICalHttpUrlHelpText": "Copia esta URL a tu gestor(es) o haz click en subscribir si tu navegador soporta webcal",
|
||||
"ICalFeed": "iCal Feed",
|
||||
"Hostname": "Nombre del Host",
|
||||
"HelpText": "Intervalo en minutos. Ajustar a cero para inhabilitar (esto dentendrá toda captura de estrenos automática)",
|
||||
"EnableSSL": "Habilitar SSL",
|
||||
"EnableRSS": "Habilitar RSS",
|
||||
"EnableInteractiveSearch": "Habilitar Búsqueda Interactiva",
|
||||
@@ -907,7 +905,6 @@
|
||||
"InCinemasMsg": "La película está en los cines",
|
||||
"ListSyncLevelHelpTextWarning": "Los archivos de películas se eliminarán permanentemente, esto puede resultar en borrar su biblioteca si sus listas están vacías",
|
||||
"RSS": "RSS",
|
||||
"No": "No",
|
||||
"EditDelayProfile": "Editar perfil de retraso",
|
||||
"Connection": "Conexiones",
|
||||
"ConsideredAvailable": "Considerado disponible",
|
||||
@@ -924,7 +921,7 @@
|
||||
"DeleteMovieFolderHelpText": "Eliminar la carpeta de películas y su contenido",
|
||||
"DeleteSelectedMovie": "Eliminar película (s) seleccionada (s)",
|
||||
"DeleteTheMovieFolder": "Se eliminará la carpeta de películas '{0}' y todo su contenido.",
|
||||
"Discord": "Discordia",
|
||||
"Discord": "Discord",
|
||||
"Donations": "Donaciones",
|
||||
"DoneEditingGroups": "Terminado de editar grupos",
|
||||
"DoNotPrefer": "No prefiero",
|
||||
@@ -1026,7 +1023,6 @@
|
||||
"Weeks": "Semanas",
|
||||
"Wiki": "Wiki",
|
||||
"WouldYouLikeToRestoreBackup": "¿Le gustaría restaurar la copia de seguridad {0}?",
|
||||
"Yes": "si",
|
||||
"YesMoveFiles": "Sí, mover los archivos",
|
||||
"Yesterday": "Ayer",
|
||||
"MoveFolders2": "¿Le gustaría mover los archivos de película de '{0}' a '{1}'?",
|
||||
@@ -1114,5 +1110,10 @@
|
||||
"RemoveSelectedItems": "Eliminar los elementos seleccionados",
|
||||
"SelectReleaseGroup": "Seleccionar el grupo de lanzamiento",
|
||||
"SetReleaseGroup": "Configurar el grupo de lanzamiento",
|
||||
"TaskUserAgentTooltip": "User-Agent proporcionado por la aplicación llamó a la API"
|
||||
"TaskUserAgentTooltip": "User-Agent proporcionado por la aplicación llamó a la API",
|
||||
"RssSyncHelpText": "Intervalo en minutos. Ajustar a cero para inhabilitar (esto dentendrá toda captura de estrenos automática)",
|
||||
"AllCollectionsHiddenDueToFilter": "Todas las películas están ocultas debido al filtro aplicado.",
|
||||
"Collections": "Colección",
|
||||
"MonitorMovies": "Monitorear Película",
|
||||
"NoCollections": "No se encontraron películas, para comenzar, querrá agregar una nueva película o importar algunas existentes."
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"LinkHere": "tässä",
|
||||
"ListSyncLevelHelpText": "Kirjaston elokuvat poistetaan tai niiden valvonta lopetetaan, jollei niitä ole tuontilistallasi.",
|
||||
"ManualImportSelectMovie": "Manuaalinen tuonti - Valitse elokuva",
|
||||
"MappedDrivesRunningAsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä, kun niitä käytetään Windows-palveluna. Katso lisätietoja UKK: sta",
|
||||
"MappedDrivesRunningAsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä, kun sovellus suoritetaan Windows-palveluna. Lisätietoja löydät UKK:stä.",
|
||||
"MinimumAgeHelpText": "Vain Usenet: NZB: n vähimmäisikä minuutteina, ennen kuin heidät napataan. Käytä tätä antaaksesi uusille julkaisuille aikaa levittää usenet-palveluntarjoajallesi.",
|
||||
"MinimumFreeSpaceWhenImportingHelpText": "Estä tuonti, jos vapaan levytilan määrä sen jälkeen jää tässä määritetyn arvon alle.",
|
||||
"MonitoredHelpText": "Elokuvaa etsitään ja se ladataan, jos se on saatavilla.",
|
||||
@@ -60,7 +60,7 @@
|
||||
"MultiLanguage": "Monikielinen",
|
||||
"OrganizeModalNamingPattern": "Nimimalli:",
|
||||
"PosterOptions": "Julistevaihtoehdot",
|
||||
"PreviewRenameHelpText": "Vinkki: Jos haluat esikatsella uudelleennimeä ..., valitse Peruuta, napsauta mitä tahansa elokuvan otsikkoa ja käytä",
|
||||
"PreviewRenameHelpText": "Vihje: Esikatsellaksesi uudelleennimeämistä, valitse 'Peruuta' ja paina jonkin elokuvan otsikkoa ja käytä",
|
||||
"ProxyCheckResolveIpMessage": "Määritetyn välityspalvelimen '{0}' IP-osoitteen selvitys epäonnistui.",
|
||||
"ProxyUsernameHelpText": "Käyttäjätunnus ja salasana tulee syöttää vain tarvittaessa. Muussa tapauksessa jätä kentät tyhjiksi.",
|
||||
"QualityOrLangCutoffHasNotBeenMet": "Laadun tai kielen raja-arvoa ei ole saavutettu",
|
||||
@@ -87,12 +87,12 @@
|
||||
"AddNew": "Lisää uusi",
|
||||
"AudioInfo": "Äänitiedot",
|
||||
"BeforeUpdate": "Ennen päivitystä",
|
||||
"DownloadPropersAndRepacksHelpText2": "Käytä 'Älä suosi' -valintaa lajitellaksesi proper- ja repack-julkaisut mukautetun muodon pisteytytyksen perusteella.",
|
||||
"DownloadPropersAndRepacksHelpText2": "Käytä 'Älä suosi' -valintaa suosiaksesi mukautettujen muotojen pisteytystä Proper- ja Repack-merkintöjä enemmän.",
|
||||
"Day": "Päivä",
|
||||
"DBMigration": "Tietokannan siirto",
|
||||
"ApiKey": "API-avain",
|
||||
"AcceptConfirmationModal": "Hyväksy vahvistus",
|
||||
"ApplyTagsHelpTexts1": "Tunnisteisiin kohdistettavat toimenpiteet:",
|
||||
"ApplyTagsHelpTexts1": "Miten tunnisteita sovelletaan valittuihin elokuviin",
|
||||
"ApplyTagsHelpTexts2": "– 'Lisää' syötetyt tunnisteet aiempiin tunnisteisiin",
|
||||
"ApplyTagsHelpTexts3": "– 'Poista' ainoastaan syötetyt tunnisteet",
|
||||
"AvailabilityDelay": "Saatavuusviive",
|
||||
@@ -210,7 +210,7 @@
|
||||
"EnableInteractiveSearchHelpText": "Profiilia käytetään vuorovaikutteisen haun yhteydessä.",
|
||||
"EnableSslHelpText": " Käyttöönotto edellyttää uudelleenkäynnistystä järjestelmänvalvojan oikeuksilla.",
|
||||
"Medium": "Keskitaso",
|
||||
"MinFormatScoreHelpText": "Mukautetun muodon vähimmäispisteet voidaan ladata",
|
||||
"MinFormatScoreHelpText": "Mukautetun muodon vähimmäispisteytys, jonka perusteella ladataan.",
|
||||
"MinimumAge": "Vähimmäisikä",
|
||||
"MinimumFreeSpace": "Vapaan tallennustilan vähimmäismäärä",
|
||||
"MinimumLimits": "Vähimmäismäärät",
|
||||
@@ -226,7 +226,7 @@
|
||||
"NoLinks": "Ei linkkejä",
|
||||
"NoMinimumForAnyRuntime": "Ei toistoajan vähimmäiskestoa",
|
||||
"NoMoveFilesSelf": " Ei, siirrän tiedostot itse",
|
||||
"NoMoviesExist": "Elokuvia ei löytynyt. Aloittaaksesi sinun kannattaa lisätä uusi elokuva tai tuoda joitain olemassa olevia.",
|
||||
"NoMoviesExist": "Elokuvia ei löytynyt. Aloita lisäämällä uusi elokuva tai tuo joitakin olemassa olevia.",
|
||||
"NoResultsFound": "Ei tuloksia",
|
||||
"BranchUpdate": "Sovelluksen versiopäivityksiin käytettävä kehityshaara.",
|
||||
"BranchUpdateMechanism": "Ulkoisen päivitysratkaisun käyttämä kehityshaara.",
|
||||
@@ -269,7 +269,7 @@
|
||||
"Size": "Koko",
|
||||
"SuggestTranslationChange": "Ehdota käännösmuutosta",
|
||||
"Queued": "Jonossa",
|
||||
"TMDb": "TMDb",
|
||||
"TMDb": "TMDB",
|
||||
"UnableToLoadAltTitle": "Vaihtoehtoisten nimikkeiden lataus epäonnistui.",
|
||||
"Released": "Julkaistu",
|
||||
"ReleasedMsg": "Elokuva julkaistaan",
|
||||
@@ -286,7 +286,7 @@
|
||||
"DetailedProgressBarHelpText": "Näytä teksti edistymispalkissa.",
|
||||
"Failed": "Epäonnistui",
|
||||
"InCinemas": "Teatterijulkaisu",
|
||||
"IncludeCustomFormatWhenRenaming": "Uudelleen nimeäminen",
|
||||
"IncludeCustomFormatWhenRenaming": "Sisällytä mukautetut muodot uudelleennimetessä",
|
||||
"IndexerFlags": "Tietolähteen liput",
|
||||
"IndexerLongTermStatusCheckSingleClientMessage": "Tietolähteet eivät ole käytettävissä yli 6 tuntia kestäneiden virheiden vuoksi: {0}",
|
||||
"IndexerStatusCheckAllClientMessage": "Tietolähteet eivät ole käytettävissä virheiden vuoksi",
|
||||
@@ -329,7 +329,6 @@
|
||||
"Updates": "Päivitykset",
|
||||
"AddListExclusion": "Lisää tuontilistojen poikkeussääntö",
|
||||
"AddMovies": "Lisää elokuvia",
|
||||
"AddMoviesMonitored": "Lisää elokuvat valvottuina",
|
||||
"ChangeHasNotBeenSavedYet": "Muutosta ei ole vielä tallennettu",
|
||||
"CreateEmptyMovieFoldersHelpText": "Luo puuttuvat elokuvakansiot levyn tarkistuksen yhteydessä.",
|
||||
"DeleteDownloadClient": "Poista lataustyökalu",
|
||||
@@ -372,7 +371,6 @@
|
||||
"PendingChangesMessage": "On tallentamattomia muutoksia. Haluatko varmasti poistua sivulta?",
|
||||
"PendingChangesStayReview": "Älä poistu ja tarkista muutokset",
|
||||
"NetCore": ".NET",
|
||||
"No": "Ei",
|
||||
"NoBackupsAreAvailable": "Varmuuskopioita ei ole saatavilla",
|
||||
"NoChange": "Ei muutosta",
|
||||
"NoHistory": "Ei historiaa.",
|
||||
@@ -385,7 +383,7 @@
|
||||
"Ok": "Ok",
|
||||
"OrganizeAndRename": "Järjestä ja nimeä uudelleen",
|
||||
"OrganizeModalAllPathsRelative": "Kaikki polut ovat suhteessa:",
|
||||
"OrganizeModalDisabled": "Nimeäminen uudelleen on poistettu käytöstä, mitään ei voi nimetä uudelleen",
|
||||
"OrganizeModalDisabled": "Uudelleennimeäminen on poistettu käytöstä, eikä uudelleennimettävää ole",
|
||||
"Events": "Tapahtumat",
|
||||
"IncludeCustomFormatWhenRenamingHelpText": "Mahdollista tämän muodon käyttö {Custom Formats} -nimeämissäännön kanssa.",
|
||||
"Overview": "Yleiskatsaus",
|
||||
@@ -421,7 +419,7 @@
|
||||
"RecycleBinCleanupDaysHelpTextWarning": "Tässä määritettyä aikaa vanhemmat tiedostot poistetaan roskakorista pysyvästi automaattisesti.",
|
||||
"RecycleBinHelpText": "Pysyvän poiston sijaan elokuvatiedostot siirretään tähän kansioon.",
|
||||
"RefreshAndScan": "Päivitä ja tarkista",
|
||||
"RequiredHelpText": "Tämän {0} ehdon on vastattava muokattua muotoa. Muuten yksi {1} ottelu riittää.",
|
||||
"RequiredHelpText": "Ehdon '{0}' on vastattava mukautettua muotoa sen soveltamiseksi. Muutoin yksi '{1}' vastaavuus on riittävä.",
|
||||
"RequiredRestrictionPlaceHolder": "Lisää rajoitus",
|
||||
"AppDataLocationHealthCheckMessage": "Päivitystä ei sallita, jotta AppData-kansion poisto päivityksen yhteydessä voidaan estää.",
|
||||
"RestartRequiredHelpTextWarning": "Käyttöönotto vaatii uudelleenkäynnistyksen.",
|
||||
@@ -484,7 +482,7 @@
|
||||
"ConsideredAvailable": "Tulkitaan olevan saatavilla",
|
||||
"CopyUsingHardlinksHelpText": "Käytä hardlink-kytköksiä, kun kopioit tiedostoja torrenteista, joita jaetaan vielä.",
|
||||
"Local": "Paikalliset",
|
||||
"CouldNotFindResults": "Haku '{0}' ei tuottanut yhtään tuloksia.",
|
||||
"CouldNotFindResults": "Haku '{0}' ei tuottanut tuloksia.",
|
||||
"CreateEmptyMovieFolders": "Luo tyhjät kansiot",
|
||||
"CreateGroup": "Luo ryhmä",
|
||||
"Crew": "Ryhmä",
|
||||
@@ -495,12 +493,12 @@
|
||||
"CustomFormatHelpText": "Radarr pisteyttää jokaisen julkaisun käyttäen pisteiden summaa täsmääville mukautetuille muodoille. Jos uusi julkaisu parantaisi pisteitä samalla tai paremmalla laadulla, Radarr sieppaa sen.",
|
||||
"CustomFormatJSON": "Mukautettu muoto JSON",
|
||||
"CustomFormats": "Mukautetut muodot",
|
||||
"CustomFormatScore": "Mukautetun muodon pisteet",
|
||||
"CustomFormatScore": "Mukautetun muodon pisteytys",
|
||||
"CustomFormatsSettings": "Mukautettujen muotojen asetukset",
|
||||
"CustomFormatsSettingsSummary": "Mukautetut muodot ja niiden asetukset.",
|
||||
"CustomFormatUnknownConditionOption": "Tuntematon vaihtoehto '{0}' ehdolle '{1}'",
|
||||
"CustomFormatUnknownConditionOption": "Tuntematon valinta '{0}' ehdolle '{1}'",
|
||||
"Cutoff": "Katkaisu",
|
||||
"CutoffFormatScoreHelpText": "Kun tämä mukautetun muodon pisteytys saavutetaan, Radarr ei enää lataa elokuvia.",
|
||||
"CutoffFormatScoreHelpText": "Kun tämä mukautetun muodon pisteytys saavutetaan, ei elokuvia enää ladata.",
|
||||
"CutoffUnmet": "Katkaisutasoa ei saavutettu",
|
||||
"Days": "Päivää",
|
||||
"Debug": "Virheenkorjaus",
|
||||
@@ -562,7 +560,7 @@
|
||||
"Downloading": "Ladataan",
|
||||
"DownloadPropersAndRepacks": "Proper- ja repack-julkaisut",
|
||||
"DownloadPropersAndRepacksHelpText1": "Määrittää päivitetäänkö tiedostot automaattisesti proper- ja repack-julkaisuihin (kunnollinen/uudelleenpaketoitu).",
|
||||
"DownloadPropersAndRepacksHelpTextWarning": "Käytä mukautettuja muotoja automaattisiin päivityksiin potkureille / uudelleenpakkauksille",
|
||||
"DownloadPropersAndRepacksHelpTextWarning": "Käytä mukautettuja muotoja automaattisiin Proper/Repack-päivityksiin",
|
||||
"DownloadWarning": "Latausvaroitus: {0}",
|
||||
"DownloadWarningCheckDownloadClientForMoreDetails": "Latausvaroitus: Katso tarkempia tietoja lataustyökalusta",
|
||||
"Edition": "Painos",
|
||||
@@ -600,7 +598,7 @@
|
||||
"FailedLoadingSearchResults": "Hakutulosten lataus epäonnistui. Yritä uudelleen.",
|
||||
"FailedToLoadMovieFromAPI": "Elokuvan lataus API:n kautta epäonnistui",
|
||||
"FeatureRequests": "Kehitysehdotukset",
|
||||
"FileDateHelpText": "Tiedoston päiväyksen muutos tuonnin ja uudellentarkistuksen yhteydessä.",
|
||||
"FileDateHelpText": "Muuta tiedoston päiväys tuonnin ja uudelleentarkistuksen yhteydessä.",
|
||||
"FileManagement": "Tiedostojen hallinta",
|
||||
"Filename": "Tiedostonimi",
|
||||
"FileNames": "Tiedostonimet",
|
||||
@@ -631,7 +629,6 @@
|
||||
"Group": "Ryhmä",
|
||||
"Health": "Kunto",
|
||||
"HealthNoIssues": "Kokoonpanossasi ei ole ongelmia.",
|
||||
"HelpText": "Aikaväli minuutteina. Poista käytöstä asettamalla arvoksi '0' (tämä lopettaa julkaisujen automaattisen sieppauksen).",
|
||||
"HiddenClickToShow": "Piilotettu, näytä painalla",
|
||||
"History": "Historia",
|
||||
"Host": "Osoite",
|
||||
@@ -786,8 +783,8 @@
|
||||
"RemoveSelected": "Poista valitut",
|
||||
"RemovingTag": "Tunniste poistetaan",
|
||||
"Renamed": "Nimetty uudelleen",
|
||||
"RenameFiles": "Nimeä uudelleen",
|
||||
"RenameMovies": "Nimeä elokuvat uudelleen",
|
||||
"RenameFiles": "Uudelleennimeä tiedostot",
|
||||
"RenameMovies": "Uudelleennimeä elokuvat",
|
||||
"RenameMoviesHelpText": "Jos uudelleennimeäminen ei ole käytössä, käytetään olemassa olevaa tiedostonimeä.",
|
||||
"Reorder": "Järjestä uudelleen",
|
||||
"Replace": "Korvata",
|
||||
@@ -796,8 +793,8 @@
|
||||
"ReplaceWithSpaceDashSpace": "Korvus: välilyönti-väliviiva-välilyönti",
|
||||
"Required": "Vaaditaan",
|
||||
"RequiredRestrictionHelpText": "Julkaisun tulee sisältää ainakin yksi näistä termeistä (kirjainkokoa ei huomioida).",
|
||||
"RescanAfterRefreshHelpText": "Tarkista elokuvakansion sisältö uudelleen elokuvan päivityksen jälkeen.",
|
||||
"RescanAfterRefreshHelpTextWarning": "Radarr ei tunnista tiedostomuutoksia automaattisesti, jollei asetuksena ole 'Aina'.",
|
||||
"RescanAfterRefreshHelpText": "Tutki elokuvakansio uudelleen elokuvan päivityksen jälkeen.",
|
||||
"RescanAfterRefreshHelpTextWarning": "Tiedostomuutoksia ei tunnisteta automaattisesti, jollei asetuksena ole 'Aina'.",
|
||||
"RescanMovieFolderAfterRefresh": "Elokuvakansion uudelleentarkistus",
|
||||
"ResetAPIKey": "Uudista API-avain",
|
||||
"Restart": "Käynnistä uudelleen",
|
||||
@@ -829,7 +826,7 @@
|
||||
"SearchMissing": "Haku puuttuu",
|
||||
"SearchMovie": "Etsi elokuvaa",
|
||||
"SearchOnAdd": "Etsi lisättäessä",
|
||||
"SearchOnAddHelpText": "Elokuvia etsitään tältä tuostilistalta, kun ne lisätään Radarriin.",
|
||||
"SearchOnAddHelpText": "Etsi tuostilistan elokuvia, kun ne lisätään kirjastoon.",
|
||||
"SearchSelected": "Haku valittu",
|
||||
"Seconds": "Sekuntia",
|
||||
"Security": "Suojaus",
|
||||
@@ -856,7 +853,7 @@
|
||||
"SettingsTimeFormat": "Kellonajan esitystapa",
|
||||
"SettingsWeekColumnHeader": "Viikkosarakkeen otsikko",
|
||||
"SettingsWeekColumnHeaderHelpText": "Näkyy jokaisen sarakkeen yläpuolella käytettäessä viikkonäkymää.",
|
||||
"ShouldMonitorHelpText": "Tältä tuontilistalta lisätyt elokuvat lisätään ja niitä valvotaan.",
|
||||
"ShouldMonitorHelpText": "Lisää listan elokuvat valvottuina.",
|
||||
"ShowAdvanced": "Näytä edistyneet",
|
||||
"ShowAsAllDayEvents": "Näytä koko päivän tapahtumina",
|
||||
"ShowCutoffUnmetIconHelpText": "Näytä kuvake elokuville, joiden tiedostot eivät vastaa vielä määritettyä katkaisutasoa.",
|
||||
@@ -881,7 +878,7 @@
|
||||
"Shutdown": "Sammuta",
|
||||
"SizeOnDisk": "Koko levyllä",
|
||||
"SkipFreeSpaceCheck": "Ohita vapaan levytilan tarkistus",
|
||||
"SkipFreeSpaceCheckWhenImportingHelpText": "Käytä, kun vaapaata tilaa ei tunnisteta elokuviesi pääkansiosta",
|
||||
"SkipFreeSpaceCheckWhenImportingHelpText": "Käytä, kun vapaata tallennustilaa ei tunnisteta elokuvien juurikansiosta.",
|
||||
"Small": "Pieni",
|
||||
"Socks4": "Sukat 4",
|
||||
"Socks5": "Sukat5 (tuki TOR)",
|
||||
@@ -948,7 +945,7 @@
|
||||
"UnableToAddANewRemotePathMappingPleaseTryAgain": "Etäsijainnin kartoituksen lisäys epäonnistui. Yritä uudelleen.",
|
||||
"UnableToImportCheckLogs": "Ladattu - Tuonti epäonnistui: tarkasta lokitiedot",
|
||||
"UnableToLoadBackups": "Varmuuskopioiden lataus epäonnistui.",
|
||||
"UnableToLoadCustomFormats": "Muokattujen muotojen lataus epäonnistui.",
|
||||
"UnableToLoadCustomFormats": "Muokattuja muotoja ei voitu ladata.",
|
||||
"UnableToLoadDelayProfiles": "Viiveprofiilien lataus epäonnistui.",
|
||||
"Unlimited": "Rajoittamaton",
|
||||
"UnableToLoadDownloadClientOptions": "Lataustyökalun asetuksien lataus epäonnistui.",
|
||||
@@ -956,7 +953,7 @@
|
||||
"UnableToLoadGeneralSettings": "Yleisten asetusten lataus epäonnistui.",
|
||||
"UnableToLoadHistory": "Historian lataus epäonnistui.",
|
||||
"UnableToLoadIndexerOptions": "Tietolähteiden asetuksien lataus epäonnistui.",
|
||||
"UnableToLoadIndexers": "Tietolähteiden lataus epäonnistui.",
|
||||
"UnableToLoadIndexers": "Tietolähteiden lataus epäonnistui",
|
||||
"UnableToLoadLanguages": "Kielien lataus epäonnistui.",
|
||||
"UnableToLoadListExclusions": "Tuontilistojen poikkeussääntöjen lataus epäonnistui.",
|
||||
"UnableToLoadListOptions": "Tuontilistojen asetuksien lataus epäonnistui.",
|
||||
@@ -989,7 +986,7 @@
|
||||
"UpdateAutomaticallyHelpText": "Lataa ja asenna päivitykset automaattisesti. Voit edelleen asentaa ne myös lähteestä System:Updates.",
|
||||
"UpdateCheckStartupTranslocationMessage": "Päivitystä ei voi asentaa, koska käynnistyskansio '{0}' sijaitsee 'App Translocation' -kansiossa.",
|
||||
"UpdateMechanismHelpText": "Käytä Radarrin sisäänrakennettua päivitystoimintoa tai omaa komentosarjaasi.",
|
||||
"UpdateSelected": "Päivitä valittu",
|
||||
"UpdateSelected": "Päivitä valitut",
|
||||
"UpgradeUntilCustomFormatScore": "Päivitä mukautetun muodon pistetytykseen saakka",
|
||||
"UpgradeUntilQuality": "Päivitä laatuun asti",
|
||||
"UpgradeUntilThisQualityIsMetOrExceeded": "Päivitä, kunnes tämä laatu saavutetaan tai ylitetään",
|
||||
@@ -1016,7 +1013,6 @@
|
||||
"Wiki": "Wiki",
|
||||
"WouldYouLikeToRestoreBackup": "Haluatko palauttaa varmuuskopion {0}?",
|
||||
"Year": "Vuosi",
|
||||
"Yes": "Kyllä",
|
||||
"YesCancel": "Kyllä, peruuta",
|
||||
"YesMoveFiles": "Kyllä, siirrä tiedostot",
|
||||
"Yesterday": "Eilen",
|
||||
@@ -1074,7 +1070,7 @@
|
||||
"RemotePathMappingCheckFileRemoved": "Tiedosto '{0}' poistettiin kesken käsittelyn.",
|
||||
"RemotePathMappingCheckFilesLocalWrongOSPath": "Paikallinen lataustyökalu '{0}' ilmoitti tiedostosijainniksi '{1}', mutta se ei ole kelvollinen '{2}' -sijainti. Tarkista lataustyökalusi asetukset.",
|
||||
"RemotePathMappingCheckFolderPermissions": "Radarr näkee, muttei voi käyttää latauskansiota '{0}'. Todennäköinen syy on sijainnin käyttöoikeusvirhe.",
|
||||
"RemotePathMappingCheckGenericPermissions": "Lataustyökalu '{0}' sijoittaa lataukset kansioon '{1}', mutta Radarr ei näe sitä. Saata joutua muokkaamaan kansion käyttöoikeuksia.",
|
||||
"RemotePathMappingCheckGenericPermissions": "Lataustyökalu '{0}' sijoittaa lataukset kansioon '{1}', mutta Radarr ei näe sitä. Saatat joutua muokkaamaan kansion käyttöoikeuksia.",
|
||||
"RemotePathMappingCheckDockerFolderMissing": "Käytät Dockeria ja lataustyökalu '{0}' sijoittaa lataukset kohteeseen '{1}', mutta kansiota ei näytä olevan olemassa containerissa. Tarkista etäsijaintiesi kartoitukset ja containerin tallennusmedia-asetukset.",
|
||||
"RemotePathMappingCheckFilesBadDockerPath": "Käytät Dockeria ja lataustyökalu '{0}' ilmoitti latauskohteeksi '{1}', mutta se ei ole kelvollinen '{2}' -sijainti. Tarkista etäsijaintiesi kartoitukset ja lataustyökalun asetukset.",
|
||||
"RemotePathMappingCheckRemoteDownloadClient": "Etälataustyökalu '{0}' ilmoitti tiedostosijainniksi '{1}', mutta kansiota ei näytä olevan olemassa. Todennäköinen syy on puuttuva tai virheellinen etäsijainnin kartoitus.",
|
||||
@@ -1115,5 +1111,28 @@
|
||||
"Waiting": "Odottaa",
|
||||
"OriginalTitle": "Alkuperäinen nimi",
|
||||
"OriginalLanguage": "Alkuperäinen kieli",
|
||||
"Database": "Tietokanta"
|
||||
"Database": "Tietokanta",
|
||||
"RefreshMonitoredIntervalHelpText": "Miten usein valvottujen latausten tiedot päivitetään lataustyökaluilta (vähimmäisaika on 1 minuutti).",
|
||||
"RssSyncHelpText": "Aikaväli minuutteina. Arvo nolla kytkee toiminnon pois käytöstä ja lopettaen samalla automaattisen julkaisujen kaappauksen täysin.",
|
||||
"InstanceName": "Instanssin nimi",
|
||||
"InstanceNameHelpText": "Instanssin nimi välilehdellä ja sovelluksen Syslog-nimeksi",
|
||||
"AllCollectionsHiddenDueToFilter": "Käytössä oleva suodatin on piilottanut kaikki kokoelmat.",
|
||||
"Collections": "Kokoelmat",
|
||||
"MonitorMovies": "Valvo elokuvia",
|
||||
"NoCollections": "Kokoelmia ei löytynyt. Aloita lisäämällä uusi elokuva tai tuo joitakin olemassa olevia.",
|
||||
"EditCollection": "Muokkaa kokoelmaa",
|
||||
"SearchOnAddCollectionHelpText": "Etsi kokoelman elokuvia, kun ne lisätään kirjastoon.",
|
||||
"ChooseImportMode": "Valitse tuontitila",
|
||||
"CollectionsSelectedInterp": "{0} kokoelmaa valittu",
|
||||
"MonitorCollection": "Valvo kokoelmaa",
|
||||
"MonitoredCollectionHelpText": "Valvonta lisää kokoelman elokuvat automaattisesti kirjastoon.",
|
||||
"MovieAndCollection": "Elokuva ja kokoelma",
|
||||
"MovieCollectionMissingRoot": "Elokuvakokoelman juurikansio puuttuu: {0}",
|
||||
"MovieCollectionMultipleMissingRoots": "Useita elokuvakokoelmien juurikansioita puuttuu: {0}",
|
||||
"MovieOnly": "Vain elokuva",
|
||||
"RefreshCollections": "Päivitä kokoelmat",
|
||||
"ScrollMovies": "Vieritä elokuvia",
|
||||
"ShowCollectionDetails": "Näytä kokoelman tila",
|
||||
"ShowOverview": "Näytä yleiskatsaus",
|
||||
"UnableToLoadCollections": "Kokoelmia ei voitu ladata"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"IndexerStatusCheckAllClientMessage": "Tous les indexeurs sont indisponibles en raison d'échecs",
|
||||
"IndexerSearchCheckNoInteractiveMessage": "Aucun indexeur disponible avec la recherche interactive activée, Radarr ne fournira aucun résultat de recherche interactif",
|
||||
"IndexerSearchCheckNoInteractiveMessage": "Aucun indexeur disponible avec la recherche interactive activée, Radarr ne fournira aucun résultat de recherche interactive",
|
||||
"IndexerSearchCheckNoAvailableIndexersMessage": "Tous les indexeurs compatibles avec la recherche sont temporairement indisponibles en raison d'erreurs d'indexation récentes",
|
||||
"IndexerSearchCheckNoAutomaticMessage": "Aucun indexeur disponible avec la recherche automatique activée, Radarr ne fournira aucun résultat de recherche automatique",
|
||||
"Indexers": "Indexeurs",
|
||||
@@ -26,7 +26,7 @@
|
||||
"Edit": "Éditer",
|
||||
"Downloaded": "Téléchargé",
|
||||
"DownloadClientStatusCheckAllClientMessage": "Aucun client de téléchargement n'est disponible en raison d'échecs",
|
||||
"DownloadClients": "Clients Télécharg.",
|
||||
"DownloadClients": "Clients de téléchargement",
|
||||
"DownloadClientCheckNoneAvailableMessage": "Aucun client de téléchargement n'est disponible",
|
||||
"Dates": "Dates",
|
||||
"Date": "Date",
|
||||
@@ -36,7 +36,7 @@
|
||||
"Delete": "Supprimer",
|
||||
"DelayProfiles": "Profils de retard",
|
||||
"Day": "Jour",
|
||||
"CustomFormats": "Formats Persos",
|
||||
"CustomFormats": "Formats personnalisés",
|
||||
"CustomFilters": "Filtres personnalisés",
|
||||
"Crew": "Équipe",
|
||||
"Connections": "Connexions",
|
||||
@@ -48,7 +48,7 @@
|
||||
"Calendar": "Calendrier",
|
||||
"BackupNow": "Sauvegarder maintenant",
|
||||
"Backup": "Sauvegarde",
|
||||
"AppDataLocationHealthCheckMessage": "Mettre à jour ne sera pas possible pour éviter la suppression AppData lors de la mise à jour",
|
||||
"AppDataLocationHealthCheckMessage": "Mettre à jour ne sera pas possible afin d'éviter de supprimer le dossier AppData lors de la mise à jour",
|
||||
"Analytics": "Analytique",
|
||||
"All": "Tout",
|
||||
"AddNewTmdbIdMessage": "Vous pouvez également effectuer une recherche à l'aide de l'identifiant TMDb d'un film. exemple. tmdb:71663",
|
||||
@@ -59,7 +59,7 @@
|
||||
"Activity": "Activité",
|
||||
"About": "À propos",
|
||||
"CustomFormatsSettingsSummary": "Paramètres et Formats personnalisés",
|
||||
"IndexerStatusCheckSingleClientMessage": "Indexeurs indisponibles en raison d'échecs: {0}",
|
||||
"IndexerStatusCheckSingleClientMessage": "Indexeurs indisponibles en raison d'échecs : {0}",
|
||||
"DownloadClientStatusCheckSingleClientMessage": "Clients de Téléchargement indisponibles en raison d'échecs : {0}",
|
||||
"SetTags": "Définir Tags",
|
||||
"ReleaseTitle": "Titre de la version",
|
||||
@@ -292,7 +292,7 @@
|
||||
"RecentFolders": "Dossiers récents",
|
||||
"QuickImport": "Déplacer automatiquement",
|
||||
"PosterSize": "Taille des posters",
|
||||
"Posters": "Posters",
|
||||
"Posters": "Affiches",
|
||||
"PosterOptions": "Options des posters",
|
||||
"PendingChangesStayReview": "Rester et vérifier les changements",
|
||||
"PendingChangesMessage": "Vous avez effectué des changements non sauvegardés, souhaitez vous quitter cette page ?",
|
||||
@@ -322,7 +322,7 @@
|
||||
"CertificateValidation": "Validation du certificat",
|
||||
"BypassProxyForLocalAddresses": "Contourner le proxy pour les adresses locales",
|
||||
"Branch": "Branche",
|
||||
"BindAddressHelpText": "Adresse IP4 valide ou '*' pour toutes les interfaces",
|
||||
"BindAddressHelpText": "Adresse IPv4 valide ou '*' pour toutes les interfaces",
|
||||
"BindAddress": "Adresse d'attache",
|
||||
"Backups": "Sauvegardes",
|
||||
"BackupRetentionHelpText": "Les sauvegardes automatiques plus anciennes que la période de conservation seront automatiquement effacées",
|
||||
@@ -347,7 +347,6 @@
|
||||
"AllowHardcodedSubsHelpText": "Les sous-titres incrustés détectés seront automatiquement téléchargés",
|
||||
"AllowHardcodedSubs": "Autoriser les sous-titres incrustés",
|
||||
"AgeWhenGrabbed": "Age (au moment du téléchargement)",
|
||||
"AddMoviesMonitored": "Ajouter des films en mode surveillé",
|
||||
"AddListExclusion": "Ajouter une exclusion de liste",
|
||||
"IgnoreDeletedMovies": "Annuler la surveillance des films supprimés",
|
||||
"IgnoredAddresses": "Adresses ignorées",
|
||||
@@ -355,7 +354,6 @@
|
||||
"ICalHttpUrlHelpText": "Copiez cette URL dans votre client ou cliquez pour souscrire si votre navigateur est compatible avec webcal",
|
||||
"ICalFeed": "Flux iCal",
|
||||
"Hostname": "Nom d'hôte",
|
||||
"HelpText": "Intervalle en minutes. Mettre à zéro pour désactiver (cela arrêtera tous les téléchargements automatiques)",
|
||||
"Group": "Groupe",
|
||||
"GrabRelease": "Télécharger la version",
|
||||
"GrabID": "ID du grab",
|
||||
@@ -385,7 +383,7 @@
|
||||
"Enable": "Activer",
|
||||
"EditPerson": "Éditer la personne",
|
||||
"EditMovie": "Éditer le film",
|
||||
"Edition": "Edition",
|
||||
"Edition": "Édition",
|
||||
"DownloadWarningCheckDownloadClientForMoreDetails": "Avertissement téléchargement : voir le client de téléchargement pour plus de détails",
|
||||
"DownloadFailedCheckDownloadClientForMoreDetails": "Téléchargement échoué : voir le client de téléchargement pour plus de détails",
|
||||
"DownloadClientSettings": "Réglages Clients de téléchargement",
|
||||
@@ -455,7 +453,7 @@
|
||||
"CopyToClipboard": "Copier dans le presse-papier",
|
||||
"GoToInterp": "Aller à {0}",
|
||||
"ForMoreInformationOnTheIndividualImportListsClinkOnTheInfoButtons": "Pour plus d'informations sur les listes d'importation individuelles, cliquez sur les boutons d'information.",
|
||||
"ForMoreInformationOnTheIndividualDownloadClients": "Pour plus d'informations sur les clients de téléchargement individuels, cliquez sur les boutons d'information.",
|
||||
"ForMoreInformationOnTheIndividualDownloadClients": "Pour plus d'informations sur chaque client de téléchargement, cliquez sur les boutons plus d'information.",
|
||||
"FilterPlaceHolder": "Chercher les films",
|
||||
"FailedLoadingSearchResults": "Échec du chargement des résultats de la recherche, veuillez réessayer.",
|
||||
"Excluded": "Exclu",
|
||||
@@ -573,7 +571,7 @@
|
||||
"ProxyBypassFilterHelpText": "Utiliser ',' comme séparateur et '*.' comme caractère générique pour les sous-domaines",
|
||||
"OnGrabHelpText": "À la Récupération",
|
||||
"NegateHelpText": "Si coché, le format personnalisé ne s'appliquera pas si cette condition {0} correspond.",
|
||||
"LastDuration": "dernière Durée",
|
||||
"LastDuration": "Dernière durée",
|
||||
"IncludeCustomFormatWhenRenamingHelpText": "Inclus dans {Custom Formats} renommer le format",
|
||||
"GrabReleaseMessageText": "Radarr n'a pas été en mesure de déterminer à quel film cette version était destinée. Radarr peut être incapable d'importer automatiquement cette version. Voulez-vous récupérer '{0}' ?",
|
||||
"ExtraFileExtensionsHelpTexts1": "Liste séparée par des virgules des fichiers supplémentaires à importer (.nfo sera importé en tant que .nfo-orig)",
|
||||
@@ -586,7 +584,7 @@
|
||||
"UpgradeUntilThisQualityIsMetOrExceeded": "Mettre à niveau jusqu'à ce que cette qualité soit atteinte ou dépassée",
|
||||
"UpgradeAllowedHelpText": "Ne sera pas mis à jour si la qualité est désactivée",
|
||||
"UpdateScriptPathHelpText": "Chemin vers un script personnalisé qui prend un package de mise à jour extraite et gère le reste du processus de mise à jour",
|
||||
"UpdateMechanismHelpText": "Utiliser le programme de mise à jour intégré dans Radarr ou un script",
|
||||
"UpdateMechanismHelpText": "Utiliser le programme de mise à jour intégré de Radarr ou un script",
|
||||
"UpdateAutomaticallyHelpText": "Télécharger et installer automatiquement les mises à jour. Vous pourrez toujours installer à partir de System : Updates",
|
||||
"Unreleased": "Indisponible",
|
||||
"UnmonitoredHelpText": "Inclure les films non surveillés dans le flux iCal",
|
||||
@@ -828,7 +826,7 @@
|
||||
"EditQualityProfile": "Modifier les profils",
|
||||
"ErrorRestoringBackup": "Erreur lors de la restauration de la sauvegarde",
|
||||
"ExternalUpdater": "Radarr est configuré pour utiliser un système de mise à jour ad-hoc",
|
||||
"FileWasDeletedByViaUI": "Le fichier à été supprimé via l'interface",
|
||||
"FileWasDeletedByViaUI": "Le fichier a été supprimé via l'interface",
|
||||
"Announced": "Annoncé",
|
||||
"ChmodFolder": "chmod Dossier",
|
||||
"ChmodFolderHelpText": "Nombre, appliqué durant l'import/renommage vers les dossiers et fichiers multimédias (sans exécuter les bits)",
|
||||
@@ -848,7 +846,7 @@
|
||||
"AllResultsHiddenFilter": "Tous les résultats ont été dissimulés par le filtre actuellement appliqué",
|
||||
"Always": "Toujours",
|
||||
"AptUpdater": "Utiliser apt pour installer la mise à jour",
|
||||
"AreYouSureYouWantToRemoveSelectedItemsFromQueue": "Êtes-vous sûr de vouloir désinstaller {0} objet{1} de la file d'attente ?",
|
||||
"AreYouSureYouWantToRemoveSelectedItemsFromQueue": "Êtes-vous sûr de vouloir supprimer {0} objet(s) de la file d'attente ?",
|
||||
"AuthBasic": "Authentification de base (popup)",
|
||||
"AuthForm": "Authentification par formulaire (page de connexion)",
|
||||
"AreYouSureYouWantToDeleteFormat": "Êtes-vous sûr de vouloir supprimer le tag {0} ?",
|
||||
@@ -894,7 +892,7 @@
|
||||
"HomePage": "Page d'accueil",
|
||||
"HttpHttps": "HTTP(S)",
|
||||
"ImportLibrary": "Import bibliothèque",
|
||||
"MissingFromDisk": "Radarr n'a pas pu trouver le fichier sur le disque, il a donc été supprimé",
|
||||
"MissingFromDisk": "Radarr n'a pas pu trouver le fichier sur le disque, il a donc été supprimé dans la base de donnée",
|
||||
"MovieIsRecommend": "Le film est recommandé en fonction de l'ajout récent",
|
||||
"NoAltTitle": "Pas de titres alternatifs.",
|
||||
"NoLinks": "Aucun liens",
|
||||
@@ -912,7 +910,7 @@
|
||||
"InteractiveImportErrQuality": "La qualité doit être choisie pour chaque fichier sélectionné",
|
||||
"LowerCase": "Minuscules",
|
||||
"ManualImportSelectMovie": "Importation manuelle - Sélectionnez un film",
|
||||
"MappedDrivesRunningAsService": "Les lecteurs réseau mappés ne sont pas disponibles lorsqu'ils sont exécutés en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations",
|
||||
"MappedDrivesRunningAsService": "Les lecteurs réseau mappés ne sont pas disponibles en fonctionnement en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations",
|
||||
"RequiredRestrictionHelpText": "La version doit contenir au moins un de ces termes (insensible à la casse)",
|
||||
"InvalidFormat": "Format invalide",
|
||||
"LastExecution": "Dernière exécution",
|
||||
@@ -944,7 +942,6 @@
|
||||
"ImportNotForDownloads": "Ne pas utiliser pour importer des téléchargements à partir de votre client de téléchargement, cela concerne uniquement les bibliothèques organisées existantes, pas les fichiers non triés.",
|
||||
"PreferUsenet": "Préférez Usenet",
|
||||
"ReplaceWithDash": "Remplacer par Dash",
|
||||
"No": "Non",
|
||||
"InCinemasDate": "Dans les cinémas Date",
|
||||
"InstallLatest": "Installer le dernier",
|
||||
"KeepAndUnmonitorMovie": "Conserver et annuler la surveillance du film",
|
||||
@@ -994,7 +991,7 @@
|
||||
"SearchCutoffUnmet": "Limite de recherche non satisfaite",
|
||||
"SearchMissing": "Recherche manquante",
|
||||
"Seconds": "Secondes",
|
||||
"SelectDotDot": "'Sélectionner...",
|
||||
"SelectDotDot": "Sélectionner...",
|
||||
"SelectLanguage": "Choisir la langue",
|
||||
"SelectMovie": "Sélectionnez un film",
|
||||
"SelectQuality": "Sélectionnez la qualité",
|
||||
@@ -1005,7 +1002,7 @@
|
||||
"Sunday": "dimanche",
|
||||
"TagDetails": "Détails du tag - {0}",
|
||||
"TheLogLevelDefault": "Le niveau de journalisation est par défaut «Info» et peut être modifié dans",
|
||||
"ThisCannotBeCancelled": "Cela ne peut pas être annulé une fois démarré sans redémarrer Radarr.",
|
||||
"ThisCannotBeCancelled": "Cela ne peut pas être annulé une fois démarré sans désactiver tous vos indexeurs.",
|
||||
"TorrentDelayTime": "Retard du torrent : {0}",
|
||||
"TorrentsDisabled": "Torrents désactivés",
|
||||
"Trace": "Trace",
|
||||
@@ -1027,7 +1024,6 @@
|
||||
"Weeks": "Semaines",
|
||||
"Wiki": "Wiki",
|
||||
"WouldYouLikeToRestoreBackup": "Souhaitez-vous restaurer la sauvegarde {0} ?",
|
||||
"Yes": "Oui",
|
||||
"YesMoveFiles": "Oui, déplacez les fichiers",
|
||||
"MoveFolders2": "Souhaitez-vous déplacer les fichiers vidéo de «{0}» vers «{1}» ?",
|
||||
"SqliteVersionCheckUpgradeRequiredMessage": "La version {0} de SQLite actuellement installée n'est plus prise en charge. Veuillez mettre à niveau SQLite vers au moins la version {1}.",
|
||||
@@ -1048,7 +1044,7 @@
|
||||
"DownloadClientCheckDownloadingToRoot": "Le client de téléchargement {0} place les téléchargements dans le dossier racine {1}. Vous ne devez pas télécharger dans un dossier racine.",
|
||||
"DeleteFileLabel": "Supprimer {0} fichiers",
|
||||
"NotificationTriggersHelpText": "Sélectionnez les événements qui doivent déclencher cette notification",
|
||||
"From": "De",
|
||||
"From": "de",
|
||||
"UpdateAvailable": "Une nouvelle mise à jour est disponible",
|
||||
"RemotePathMappingCheckImportFailed": "Radarr a échoué en important un Film. Vérifier vos logs pour plus de détails.",
|
||||
"RemotePathMappingCheckDownloadPermissions": "Radarr peut voir mais ne peut accéder au film téléchargé {0}. Il s'agit probablement d'une erreur de permissions.",
|
||||
@@ -1074,22 +1070,22 @@
|
||||
"RemotePathMappingCheckFilesGenericPermissions": "Le client de téléchargement {0} met les téléchargements dans {1} mais Radarr ne peut voir ce répertoire. Il est possible que vous ayez besoin d'ajuster les permissions de ce dossier.",
|
||||
"RemotePathMappingCheckFilesLocalWrongOSPath": "Le client de téléchargement {0} met les téléchargements dans {1} mais il ne s'agit pas d'un chemin {2} valide. Vérifiez les paramètres de votre client de téléchargement.",
|
||||
"BypassDelayIfHighestQualityHelpText": "Outrepasser le délai quand la version a la plus haute qualité activée dans le profil de qualité avec le protocole préféré",
|
||||
"ClickToChangeReleaseGroup": "Cliquez pour changer de release group",
|
||||
"ClickToChangeReleaseGroup": "Cliquer pour changer le groupe de publication",
|
||||
"AnnouncedMsg": "Le film est annoncé",
|
||||
"Filters": "Filtres",
|
||||
"IndexerDownloadClientHelpText": "Précisez quel client de téléchargement est utilisé pour cet indexer",
|
||||
"IndexerDownloadClientHelpText": "Spécifiez quel client de téléchargement est utilisé pour cet indexeur",
|
||||
"TmdbRating": "Note TMDb",
|
||||
"IndexerTagHelpText": "Utiliser seulement cet indexeur pour les films avec au moins un tag correspondant. Laissez vide pour l'utiliser avec tous les films.",
|
||||
"IndexerJackettAll": "Les indexeurs utilisant le endpoint 'all' de Jackett: {0}",
|
||||
"IndexerJackettAll": "Indexeurs utilisant le endpoint non supporté 'all' de Jackett : {0}",
|
||||
"ManualImportSetReleaseGroup": "Import manuel - Spécifier le groupe de Release",
|
||||
"TmdbVotes": "Votes TMDb",
|
||||
"ImdbRating": "Note IMDb",
|
||||
"ImdbVotes": "Votes IMDb",
|
||||
"LocalPath": "Chemin local",
|
||||
"DiscordUrlInSlackNotification": "Vous avez une configuration de notification Discord en tant que notification Slack. Configurez cela comme une notification Discord pour une meilleure fonctionnalité. Les notifications affectées sont: {0}",
|
||||
"RemotePathMappingCheckDockerFolderMissing": "Vous utilisez docker; {0} enregistre les téléchargements dans {1} mais ce dossier n'est pas présent dans ce conteneur. Vérifiez vos paramètres de dossier distant et les paramètres de votre conteneur docker.",
|
||||
"DiscordUrlInSlackNotification": "Vous avez une configuration de notification Discord en tant que notification Slack. Configurez cela comme une notification Discord pour un meilleur fonctionnement. Les notifications affectées sont : {0}",
|
||||
"RemotePathMappingCheckDockerFolderMissing": "Vous utilisez docker ; {0} enregistre les téléchargements dans {1} mais ce dossier n'est pas présent dans ce conteneur. Vérifiez vos paramètres de dossier distant et les paramètres de votre conteneur docker.",
|
||||
"RemotePathMappingCheckRemoteDownloadClient": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
|
||||
"RemotePathMappingCheckBadDockerPath": "Vous utilisez docker; {0} enregistre les téléchargements dans {1} mais ce n'est pas un dossier valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
|
||||
"RemotePathMappingCheckBadDockerPath": "Vous utilisez docker ; le client de téléchargement {0} enregistre les téléchargements dans {1} mais ce n'est pas un chemin valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
|
||||
"RemotePathMappingCheckFilesWrongOSPath": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais il ne s'agit pas d'un chemin {2} valide. Vérifiez les paramètres de votre client de téléchargement.",
|
||||
"RemotePathMappingCheckLocalFolderMissing": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
|
||||
"OnApplicationUpdate": "Lors de la mise à jour de l'app",
|
||||
@@ -1102,9 +1098,26 @@
|
||||
"OriginalLanguage": "Langue d'origine",
|
||||
"Rating": "Note",
|
||||
"RemotePath": "Dossier distant",
|
||||
"RemotePathMappingCheckFilesBadDockerPath": "Vous utilisez docker; {0} signifie les téléchargement dans {1} mais ce n'est pas un dossier valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
|
||||
"RemotePathMappingCheckFilesBadDockerPath": "Vous utilisez docker ; {0} signifie les téléchargement dans {1} mais ce n'est pas un dossier valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
|
||||
"RemotePathMappingCheckWrongOSPath": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin {2} est invalide. Vérifiez vos paramètres de chemins distants et les paramètres de votre client de téléchargement.",
|
||||
"RemoveCompleted": "Supprimer les complétés",
|
||||
"Database": "Base de données",
|
||||
"SelectLanguages": "Choisir la langue"
|
||||
"SelectLanguages": "Choisir la/les langue(s)",
|
||||
"RemoveDownloadsAlert": "Les paramètres de suppression ont été déplacés dans les réglages de chaque client de téléchargement dans le tableau ci-dessus.",
|
||||
"SizeLimit": "Limite de taille",
|
||||
"Started": "Démarré",
|
||||
"Waiting": "En attente",
|
||||
"RemoveFailed": "Echec de la suppression",
|
||||
"RemoveSelectedItem": "Supprimer l'élément sélectionné",
|
||||
"RemoveSelectedItems": "Supprimer les éléments sélectionnés",
|
||||
"SelectReleaseGroup": "Sélectionner le groupe de publication",
|
||||
"SetReleaseGroup": "Régler le groupe de publication",
|
||||
"RefreshMonitoredIntervalHelpText": "Intervalle en minutes entre chaque vérification des téléchargements, minimum 1 minute",
|
||||
"AllCollectionsHiddenDueToFilter": "Tous les films sont masqués en raison du filtre appliqué.",
|
||||
"Collections": "Collection",
|
||||
"MonitorMovies": "Surveiller le film",
|
||||
"NoCollections": "Aucun film trouvé, pour commencer, vous voudrez ajouter un nouveau film ou importer des films existants.",
|
||||
"RssSyncHelpText": "Intervalle en minutes. Mettre à zéro pour désactiver (cela arrêtera tous les téléchargements automatiques)",
|
||||
"CollectionsSelectedInterp": "{0} Collections(s) Sélectionnée(s)",
|
||||
"ChooseImportMode": "Mode d'importation"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user