mirror of
https://github.com/Radarr/Radarr.git
synced 2026-03-05 13:21:25 -05:00
Compare commits
26 Commits
v4.7.4.775
...
v4.7.5.780
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8e54fdf99 | ||
|
|
c3b856401e | ||
|
|
25f6f3ec6d | ||
|
|
d28eb47a1a | ||
|
|
431bc14e76 | ||
|
|
efe5c3beb7 | ||
|
|
d61ce6112b | ||
|
|
531e948687 | ||
|
|
7ad4411e4d | ||
|
|
e8e23e41dc | ||
|
|
0c1fc49d69 | ||
|
|
83632f91e6 | ||
|
|
1bbd08a5a0 | ||
|
|
298077940e | ||
|
|
4fb632e4fc | ||
|
|
7bcb492572 | ||
|
|
a673535417 | ||
|
|
e0d70dc341 | ||
|
|
aa98b2bac9 | ||
|
|
145f67d14b | ||
|
|
caea810908 | ||
|
|
9a567b93d0 | ||
|
|
6ecd41bc5a | ||
|
|
d5b4f0efa9 | ||
|
|
b337f62a34 | ||
|
|
c42fc6094d |
@@ -9,7 +9,7 @@ variables:
|
||||
testsFolder: './_tests'
|
||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
||||
majorVersion: '4.7.4'
|
||||
majorVersion: '4.7.5'
|
||||
minorVersion: $[counter('minorVersion', 2000)]
|
||||
radarrVersion: '$(majorVersion).$(minorVersion)'
|
||||
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
|
||||
@@ -536,8 +536,8 @@ stages:
|
||||
testRunTitle: '$(testName) Unit Tests'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- job: Unit_LinuxCore_Postgres
|
||||
displayName: Unit Native LinuxCore with Postgres Database
|
||||
- job: Unit_LinuxCore_Postgres14
|
||||
displayName: Unit Native LinuxCore with Postgres14 Database
|
||||
dependsOn: Prepare
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
variables:
|
||||
@@ -589,7 +589,63 @@ stages:
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResult.xml'
|
||||
testRunTitle: 'LinuxCore Postgres Unit Tests'
|
||||
testRunTitle: 'LinuxCore Postgres14 Unit Tests'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- job: Unit_LinuxCore_Postgres15
|
||||
displayName: Unit Native LinuxCore with Postgres15 Database
|
||||
dependsOn: Prepare
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
variables:
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
artifactName: linux-x64-tests
|
||||
Radarr__Postgres__Host: 'localhost'
|
||||
Radarr__Postgres__Port: '5432'
|
||||
Radarr__Postgres__User: 'radarr'
|
||||
Radarr__Postgres__Password: 'radarr'
|
||||
|
||||
pool:
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
|
||||
timeoutInMinutes: 10
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
inputs:
|
||||
version: $(dotnetVersion)
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: $(artifactName)
|
||||
targetPath: $(testsFolder)
|
||||
- bash: |
|
||||
chmod a+x _tests/ffprobe
|
||||
displayName: Make ffprobe Executable
|
||||
- bash: find ${TESTSFOLDER} -name "Radarr.Test.Dummy" -exec chmod a+x {} \;
|
||||
displayName: Make Test Dummy Executable
|
||||
condition: and(succeeded(), ne(variables['osName'], 'Windows'))
|
||||
- bash: |
|
||||
docker run -d --name=postgres15 \
|
||||
-e POSTGRES_PASSWORD=radarr \
|
||||
-e POSTGRES_USER=radarr \
|
||||
-p 5432:5432/tcp \
|
||||
-v /usr/share/zoneinfo/America/Chicago:/etc/localtime:ro \
|
||||
postgres:15
|
||||
displayName: Start postgres
|
||||
- bash: |
|
||||
chmod a+x ${TESTSFOLDER}/test.sh
|
||||
ls -lR ${TESTSFOLDER}
|
||||
${TESTSFOLDER}/test.sh Linux Unit Test
|
||||
displayName: Run Tests
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Test Results
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResult.xml'
|
||||
testRunTitle: 'LinuxCore Postgres15 Unit Tests'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- stage: Integration
|
||||
@@ -675,8 +731,8 @@ stages:
|
||||
failTaskOnFailedTests: true
|
||||
displayName: Publish Test Results
|
||||
|
||||
- job: Integration_LinuxCore_Postgres
|
||||
displayName: Integration Native LinuxCore with Postgres Database
|
||||
- job: Integration_LinuxCore_Postgres14
|
||||
displayName: Integration Native LinuxCore with Postgres14 Database
|
||||
dependsOn: Prepare
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
variables:
|
||||
@@ -733,7 +789,70 @@ stages:
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResult.xml'
|
||||
testRunTitle: 'Integration LinuxCore Postgres Database Integration Tests'
|
||||
testRunTitle: 'Integration LinuxCore Postgres14 Database Integration Tests'
|
||||
failTaskOnFailedTests: true
|
||||
displayName: Publish Test Results
|
||||
|
||||
|
||||
- job: Integration_LinuxCore_Postgres15
|
||||
displayName: Integration Native LinuxCore with Postgres Database
|
||||
dependsOn: Prepare
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
variables:
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
Radarr__Postgres__Host: 'localhost'
|
||||
Radarr__Postgres__Port: '5432'
|
||||
Radarr__Postgres__User: 'radarr'
|
||||
Radarr__Postgres__Password: 'radarr'
|
||||
|
||||
pool:
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
inputs:
|
||||
version: $(dotnetVersion)
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: 'linux-x64-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: Packages
|
||||
itemPattern: '**/$(pattern)'
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
- task: ExtractFiles@1
|
||||
inputs:
|
||||
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
|
||||
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
|
||||
displayName: Extract Package
|
||||
- bash: |
|
||||
mkdir -p ./bin/
|
||||
cp -r -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin/Radarr/. ./bin/
|
||||
displayName: Move Package Contents
|
||||
- bash: |
|
||||
docker run -d --name=postgres15 \
|
||||
-e POSTGRES_PASSWORD=radarr \
|
||||
-e POSTGRES_USER=radarr \
|
||||
-p 5432:5432/tcp \
|
||||
-v /usr/share/zoneinfo/America/Chicago:/etc/localtime:ro \
|
||||
postgres:15
|
||||
displayName: Start postgres
|
||||
- bash: |
|
||||
chmod a+x ${TESTSFOLDER}/test.sh
|
||||
${TESTSFOLDER}/test.sh Linux Integration Test
|
||||
displayName: Run Integration Tests
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResult.xml'
|
||||
testRunTitle: 'Integration LinuxCore Postgres15 Database Integration Tests'
|
||||
failTaskOnFailedTests: true
|
||||
displayName: Publish Test Results
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ export interface MovieIndexAppState {
|
||||
showQualityProfile: boolean;
|
||||
showReleaseDate: boolean;
|
||||
showCinemaRelease: boolean;
|
||||
showTmdbRating: boolean;
|
||||
showImdbRating: boolean;
|
||||
showRottenTomatoesRating: boolean;
|
||||
showSearchAction: boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +31,18 @@ function getDownloadIcon(isGrabbing, isGrabbed, grabError) {
|
||||
return icons.DOWNLOAD;
|
||||
}
|
||||
|
||||
function getDownloadKind(isGrabbed, grabError) {
|
||||
if (isGrabbed) {
|
||||
return kinds.SUCCESS;
|
||||
}
|
||||
|
||||
if (grabError) {
|
||||
return kinds.DANGER;
|
||||
}
|
||||
|
||||
return kinds.DEFAULT;
|
||||
}
|
||||
|
||||
function getDownloadTooltip(isGrabbing, isGrabbed, grabError) {
|
||||
if (isGrabbing) {
|
||||
return '';
|
||||
@@ -148,7 +160,7 @@ class InteractiveSearchRow extends Component {
|
||||
<TableRowCell className={styles.download}>
|
||||
<SpinnerIconButton
|
||||
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
|
||||
kind={grabError ? kinds.DANGER : kinds.DEFAULT}
|
||||
kind={getDownloadKind(isGrabbed, grabError)}
|
||||
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
|
||||
isDisabled={isGrabbed}
|
||||
isSpinning={isGrabbing}
|
||||
|
||||
@@ -9,3 +9,9 @@
|
||||
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.customFormatScore {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Please do not change this file!
|
||||
interface CssExports {
|
||||
'actions': string;
|
||||
'customFormatScore': string;
|
||||
'sourceTitle': string;
|
||||
}
|
||||
export const cssExports: CssExports;
|
||||
|
||||
@@ -7,7 +7,8 @@ import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import MovieFormats from 'Movie/MovieFormats';
|
||||
import MovieLanguage from 'Movie/MovieLanguage';
|
||||
import MovieQuality from 'Movie/MovieQuality';
|
||||
@@ -106,8 +107,15 @@ class MovieHistoryRow extends Component {
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
{formatCustomFormatScore(customFormatScore)}
|
||||
<TableRowCell className={styles.customFormatScore}>
|
||||
<Tooltip
|
||||
anchor={formatCustomFormatScore(
|
||||
customFormatScore,
|
||||
customFormats.length
|
||||
)}
|
||||
tooltip={<MovieFormats formats={customFormats} />}
|
||||
position={tooltipPositions.TOP}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<RelativeDateCellConnector
|
||||
|
||||
@@ -100,6 +100,15 @@ function MovieIndexSortMenu(props: MovieIndexSortMenuProps) {
|
||||
{translate('DigitalRelease')}
|
||||
</SortMenuItem>
|
||||
|
||||
<SortMenuItem
|
||||
name="tmdbRating"
|
||||
sortKey={sortKey}
|
||||
sortDirection={sortDirection}
|
||||
onPress={onSortSelect}
|
||||
>
|
||||
{translate('TmdbRating')}
|
||||
</SortMenuItem>
|
||||
|
||||
<SortMenuItem
|
||||
name="imdbRating"
|
||||
sortKey={sortKey}
|
||||
@@ -110,12 +119,12 @@ function MovieIndexSortMenu(props: MovieIndexSortMenuProps) {
|
||||
</SortMenuItem>
|
||||
|
||||
<SortMenuItem
|
||||
name="tmdbRating"
|
||||
name="rottenTomatoesRating"
|
||||
sortKey={sortKey}
|
||||
sortDirection={sortDirection}
|
||||
onPress={onSortSelect}
|
||||
>
|
||||
{translate('TmdbRating')}
|
||||
{translate('RottenTomatoesRating')}
|
||||
</SortMenuItem>
|
||||
|
||||
<SortMenuItem
|
||||
|
||||
@@ -2,10 +2,13 @@ import React, { useCallback, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { MOVIE_SEARCH, REFRESH_MOVIE } from 'Commands/commandNames';
|
||||
import Icon from 'Components/Icon';
|
||||
import ImdbRating from 'Components/ImdbRating';
|
||||
import Label from 'Components/Label';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import Link from 'Components/Link/Link';
|
||||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
import RottenTomatoRating from 'Components/RottenTomatoRating';
|
||||
import TmdbRating from 'Components/TmdbRating';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal';
|
||||
@@ -44,6 +47,9 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
|
||||
showQualityProfile,
|
||||
showCinemaRelease,
|
||||
showReleaseDate,
|
||||
showTmdbRating,
|
||||
showImdbRating,
|
||||
showRottenTomatoesRating,
|
||||
showSearchAction,
|
||||
} = useSelector(selectPosterOptions);
|
||||
|
||||
@@ -257,6 +263,24 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{showTmdbRating && !!ratings.tmdb ? (
|
||||
<div className={styles.title}>
|
||||
<TmdbRating ratings={ratings} iconSize={12} />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{showImdbRating && !!ratings.imdb ? (
|
||||
<div className={styles.title}>
|
||||
<ImdbRating ratings={ratings} iconSize={12} />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{showRottenTomatoesRating && !!ratings.rottenTomatoes ? (
|
||||
<div className={styles.title}>
|
||||
<RottenTomatoRating ratings={ratings} iconSize={12} />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<MovieIndexPosterInfo
|
||||
studio={studio}
|
||||
qualityProfile={qualityProfile}
|
||||
@@ -279,6 +303,9 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
|
||||
certification={certification}
|
||||
originalTitle={originalTitle}
|
||||
originalLanguage={originalLanguage}
|
||||
showTmdbRating={showTmdbRating}
|
||||
showImdbRating={showImdbRating}
|
||||
showRottenTomatoesRating={showRottenTomatoesRating}
|
||||
/>
|
||||
|
||||
<EditMovieModalConnector
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import Icon from 'Components/Icon';
|
||||
import ImdbRating from 'Components/ImdbRating';
|
||||
import RottenTomatoRating from 'Components/RottenTomatoRating';
|
||||
import TmdbRating from 'Components/TmdbRating';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import { Language, Ratings } from 'Movie/Movie';
|
||||
@@ -33,6 +34,9 @@ interface MovieIndexPosterInfoProps {
|
||||
shortDateFormat: string;
|
||||
longDateFormat: string;
|
||||
timeFormat: string;
|
||||
showTmdbRating: boolean;
|
||||
showImdbRating: boolean;
|
||||
showRottenTomatoesRating: boolean;
|
||||
}
|
||||
|
||||
function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) {
|
||||
@@ -58,6 +62,9 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) {
|
||||
shortDateFormat,
|
||||
longDateFormat,
|
||||
timeFormat,
|
||||
showTmdbRating,
|
||||
showImdbRating,
|
||||
showRottenTomatoesRating,
|
||||
} = props;
|
||||
|
||||
if (sortKey === 'studio' && studio) {
|
||||
@@ -163,7 +170,15 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) {
|
||||
);
|
||||
}
|
||||
|
||||
if (sortKey === 'imdbRating' && !!ratings.imdb) {
|
||||
if (!showTmdbRating && sortKey === 'tmdbRating' && !!ratings.tmdb) {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<TmdbRating ratings={ratings} iconSize={12} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!showImdbRating && sortKey === 'imdbRating' && !!ratings.imdb) {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<ImdbRating ratings={ratings} iconSize={12} />
|
||||
@@ -171,10 +186,14 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) {
|
||||
);
|
||||
}
|
||||
|
||||
if (sortKey === 'tmdbRating' && !!ratings.tmdb) {
|
||||
if (
|
||||
!showRottenTomatoesRating &&
|
||||
sortKey === 'rottenTomatoesRating' &&
|
||||
!!ratings.rottenTomatoes
|
||||
) {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<TmdbRating ratings={ratings} iconSize={12} />
|
||||
<RottenTomatoRating ratings={ratings} iconSize={12} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -145,6 +145,9 @@ export default function MovieIndexPosters(props: MovieIndexPostersProps) {
|
||||
showQualityProfile,
|
||||
showCinemaRelease,
|
||||
showReleaseDate,
|
||||
showTmdbRating,
|
||||
showImdbRating,
|
||||
showRottenTomatoesRating,
|
||||
} = posterOptions;
|
||||
|
||||
const nextAiringHeight = 19;
|
||||
@@ -176,12 +179,22 @@ export default function MovieIndexPosters(props: MovieIndexPostersProps) {
|
||||
heights.push(19);
|
||||
}
|
||||
|
||||
if (showTmdbRating) {
|
||||
heights.push(19);
|
||||
}
|
||||
|
||||
if (showImdbRating) {
|
||||
heights.push(19);
|
||||
}
|
||||
|
||||
if (showRottenTomatoesRating) {
|
||||
heights.push(19);
|
||||
}
|
||||
|
||||
switch (sortKey) {
|
||||
case 'studio':
|
||||
case 'added':
|
||||
case 'year':
|
||||
case 'imdbRating':
|
||||
case 'tmdbRating':
|
||||
case 'path':
|
||||
case 'sizeOnDisk':
|
||||
case 'originalTitle':
|
||||
@@ -204,6 +217,21 @@ export default function MovieIndexPosters(props: MovieIndexPostersProps) {
|
||||
heights.push(19);
|
||||
}
|
||||
break;
|
||||
case 'imdbRating':
|
||||
if (!showImdbRating) {
|
||||
heights.push(19);
|
||||
}
|
||||
break;
|
||||
case 'tmdbRating':
|
||||
if (!showTmdbRating) {
|
||||
heights.push(19);
|
||||
}
|
||||
break;
|
||||
case 'rottenTomatoesRating':
|
||||
if (!showRottenTomatoesRating) {
|
||||
heights.push(19);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// No need to add a height of 0
|
||||
}
|
||||
|
||||
@@ -54,6 +54,9 @@ function MovieIndexPosterOptionsModalContent(
|
||||
showQualityProfile,
|
||||
showCinemaRelease,
|
||||
showReleaseDate,
|
||||
showTmdbRating,
|
||||
showImdbRating,
|
||||
showRottenTomatoesRating,
|
||||
showSearchAction,
|
||||
} = posterOptions;
|
||||
|
||||
@@ -156,6 +159,42 @@ function MovieIndexPosterOptionsModalContent(
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('ShowTmdbRating')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showTmdbRating"
|
||||
value={showTmdbRating}
|
||||
helpText={translate('ShowTmdbRatingHelpText')}
|
||||
onChange={onPosterOptionChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('ShowImdbRating')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showImdbRating"
|
||||
value={showImdbRating}
|
||||
helpText={translate('ShowImdbRatingHelpText')}
|
||||
onChange={onPosterOptionChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('ShowRottenTomatoesRating')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showRottenTomatoesRating"
|
||||
value={showRottenTomatoesRating}
|
||||
helpText={translate('ShowRottenTomatoesRatingHelpText')}
|
||||
onChange={onPosterOptionChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('ShowSearch')}</FormLabel>
|
||||
|
||||
|
||||
@@ -39,3 +39,9 @@
|
||||
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.customFormatScore {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
interface CssExports {
|
||||
'actions': string;
|
||||
'age': string;
|
||||
'customFormatScore': string;
|
||||
'download': string;
|
||||
'formats': string;
|
||||
'language': string;
|
||||
|
||||
@@ -4,7 +4,8 @@ import IconButton from 'Components/Link/IconButton';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import MovieFormats from 'Movie/MovieFormats';
|
||||
import MovieLanguage from 'Movie/MovieLanguage';
|
||||
import MovieQuality from 'Movie/MovieQuality';
|
||||
@@ -12,6 +13,7 @@ import FileEditModal from 'MovieFile/Edit/FileEditModal';
|
||||
import MediaInfoConnector from 'MovieFile/MediaInfoConnector';
|
||||
import * as mediaInfoTypes from 'MovieFile/mediaInfoTypes';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import FileDetailsModal from '../FileDetailsModal';
|
||||
import MovieFileRowCellPlaceholder from './MovieFileRowCellPlaceholder';
|
||||
@@ -78,6 +80,7 @@ class MovieFileEditorRow extends Component {
|
||||
quality,
|
||||
qualityCutoffNotMet,
|
||||
customFormats,
|
||||
customFormatScore,
|
||||
languages
|
||||
} = this.props;
|
||||
|
||||
@@ -170,6 +173,19 @@ class MovieFileEditorRow extends Component {
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell
|
||||
className={styles.customFormatScore}
|
||||
>
|
||||
<Tooltip
|
||||
anchor={formatCustomFormatScore(
|
||||
customFormatScore,
|
||||
customFormats.length
|
||||
)}
|
||||
tooltip={<MovieFormats formats={customFormats} />}
|
||||
position={tooltipPositions.TOP}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.actions}>
|
||||
<IconButton
|
||||
title={translate('EditMovieFile')}
|
||||
@@ -225,6 +241,7 @@ MovieFileEditorRow.propTypes = {
|
||||
quality: PropTypes.object.isRequired,
|
||||
releaseGroup: PropTypes.string,
|
||||
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
customFormatScore: PropTypes.number.isRequired,
|
||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
mediaInfo: PropTypes.object,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Icon from 'Components/Icon';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
@@ -45,10 +46,18 @@ const columns = [
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'quality.customFormats',
|
||||
name: 'customFormats',
|
||||
label: () => translate('Formats'),
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'customFormatScore',
|
||||
label: React.createElement(Icon, {
|
||||
name: icons.SCORE,
|
||||
title: () => translate('CustomFormatScore')
|
||||
}),
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'action',
|
||||
label: React.createElement(IconButton, { name: icons.ADVANCED_SETTINGS }),
|
||||
|
||||
@@ -35,6 +35,9 @@ export const defaultState = {
|
||||
showQualityProfile: true,
|
||||
showCinemaRelease: false,
|
||||
showReleaseDate: false,
|
||||
showTmdbRating: false,
|
||||
showImdbRating: false,
|
||||
showRottenTomatoesRating: false,
|
||||
showSearchAction: false
|
||||
},
|
||||
|
||||
@@ -253,7 +256,7 @@ export const defaultState = {
|
||||
rottenTomatoesRating: function(item) {
|
||||
const { ratings = {} } = item;
|
||||
|
||||
return ratings.rottenTomatoes ? ratings.rottenTomatoes.value : 0;
|
||||
return ratings.rottenTomatoes ? ratings.rottenTomatoes.value : -1;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -20,5 +20,7 @@
|
||||
}
|
||||
|
||||
.actions {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
min-width: 90px;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
|
||||
.Returns(_folders);
|
||||
|
||||
Subject.LookupContents(root, false, false).Directories.Should().NotContain(Path.Combine(root, RECYCLING_BIN));
|
||||
Subject.LookupContents(root, false, false).Directories.Should().NotContain(dir => dir.Path == Path.Combine(root, RECYCLING_BIN));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -62,7 +62,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
|
||||
.Returns(_folders);
|
||||
|
||||
Subject.LookupContents(root, false, false).Directories.Should().NotContain(Path.Combine(root, SYSTEM_VOLUME_INFORMATION));
|
||||
Subject.LookupContents(root, false, false).Directories.Should().NotContain(dir => dir.Path == Path.Combine(root, SYSTEM_VOLUME_INFORMATION));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -564,7 +564,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
|
||||
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||
|
||||
count.Should().Equals(0);
|
||||
count.Should().Be(0);
|
||||
destination.GetFileSystemInfos().Should().BeEmpty();
|
||||
}
|
||||
|
||||
@@ -584,7 +584,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
|
||||
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||
|
||||
count.Should().Equals(0);
|
||||
count.Should().Be(0);
|
||||
destination.GetFileSystemInfos().Should().HaveCount(1);
|
||||
}
|
||||
|
||||
@@ -601,7 +601,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
|
||||
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||
|
||||
count.Should().Equals(3);
|
||||
count.Should().Be(3);
|
||||
VerifyCopyFolder(original.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
@@ -618,7 +618,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
|
||||
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||
|
||||
count.Should().Equals(3);
|
||||
count.Should().Be(3);
|
||||
|
||||
File.Exists(Path.Combine(destination.FullName, _nfsFile)).Should().BeFalse();
|
||||
}
|
||||
@@ -638,7 +638,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
|
||||
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||
|
||||
count.Should().Equals(0);
|
||||
count.Should().Be(0);
|
||||
VerifyCopyFolder(original.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
@@ -655,7 +655,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
|
||||
var count = Subject.MirrorFolder(source.FullName + Path.DirectorySeparatorChar, destination.FullName);
|
||||
|
||||
count.Should().Equals(3);
|
||||
count.Should().Be(3);
|
||||
VerifyCopyFolder(original.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NLog;
|
||||
@@ -119,21 +120,21 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_execute_simple_get()
|
||||
public async Task should_execute_simple_get()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Execute(request);
|
||||
var response = await Subject.ExecuteAsync(request);
|
||||
|
||||
response.Content.Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_execute_https_get()
|
||||
public async Task should_execute_https_get()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Execute(request);
|
||||
var response = await Subject.ExecuteAsync(request);
|
||||
|
||||
response.Content.Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
@@ -145,47 +146,47 @@ namespace NzbDrone.Common.Test.Http
|
||||
Mocker.GetMock<IConfigService>().SetupGet(x => x.CertificateValidation).Returns(validationType);
|
||||
var request = new HttpRequest($"https://expired.badssl.com");
|
||||
|
||||
Assert.Throws<HttpRequestException>(() => Subject.Execute(request));
|
||||
Assert.ThrowsAsync<HttpRequestException>(async () => await Subject.ExecuteAsync(request));
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void bad_ssl_should_pass_if_remote_validation_disabled()
|
||||
public async Task bad_ssl_should_pass_if_remote_validation_disabled()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().SetupGet(x => x.CertificateValidation).Returns(CertificateValidationType.Disabled);
|
||||
|
||||
var request = new HttpRequest($"https://expired.badssl.com");
|
||||
|
||||
Subject.Execute(request);
|
||||
await Subject.ExecuteAsync(request);
|
||||
ExceptionVerification.ExpectedErrors(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_execute_typed_get()
|
||||
public async Task should_execute_typed_get()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get?test=1");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Url.EndsWith("/get?test=1");
|
||||
response.Resource.Args.Should().Contain("test", "1");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_execute_simple_post()
|
||||
public async Task should_execute_simple_post()
|
||||
{
|
||||
var message = "{ my: 1 }";
|
||||
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/post");
|
||||
request.SetContent(message);
|
||||
|
||||
var response = Subject.Post<HttpBinResource>(request);
|
||||
var response = await Subject.PostAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Data.Should().Be(message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_execute_post_with_content_type()
|
||||
public async Task should_execute_post_with_content_type()
|
||||
{
|
||||
var message = "{ my: 1 }";
|
||||
|
||||
@@ -193,17 +194,17 @@ namespace NzbDrone.Common.Test.Http
|
||||
request.SetContent(message);
|
||||
request.Headers.ContentType = "application/json";
|
||||
|
||||
var response = Subject.Post<HttpBinResource>(request);
|
||||
var response = await Subject.PostAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Data.Should().Be(message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_execute_get_using_gzip()
|
||||
public async Task should_execute_get_using_gzip()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/gzip");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers["Accept-Encoding"].ToString().Should().Contain("gzip");
|
||||
|
||||
@@ -213,11 +214,11 @@ namespace NzbDrone.Common.Test.Http
|
||||
|
||||
[Test]
|
||||
[Platform(Exclude = "MacOsX", Reason = "Azure agent update prevents brotli on OSX")]
|
||||
public void should_execute_get_using_brotli()
|
||||
public async Task should_execute_get_using_brotli()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/brotli");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers["Accept-Encoding"].ToString().Should().Contain("br");
|
||||
|
||||
@@ -235,7 +236,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/status/{statusCode}");
|
||||
|
||||
var exception = Assert.Throws<HttpException>(() => Subject.Get<HttpBinResource>(request));
|
||||
var exception = Assert.ThrowsAsync<HttpException>(async () => await Subject.GetAsync<HttpBinResource>(request));
|
||||
|
||||
((int)exception.Response.StatusCode).Should().Be(statusCode);
|
||||
|
||||
@@ -248,7 +249,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}");
|
||||
request.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.NotFound };
|
||||
|
||||
Assert.Throws<HttpException>(() => Subject.Get<HttpBinResource>(request));
|
||||
Assert.ThrowsAsync<HttpException>(async () => await Subject.GetAsync<HttpBinResource>(request));
|
||||
|
||||
ExceptionVerification.IgnoreWarns();
|
||||
}
|
||||
@@ -259,28 +260,28 @@ namespace NzbDrone.Common.Test.Http
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}");
|
||||
request.LogHttpError = false;
|
||||
|
||||
Assert.Throws<HttpException>(() => Subject.Get<HttpBinResource>(request));
|
||||
Assert.ThrowsAsync<HttpException>(async () => await Subject.GetAsync<HttpBinResource>(request));
|
||||
|
||||
ExceptionVerification.ExpectedWarns(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_follow_redirects_when_not_in_production()
|
||||
public async Task should_not_follow_redirects_when_not_in_production()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/redirect/1");
|
||||
|
||||
Subject.Get(request);
|
||||
await Subject.GetAsync(request);
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_follow_redirects()
|
||||
public async Task should_follow_redirects()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/redirect/1");
|
||||
request.AllowAutoRedirect = true;
|
||||
|
||||
var response = Subject.Get(request);
|
||||
var response = await Subject.GetAsync(request);
|
||||
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
@@ -288,12 +289,12 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_follow_redirects()
|
||||
public async Task should_not_follow_redirects()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/redirect/1");
|
||||
request.AllowAutoRedirect = false;
|
||||
|
||||
var response = Subject.Get(request);
|
||||
var response = await Subject.GetAsync(request);
|
||||
|
||||
response.StatusCode.Should().Be(HttpStatusCode.Found);
|
||||
|
||||
@@ -301,14 +302,14 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_follow_redirects_to_https()
|
||||
public async Task should_follow_redirects_to_https()
|
||||
{
|
||||
var request = new HttpRequestBuilder($"https://{_httpBinHost}/redirect-to")
|
||||
.AddQueryParam("url", $"https://radarr.video/")
|
||||
.Build();
|
||||
request.AllowAutoRedirect = true;
|
||||
|
||||
var response = Subject.Get(request);
|
||||
var response = await Subject.GetAsync(request);
|
||||
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
response.Content.Should().Contain("Radarr");
|
||||
@@ -322,17 +323,17 @@ namespace NzbDrone.Common.Test.Http
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/redirect/6");
|
||||
request.AllowAutoRedirect = true;
|
||||
|
||||
Assert.Throws<WebException>(() => Subject.Get(request));
|
||||
Assert.ThrowsAsync<WebException>(async () => await Subject.GetAsync(request));
|
||||
|
||||
ExceptionVerification.ExpectedErrors(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_send_user_agent()
|
||||
public async Task should_send_user_agent()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers.Should().ContainKey("User-Agent");
|
||||
|
||||
@@ -342,24 +343,24 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[TestCase("Accept", "text/xml, text/rss+xml, application/rss+xml")]
|
||||
public void should_send_headers(string header, string value)
|
||||
public async Task should_send_headers(string header, string value)
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
request.Headers.Add(header, value);
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers[header].ToString().Should().Be(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_download_file()
|
||||
public async Task should_download_file()
|
||||
{
|
||||
var file = GetTempFilePath();
|
||||
|
||||
var url = "https://radarr.video/img/slider/moviedetails.png";
|
||||
|
||||
Subject.DownloadFile(url, file);
|
||||
await Subject.DownloadFileAsync(url, file);
|
||||
|
||||
var fileInfo = new FileInfo(file);
|
||||
fileInfo.Exists.Should().BeTrue();
|
||||
@@ -367,7 +368,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_download_file_with_redirect()
|
||||
public async Task should_download_file_with_redirect()
|
||||
{
|
||||
var file = GetTempFilePath();
|
||||
|
||||
@@ -375,7 +376,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
.AddQueryParam("url", $"https://radarr.video/img/slider/moviedetails.png")
|
||||
.Build();
|
||||
|
||||
Subject.DownloadFile(request.Url.FullUri, file);
|
||||
await Subject.DownloadFileAsync(request.Url.FullUri, file);
|
||||
|
||||
ExceptionVerification.ExpectedErrors(0);
|
||||
|
||||
@@ -389,7 +390,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
var file = GetTempFilePath();
|
||||
|
||||
Assert.Throws<HttpException>(() => Subject.DownloadFile("https://download.sonarr.tv/wrongpath", file));
|
||||
Assert.ThrowsAsync<HttpException>(async () => await Subject.DownloadFileAsync("https://download.sonarr.tv/wrongpath", file));
|
||||
|
||||
File.Exists(file).Should().BeFalse();
|
||||
|
||||
@@ -397,7 +398,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_write_redirect_content_to_stream()
|
||||
public async Task should_not_write_redirect_content_to_stream()
|
||||
{
|
||||
var file = GetTempFilePath();
|
||||
|
||||
@@ -407,7 +408,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
request.AllowAutoRedirect = false;
|
||||
request.ResponseStream = fileStream;
|
||||
|
||||
var response = Subject.Get(request);
|
||||
var response = await Subject.GetAsync(request);
|
||||
|
||||
response.StatusCode.Should().Be(HttpStatusCode.Moved);
|
||||
}
|
||||
@@ -422,12 +423,12 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_send_cookie()
|
||||
public async Task should_send_cookie()
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
request.Cookies["my"] = "cookie";
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers.Should().ContainKey("Cookie");
|
||||
|
||||
@@ -436,7 +437,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
cookie.Should().Contain("my=cookie");
|
||||
}
|
||||
|
||||
public void GivenOldCookie()
|
||||
public async Task GivenOldCookie()
|
||||
{
|
||||
if (_httpBinHost == _httpBinHost2)
|
||||
{
|
||||
@@ -450,19 +451,19 @@ namespace NzbDrone.Common.Test.Http
|
||||
|
||||
oldClient.Should().NotBeSameAs(Subject);
|
||||
|
||||
var oldResponse = oldClient.Get<HttpBinResource>(oldRequest);
|
||||
var oldResponse = await oldClient.GetAsync<HttpBinResource>(oldRequest);
|
||||
|
||||
oldResponse.Resource.Headers.Should().ContainKey("Cookie");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_preserve_cookie_during_session()
|
||||
public async Task should_preserve_cookie_during_session()
|
||||
{
|
||||
GivenOldCookie();
|
||||
await GivenOldCookie();
|
||||
|
||||
var request = new HttpRequest($"https://{_httpBinHost2}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers.Should().ContainKey("Cookie");
|
||||
|
||||
@@ -472,30 +473,30 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_send_cookie_to_other_host()
|
||||
public async Task should_not_send_cookie_to_other_host()
|
||||
{
|
||||
GivenOldCookie();
|
||||
await GivenOldCookie();
|
||||
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers.Should().NotContainKey("Cookie");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_store_request_cookie()
|
||||
public async Task should_not_store_request_cookie()
|
||||
{
|
||||
var requestGet = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
requestGet.Cookies.Add("my", "cookie");
|
||||
requestGet.AllowAutoRedirect = false;
|
||||
requestGet.StoreRequestCookie = false;
|
||||
requestGet.StoreResponseCookie = false;
|
||||
var responseGet = Subject.Get<HttpBinResource>(requestGet);
|
||||
var responseGet = await Subject.GetAsync<HttpBinResource>(requestGet);
|
||||
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestCookies.AllowAutoRedirect = false;
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().BeEmpty();
|
||||
|
||||
@@ -503,18 +504,18 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_store_request_cookie()
|
||||
public async Task should_store_request_cookie()
|
||||
{
|
||||
var requestGet = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
requestGet.Cookies.Add("my", "cookie");
|
||||
requestGet.AllowAutoRedirect = false;
|
||||
requestGet.StoreRequestCookie.Should().BeTrue();
|
||||
requestGet.StoreResponseCookie = false;
|
||||
var responseGet = Subject.Get<HttpBinResource>(requestGet);
|
||||
var responseGet = await Subject.GetAsync<HttpBinResource>(requestGet);
|
||||
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestCookies.AllowAutoRedirect = false;
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
|
||||
@@ -522,7 +523,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_request_cookie()
|
||||
public async Task should_delete_request_cookie()
|
||||
{
|
||||
var requestDelete = new HttpRequest($"https://{_httpBinHost}/cookies/delete?my");
|
||||
requestDelete.Cookies.Add("my", "cookie");
|
||||
@@ -531,13 +532,13 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestDelete.StoreResponseCookie = false;
|
||||
|
||||
// Delete and redirect since that's the only way to check the internal temporary cookie container
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestDelete);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestDelete);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_clear_request_cookie()
|
||||
public async Task should_clear_request_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestSet.Cookies.Add("my", "cookie");
|
||||
@@ -545,7 +546,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestSet.StoreRequestCookie = true;
|
||||
requestSet.StoreResponseCookie = false;
|
||||
|
||||
var responseSet = Subject.Get<HttpCookieResource>(requestSet);
|
||||
var responseSet = await Subject.GetAsync<HttpCookieResource>(requestSet);
|
||||
|
||||
var requestClear = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestClear.Cookies.Add("my", null);
|
||||
@@ -553,24 +554,24 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestClear.StoreRequestCookie = true;
|
||||
requestClear.StoreResponseCookie = false;
|
||||
|
||||
var responseClear = Subject.Get<HttpCookieResource>(requestClear);
|
||||
var responseClear = await Subject.GetAsync<HttpCookieResource>(requestClear);
|
||||
|
||||
responseClear.Resource.Cookies.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_store_response_cookie()
|
||||
public async Task should_not_store_response_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie");
|
||||
requestSet.AllowAutoRedirect = false;
|
||||
requestSet.StoreRequestCookie = false;
|
||||
requestSet.StoreResponseCookie.Should().BeFalse();
|
||||
|
||||
var responseSet = Subject.Get(requestSet);
|
||||
var responseSet = await Subject.GetAsync(requestSet);
|
||||
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().BeEmpty();
|
||||
|
||||
@@ -578,18 +579,18 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_store_response_cookie()
|
||||
public async Task should_store_response_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie");
|
||||
requestSet.AllowAutoRedirect = false;
|
||||
requestSet.StoreRequestCookie = false;
|
||||
requestSet.StoreResponseCookie = true;
|
||||
|
||||
var responseSet = Subject.Get(requestSet);
|
||||
var responseSet = await Subject.GetAsync(requestSet);
|
||||
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
|
||||
@@ -597,13 +598,13 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_temp_store_response_cookie()
|
||||
public async Task should_temp_store_response_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie");
|
||||
requestSet.AllowAutoRedirect = true;
|
||||
requestSet.StoreRequestCookie = false;
|
||||
requestSet.StoreResponseCookie.Should().BeFalse();
|
||||
var responseSet = Subject.Get<HttpCookieResource>(requestSet);
|
||||
var responseSet = await Subject.GetAsync<HttpCookieResource>(requestSet);
|
||||
|
||||
// Set and redirect since that's the only way to check the internal temporary cookie container
|
||||
responseSet.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
@@ -612,7 +613,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_overwrite_response_cookie()
|
||||
public async Task should_overwrite_response_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie");
|
||||
requestSet.Cookies.Add("my", "oldcookie");
|
||||
@@ -620,11 +621,11 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestSet.StoreRequestCookie = false;
|
||||
requestSet.StoreResponseCookie = true;
|
||||
|
||||
var responseSet = Subject.Get(requestSet);
|
||||
var responseSet = await Subject.GetAsync(requestSet);
|
||||
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
|
||||
@@ -632,7 +633,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_overwrite_temp_response_cookie()
|
||||
public async Task should_overwrite_temp_response_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie");
|
||||
requestSet.Cookies.Add("my", "oldcookie");
|
||||
@@ -640,13 +641,13 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestSet.StoreRequestCookie = true;
|
||||
requestSet.StoreResponseCookie = false;
|
||||
|
||||
var responseSet = Subject.Get<HttpCookieResource>(requestSet);
|
||||
var responseSet = await Subject.GetAsync<HttpCookieResource>(requestSet);
|
||||
|
||||
responseSet.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "oldcookie");
|
||||
|
||||
@@ -654,14 +655,14 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_delete_response_cookie()
|
||||
public async Task should_not_delete_response_cookie()
|
||||
{
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestCookies.Cookies.Add("my", "cookie");
|
||||
requestCookies.AllowAutoRedirect = false;
|
||||
requestCookies.StoreRequestCookie = true;
|
||||
requestCookies.StoreResponseCookie = false;
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
|
||||
@@ -670,13 +671,13 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestDelete.StoreRequestCookie = false;
|
||||
requestDelete.StoreResponseCookie = false;
|
||||
|
||||
var responseDelete = Subject.Get(requestDelete);
|
||||
var responseDelete = await Subject.GetAsync(requestDelete);
|
||||
|
||||
requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestCookies.StoreRequestCookie = false;
|
||||
requestCookies.StoreResponseCookie = false;
|
||||
|
||||
responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
|
||||
@@ -684,14 +685,14 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_response_cookie()
|
||||
public async Task should_delete_response_cookie()
|
||||
{
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestCookies.Cookies.Add("my", "cookie");
|
||||
requestCookies.AllowAutoRedirect = false;
|
||||
requestCookies.StoreRequestCookie = true;
|
||||
requestCookies.StoreResponseCookie = false;
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
|
||||
@@ -700,13 +701,13 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestDelete.StoreRequestCookie = false;
|
||||
requestDelete.StoreResponseCookie = true;
|
||||
|
||||
var responseDelete = Subject.Get(requestDelete);
|
||||
var responseDelete = await Subject.GetAsync(requestDelete);
|
||||
|
||||
requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestCookies.StoreRequestCookie = false;
|
||||
requestCookies.StoreResponseCookie = false;
|
||||
|
||||
responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().BeEmpty();
|
||||
|
||||
@@ -714,14 +715,14 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_temp_response_cookie()
|
||||
public async Task should_delete_temp_response_cookie()
|
||||
{
|
||||
var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies");
|
||||
requestCookies.Cookies.Add("my", "cookie");
|
||||
requestCookies.AllowAutoRedirect = false;
|
||||
requestCookies.StoreRequestCookie = true;
|
||||
requestCookies.StoreResponseCookie = false;
|
||||
var responseCookies = Subject.Get<HttpCookieResource>(requestCookies);
|
||||
var responseCookies = await Subject.GetAsync<HttpCookieResource>(requestCookies);
|
||||
|
||||
responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie");
|
||||
|
||||
@@ -729,7 +730,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestDelete.AllowAutoRedirect = true;
|
||||
requestDelete.StoreRequestCookie = false;
|
||||
requestDelete.StoreResponseCookie = false;
|
||||
var responseDelete = Subject.Get<HttpCookieResource>(requestDelete);
|
||||
var responseDelete = await Subject.GetAsync<HttpCookieResource>(requestDelete);
|
||||
|
||||
responseDelete.Resource.Cookies.Should().BeEmpty();
|
||||
|
||||
@@ -747,13 +748,13 @@ namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/status/429");
|
||||
|
||||
Assert.Throws<TooManyRequestsException>(() => Subject.Get(request));
|
||||
Assert.ThrowsAsync<TooManyRequestsException>(async () => await Subject.GetAsync(request));
|
||||
|
||||
ExceptionVerification.IgnoreWarns();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_call_interceptor()
|
||||
public async Task should_call_interceptor()
|
||||
{
|
||||
Mocker.SetConstant<IEnumerable<IHttpRequestInterceptor>>(new[] { Mocker.GetMock<IHttpRequestInterceptor>().Object });
|
||||
|
||||
@@ -767,7 +768,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
|
||||
Subject.Get(request);
|
||||
await Subject.GetAsync(request);
|
||||
|
||||
Mocker.GetMock<IHttpRequestInterceptor>()
|
||||
.Verify(v => v.PreRequest(It.IsAny<HttpRequest>()), Times.Once());
|
||||
@@ -778,7 +779,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
|
||||
[TestCase("en-US")]
|
||||
[TestCase("es-ES")]
|
||||
public void should_parse_malformed_cloudflare_cookie(string culture)
|
||||
public async Task should_parse_malformed_cloudflare_cookie(string culture)
|
||||
{
|
||||
var origCulture = Thread.CurrentThread.CurrentCulture;
|
||||
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
|
||||
@@ -794,11 +795,11 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestSet.AllowAutoRedirect = false;
|
||||
requestSet.StoreResponseCookie = true;
|
||||
|
||||
var responseSet = Subject.Get(requestSet);
|
||||
var responseSet = await Subject.GetAsync(requestSet);
|
||||
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers.Should().ContainKey("Cookie");
|
||||
|
||||
@@ -816,7 +817,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
}
|
||||
|
||||
[TestCase("lang_code=en; expires=Wed, 23-Dec-2026 18:09:14 GMT; Max-Age=31536000; path=/; domain=.abc.com")]
|
||||
public void should_reject_malformed_domain_cookie(string malformedCookie)
|
||||
public async Task should_reject_malformed_domain_cookie(string malformedCookie)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -826,11 +827,11 @@ namespace NzbDrone.Common.Test.Http
|
||||
requestSet.AllowAutoRedirect = false;
|
||||
requestSet.StoreResponseCookie = true;
|
||||
|
||||
var responseSet = Subject.Get(requestSet);
|
||||
var responseSet = await Subject.GetAsync(requestSet);
|
||||
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
var response = await Subject.GetAsync<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers.Should().NotContainKey("Cookie");
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace NzbDrone.Common.Test.TPLTests
|
||||
|
||||
Subject.WaitAndPulse("me", "sub", TimeSpan.FromMilliseconds(100));
|
||||
|
||||
(GetRateLimitStore()["me"] - _epoch).Should().BeCloseTo(TimeSpan.FromMilliseconds(200));
|
||||
(GetRateLimitStore()["me"] - _epoch).Should().BeCloseTo(TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(20));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,9 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||
FullName = Name;
|
||||
}
|
||||
|
||||
if (IsLinux && File.Exists("/proc/1/cgroup") && File.ReadAllText("/proc/1/cgroup").Contains("/docker/"))
|
||||
if (IsLinux &&
|
||||
((File.Exists("/proc/1/cgroup") && File.ReadAllText("/proc/1/cgroup").Contains("/docker/")) ||
|
||||
(File.Exists("/proc/1/mountinfo") && File.ReadAllText("/proc/1/mountinfo").Contains("/docker/"))))
|
||||
{
|
||||
IsDocker = true;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NzbDrone.Common.Http.Dispatchers
|
||||
{
|
||||
public interface IHttpDispatcher
|
||||
{
|
||||
HttpResponse GetResponse(HttpRequest request, CookieContainer cookies);
|
||||
Task<HttpResponse> GetResponseAsync(HttpRequest request, CookieContainer cookies);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,9 +43,13 @@ namespace NzbDrone.Common.Http.Dispatchers
|
||||
_credentialCache = cacheManager.GetCache<CredentialCache>(typeof(ManagedHttpDispatcher), "credentialcache");
|
||||
}
|
||||
|
||||
public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies)
|
||||
public async Task<HttpResponse> GetResponseAsync(HttpRequest request, CookieContainer cookies)
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(request.Method, (Uri)request.Url);
|
||||
var requestMessage = new HttpRequestMessage(request.Method, (Uri)request.Url)
|
||||
{
|
||||
Version = HttpVersion.Version20,
|
||||
VersionPolicy = HttpVersionPolicy.RequestVersionOrLower
|
||||
};
|
||||
requestMessage.Headers.UserAgent.ParseAdd(_userAgentBuilder.GetUserAgent(request.UseSimplifiedUserAgent));
|
||||
requestMessage.Headers.ConnectionClose = !request.ConnectionKeepAlive;
|
||||
|
||||
@@ -98,7 +102,7 @@ namespace NzbDrone.Common.Http.Dispatchers
|
||||
|
||||
var httpClient = GetClient(request.Url);
|
||||
|
||||
using var responseMessage = httpClient.Send(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token);
|
||||
using var responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token);
|
||||
{
|
||||
byte[] data = null;
|
||||
|
||||
@@ -106,7 +110,7 @@ namespace NzbDrone.Common.Http.Dispatchers
|
||||
{
|
||||
if (request.ResponseStream != null && responseMessage.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
responseMessage.Content.CopyTo(request.ResponseStream, null, cts.Token);
|
||||
await responseMessage.Content.CopyToAsync(request.ResponseStream, null, cts.Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,7 +126,7 @@ namespace NzbDrone.Common.Http.Dispatchers
|
||||
|
||||
headers.Add(responseMessage.Content.Headers.ToNameValueCollection());
|
||||
|
||||
return new HttpResponse(request, new HttpHeader(headers), data, responseMessage.StatusCode);
|
||||
return new HttpResponse(request, new HttpHeader(headers), data, responseMessage.StatusCode, responseMessage.Version);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +163,8 @@ namespace NzbDrone.Common.Http.Dispatchers
|
||||
|
||||
var client = new System.Net.Http.HttpClient(handler)
|
||||
{
|
||||
DefaultRequestVersion = HttpVersion.Version20,
|
||||
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower,
|
||||
Timeout = Timeout.InfiniteTimeSpan
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
@@ -25,6 +26,16 @@ namespace NzbDrone.Common.Http
|
||||
HttpResponse Post(HttpRequest request);
|
||||
HttpResponse<T> Post<T>(HttpRequest request)
|
||||
where T : new();
|
||||
|
||||
Task<HttpResponse> ExecuteAsync(HttpRequest request);
|
||||
Task DownloadFileAsync(string url, string fileName);
|
||||
Task<HttpResponse> GetAsync(HttpRequest request);
|
||||
Task<HttpResponse<T>> GetAsync<T>(HttpRequest request)
|
||||
where T : new();
|
||||
Task<HttpResponse> HeadAsync(HttpRequest request);
|
||||
Task<HttpResponse> PostAsync(HttpRequest request);
|
||||
Task<HttpResponse<T>> PostAsync<T>(HttpRequest request)
|
||||
where T : new();
|
||||
}
|
||||
|
||||
public class HttpClient : IHttpClient
|
||||
@@ -52,11 +63,11 @@ namespace NzbDrone.Common.Http
|
||||
_cookieContainerCache = cacheManager.GetCache<CookieContainer>(typeof(HttpClient));
|
||||
}
|
||||
|
||||
public HttpResponse Execute(HttpRequest request)
|
||||
public virtual async Task<HttpResponse> ExecuteAsync(HttpRequest request)
|
||||
{
|
||||
var cookieContainer = InitializeRequestCookies(request);
|
||||
|
||||
var response = ExecuteRequest(request, cookieContainer);
|
||||
var response = await ExecuteRequestAsync(request, cookieContainer);
|
||||
|
||||
if (request.AllowAutoRedirect && response.HasHttpRedirect)
|
||||
{
|
||||
@@ -82,7 +93,7 @@ namespace NzbDrone.Common.Http
|
||||
request.ContentSummary = null;
|
||||
}
|
||||
|
||||
response = ExecuteRequest(request, cookieContainer);
|
||||
response = await ExecuteRequestAsync(request, cookieContainer);
|
||||
}
|
||||
while (response.HasHttpRedirect);
|
||||
}
|
||||
@@ -112,6 +123,11 @@ namespace NzbDrone.Common.Http
|
||||
return response;
|
||||
}
|
||||
|
||||
public HttpResponse Execute(HttpRequest request)
|
||||
{
|
||||
return ExecuteAsync(request).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private static bool RequestRequiresForceGet(HttpStatusCode statusCode, HttpMethod requestMethod)
|
||||
{
|
||||
return statusCode switch
|
||||
@@ -122,7 +138,7 @@ namespace NzbDrone.Common.Http
|
||||
};
|
||||
}
|
||||
|
||||
private HttpResponse ExecuteRequest(HttpRequest request, CookieContainer cookieContainer)
|
||||
private async Task<HttpResponse> ExecuteRequestAsync(HttpRequest request, CookieContainer cookieContainer)
|
||||
{
|
||||
foreach (var interceptor in _requestInterceptors)
|
||||
{
|
||||
@@ -131,14 +147,14 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
if (request.RateLimit != TimeSpan.Zero)
|
||||
{
|
||||
_rateLimitService.WaitAndPulse(request.Url.Host, request.RateLimitKey, request.RateLimit);
|
||||
await _rateLimitService.WaitAndPulseAsync(request.Url.Host, request.RateLimitKey, request.RateLimit);
|
||||
}
|
||||
|
||||
_logger.Trace(request);
|
||||
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
|
||||
var response = _httpDispatcher.GetResponse(request, cookieContainer);
|
||||
var response = await _httpDispatcher.GetResponseAsync(request, cookieContainer);
|
||||
|
||||
HandleResponseCookies(response, cookieContainer);
|
||||
|
||||
@@ -246,7 +262,7 @@ namespace NzbDrone.Common.Http
|
||||
}
|
||||
}
|
||||
|
||||
public void DownloadFile(string url, string fileName)
|
||||
public async Task DownloadFileAsync(string url, string fileName)
|
||||
{
|
||||
var fileNamePart = fileName + ".part";
|
||||
|
||||
@@ -261,12 +277,12 @@ namespace NzbDrone.Common.Http
|
||||
_logger.Debug("Downloading [{0}] to [{1}]", url, fileName);
|
||||
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
using (var fileStream = new FileStream(fileNamePart, FileMode.Create, FileAccess.ReadWrite))
|
||||
await using (var fileStream = new FileStream(fileNamePart, FileMode.Create, FileAccess.ReadWrite))
|
||||
{
|
||||
var request = new HttpRequest(url);
|
||||
request.AllowAutoRedirect = true;
|
||||
request.ResponseStream = fileStream;
|
||||
var response = Get(request);
|
||||
var response = await GetAsync(request);
|
||||
|
||||
if (response.Headers.ContentType != null && response.Headers.ContentType.Contains("text/html"))
|
||||
{
|
||||
@@ -293,38 +309,71 @@ namespace NzbDrone.Common.Http
|
||||
}
|
||||
}
|
||||
|
||||
public HttpResponse Get(HttpRequest request)
|
||||
public void DownloadFile(string url, string fileName)
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development#the-thread-pool-hack
|
||||
Task.Run(() => DownloadFileAsync(url, fileName)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public Task<HttpResponse> GetAsync(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.Get;
|
||||
return Execute(request);
|
||||
return ExecuteAsync(request);
|
||||
}
|
||||
|
||||
public HttpResponse Get(HttpRequest request)
|
||||
{
|
||||
return Task.Run(() => GetAsync(request)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public async Task<HttpResponse<T>> GetAsync<T>(HttpRequest request)
|
||||
where T : new()
|
||||
{
|
||||
var response = await GetAsync(request);
|
||||
CheckResponseContentType(response);
|
||||
return new HttpResponse<T>(response);
|
||||
}
|
||||
|
||||
public HttpResponse<T> Get<T>(HttpRequest request)
|
||||
where T : new()
|
||||
{
|
||||
var response = Get(request);
|
||||
CheckResponseContentType(response);
|
||||
return new HttpResponse<T>(response);
|
||||
return Task.Run(() => GetAsync<T>(request)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public Task<HttpResponse> HeadAsync(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.Head;
|
||||
return ExecuteAsync(request);
|
||||
}
|
||||
|
||||
public HttpResponse Head(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.Head;
|
||||
return Execute(request);
|
||||
return Task.Run(() => HeadAsync(request)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public Task<HttpResponse> PostAsync(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.Post;
|
||||
return ExecuteAsync(request);
|
||||
}
|
||||
|
||||
public HttpResponse Post(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.Post;
|
||||
return Execute(request);
|
||||
return Task.Run(() => PostAsync(request)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public async Task<HttpResponse<T>> PostAsync<T>(HttpRequest request)
|
||||
where T : new()
|
||||
{
|
||||
var response = await PostAsync(request);
|
||||
CheckResponseContentType(response);
|
||||
return new HttpResponse<T>(response);
|
||||
}
|
||||
|
||||
public HttpResponse<T> Post<T>(HttpRequest request)
|
||||
where T : new()
|
||||
{
|
||||
var response = Post(request);
|
||||
CheckResponseContentType(response);
|
||||
return new HttpResponse<T>(response);
|
||||
return Task.Run(() => PostAsync<T>(request)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void CheckResponseContentType(HttpResponse response)
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace NzbDrone.Common.Http
|
||||
Method = HttpMethod.Get;
|
||||
Url = new HttpUri(url);
|
||||
Headers = new HttpHeader();
|
||||
ConnectionKeepAlive = true;
|
||||
AllowAutoRedirect = true;
|
||||
StoreRequestCookie = true;
|
||||
IgnorePersistentCookies = false;
|
||||
|
||||
@@ -9,28 +9,31 @@ namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class HttpResponse
|
||||
{
|
||||
private static readonly Regex RegexSetCookie = new Regex("^(.*?)=(.*?)(?:;|$)", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexSetCookie = new ("^(.*?)=(.*?)(?:;|$)", RegexOptions.Compiled);
|
||||
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, byte[] binaryData, HttpStatusCode statusCode = HttpStatusCode.OK)
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, byte[] binaryData, HttpStatusCode statusCode = HttpStatusCode.OK, Version version = null)
|
||||
{
|
||||
Request = request;
|
||||
Headers = headers;
|
||||
ResponseData = binaryData;
|
||||
StatusCode = statusCode;
|
||||
Version = version;
|
||||
}
|
||||
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, string content, HttpStatusCode statusCode = HttpStatusCode.OK)
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, string content, HttpStatusCode statusCode = HttpStatusCode.OK, Version version = null)
|
||||
{
|
||||
Request = request;
|
||||
Headers = headers;
|
||||
ResponseData = Headers.GetEncodingFromContentType().GetBytes(content);
|
||||
_content = content;
|
||||
StatusCode = statusCode;
|
||||
Version = version;
|
||||
}
|
||||
|
||||
public HttpRequest Request { get; private set; }
|
||||
public HttpHeader Headers { get; private set; }
|
||||
public HttpStatusCode StatusCode { get; private set; }
|
||||
public Version Version { get; private set; }
|
||||
public byte[] ResponseData { get; private set; }
|
||||
|
||||
private string _content;
|
||||
@@ -84,7 +87,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var result = string.Format("Res: [{0}] {1}: {2}.{3} ({4} bytes)", Request.Method, Request.Url, (int)StatusCode, StatusCode, ResponseData?.Length ?? 0);
|
||||
var result = $"Res: HTTP/{Version} [{Request.Method}] {Request.Url}: {(int)StatusCode}.{StatusCode} ({ResponseData?.Length ?? 0} bytes)";
|
||||
|
||||
if (HasHttpError && Headers.ContentType.IsNotNullOrWhiteSpace() && !Headers.ContentType.Equals("text/html", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
@@ -99,7 +102,7 @@ namespace NzbDrone.Common.Http
|
||||
where T : new()
|
||||
{
|
||||
public HttpResponse(HttpResponse response)
|
||||
: base(response.Request, response.Headers, response.ResponseData, response.StatusCode)
|
||||
: base(response.Request, response.Headers, response.ResponseData, response.StatusCode, response.Version)
|
||||
{
|
||||
Resource = Json.Deserialize<T>(response.Content);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageReference Include="NLog" Version="5.2.0" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.0" />
|
||||
<PackageReference Include="Npgsql" Version="5.0.11" />
|
||||
<PackageReference Include="Npgsql" Version="7.0.4" />
|
||||
<PackageReference Include="Sentry" Version="3.23.1" />
|
||||
<PackageReference Include="NLog.Targets.Syslog" Version="7.0.0" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -10,6 +11,8 @@ namespace NzbDrone.Common.TPL
|
||||
{
|
||||
void WaitAndPulse(string key, TimeSpan interval);
|
||||
void WaitAndPulse(string key, string subKey, TimeSpan interval);
|
||||
Task WaitAndPulseAsync(string key, TimeSpan interval);
|
||||
Task WaitAndPulseAsync(string key, string subKey, TimeSpan interval);
|
||||
}
|
||||
|
||||
public class RateLimitService : IRateLimitService
|
||||
@@ -28,7 +31,34 @@ namespace NzbDrone.Common.TPL
|
||||
WaitAndPulse(key, null, interval);
|
||||
}
|
||||
|
||||
public async Task WaitAndPulseAsync(string key, TimeSpan interval)
|
||||
{
|
||||
await WaitAndPulseAsync(key, null, interval);
|
||||
}
|
||||
|
||||
public void WaitAndPulse(string key, string subKey, TimeSpan interval)
|
||||
{
|
||||
var delay = GetDelay(key, subKey, interval);
|
||||
|
||||
if (delay.TotalSeconds > 0.0)
|
||||
{
|
||||
_logger.Trace("Rate Limit triggered, delaying '{0}' for {1:0.000} sec", key, delay.TotalSeconds);
|
||||
System.Threading.Thread.Sleep(delay);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task WaitAndPulseAsync(string key, string subKey, TimeSpan interval)
|
||||
{
|
||||
var delay = GetDelay(key, subKey, interval);
|
||||
|
||||
if (delay.TotalSeconds > 0.0)
|
||||
{
|
||||
_logger.Trace("Rate Limit triggered, delaying '{0}' for {1:0.000} sec", key, delay.TotalSeconds);
|
||||
await Task.Delay(delay);
|
||||
}
|
||||
}
|
||||
|
||||
private TimeSpan GetDelay(string key, string subKey, TimeSpan interval)
|
||||
{
|
||||
var waitUntil = DateTime.UtcNow.Add(interval);
|
||||
|
||||
@@ -59,13 +89,7 @@ namespace NzbDrone.Common.TPL
|
||||
|
||||
waitUntil -= interval;
|
||||
|
||||
var delay = waitUntil - DateTime.UtcNow;
|
||||
|
||||
if (delay.TotalSeconds > 0.0)
|
||||
{
|
||||
_logger.Trace("Rate Limit triggered, delaying '{0}' for {1:0.000} sec", key, delay.TotalSeconds);
|
||||
System.Threading.Thread.Sleep(delay);
|
||||
}
|
||||
return waitUntil - DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
[TestFixture]
|
||||
public class BasicRepositoryFixture : DbTest<BasicRepository<ScheduledTask>, ScheduledTask>
|
||||
{
|
||||
private readonly TimeSpan _dateTimePrecision = TimeSpan.FromMilliseconds(20);
|
||||
private List<ScheduledTask> _basicList;
|
||||
|
||||
[SetUp]
|
||||
@@ -20,7 +21,7 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
{
|
||||
AssertionOptions.AssertEquivalencyUsing(options =>
|
||||
{
|
||||
options.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation.ToUniversalTime())).WhenTypeIs<DateTime>();
|
||||
options.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation.ToUniversalTime(), _dateTimePrecision)).WhenTypeIs<DateTime>();
|
||||
return options;
|
||||
});
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
|
||||
var items = profiles.First().Items;
|
||||
items.Should().HaveCount(5);
|
||||
items.Select(v => v.Quality).Should().BeEquivalentTo(1, null, null, null, null);
|
||||
items.Select(v => v.Items.Count).Should().BeEquivalentTo(0, 2, 2, 2, 2);
|
||||
items.Select(v => v.Allowed).Should().BeEquivalentTo(true, false, false, false, false);
|
||||
items.Select(v => v.Quality).Should().Equal(1, null, null, null, null);
|
||||
items.Select(v => v.Items.Count).Should().Equal(0, 2, 2, 2, 2);
|
||||
items.Select(v => v.Allowed).Should().Equal(true, false, false, false, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -61,9 +61,9 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
|
||||
var items = profiles.First().Items;
|
||||
items.Should().HaveCount(5);
|
||||
items.Select(v => v.Quality).Should().BeEquivalentTo(1, null, null, null, null);
|
||||
items.Select(v => v.Items.Count).Should().BeEquivalentTo(0, 2, 2, 2, 2);
|
||||
items.Select(v => v.Allowed).Should().BeEquivalentTo(true, false, false, false, false);
|
||||
items.Select(v => v.Quality).Should().Equal(1, null, null, null, null);
|
||||
items.Select(v => v.Items.Count).Should().Equal(0, 2, 2, 2, 2);
|
||||
items.Select(v => v.Allowed).Should().Equal(true, false, false, false, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -85,9 +85,9 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
var items = profiles.First().Items;
|
||||
items.Count(c => c.Id == 1001).Should().Be(1);
|
||||
items.Should().HaveCount(5);
|
||||
items.Select(v => v.Quality).Should().BeEquivalentTo(1, null, null, null, null);
|
||||
items.Select(v => v.Items.Count).Should().BeEquivalentTo(0, 2, 2, 2, 2);
|
||||
items.Select(v => v.Allowed).Should().BeEquivalentTo(true, false, false, false, false);
|
||||
items.Select(v => v.Quality).Should().Equal(1, null, null, null, null);
|
||||
items.Select(v => v.Items.Count).Should().Equal(0, 2, 2, 2, 2);
|
||||
items.Select(v => v.Allowed).Should().Equal(true, false, false, false, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -71,19 +72,19 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_download_report_if_movie_was_not_already_downloaded()
|
||||
public async Task should_download_report_if_movie_was_not_already_downloaded()
|
||||
{
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
await Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_only_download_movie_once()
|
||||
public async Task should_only_download_movie_once()
|
||||
{
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
@@ -91,12 +92,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
await Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_download_if_any_movie_was_already_downloaded()
|
||||
public async Task should_not_download_if_any_movie_was_already_downloaded()
|
||||
{
|
||||
var remoteMovie1 = GetRemoteMovie(
|
||||
new QualityModel(Quality.HDTV720p));
|
||||
@@ -108,23 +109,25 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
decisions.Add(new DownloadDecision(remoteMovie1));
|
||||
decisions.Add(new DownloadDecision(remoteMovie2));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
await Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_downloaded_reports()
|
||||
public async Task should_return_downloaded_reports()
|
||||
{
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(1);
|
||||
var result = await Subject.ProcessDecisions(decisions);
|
||||
|
||||
result.Grabbed.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_all_downloaded_reports()
|
||||
public async Task should_return_all_downloaded_reports()
|
||||
{
|
||||
var remoteMovie1 = GetRemoteMovie(new QualityModel(Quality.HDTV720p), GetMovie(1));
|
||||
|
||||
@@ -134,11 +137,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
decisions.Add(new DownloadDecision(remoteMovie1));
|
||||
decisions.Add(new DownloadDecision(remoteMovie2));
|
||||
|
||||
Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(2);
|
||||
var result = await Subject.ProcessDecisions(decisions);
|
||||
|
||||
result.Grabbed.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_only_return_downloaded_reports()
|
||||
public async Task should_only_return_downloaded_reports()
|
||||
{
|
||||
var remoteMovie1 = GetRemoteMovie(
|
||||
new QualityModel(Quality.HDTV720p),
|
||||
@@ -157,11 +162,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
decisions.Add(new DownloadDecision(remoteMovie2));
|
||||
decisions.Add(new DownloadDecision(remoteMovie3));
|
||||
|
||||
Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(2);
|
||||
var result = await Subject.ProcessDecisions(decisions);
|
||||
|
||||
result.Grabbed.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_add_to_downloaded_list_when_download_fails()
|
||||
public async Task should_not_add_to_downloaded_list_when_download_fails()
|
||||
{
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
@@ -169,7 +176,11 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
Mocker.GetMock<IDownloadService>().Setup(s => s.DownloadReport(It.IsAny<RemoteMovie>())).Throws(new Exception());
|
||||
Subject.ProcessDecisions(decisions).Grabbed.Should().BeEmpty();
|
||||
|
||||
var result = await Subject.ProcessDecisions(decisions);
|
||||
|
||||
result.Grabbed.Should().BeEmpty();
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
@@ -185,19 +196,19 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_grab_if_pending()
|
||||
public async Task should_not_grab_if_pending()
|
||||
{
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
await Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_add_to_pending_if_movie_was_grabbed()
|
||||
public async Task should_not_add_to_pending_if_movie_was_grabbed()
|
||||
{
|
||||
var removeMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
@@ -205,12 +216,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
decisions.Add(new DownloadDecision(removeMovie));
|
||||
decisions.Add(new DownloadDecision(removeMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
await Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IPendingReleaseService>().Verify(v => v.AddMany(It.IsAny<List<Tuple<DownloadDecision, PendingReleaseReason>>>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_to_pending_even_if_already_added_to_pending()
|
||||
public async Task should_add_to_pending_even_if_already_added_to_pending()
|
||||
{
|
||||
var remoteEpisode = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
@@ -218,12 +229,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
await Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IPendingReleaseService>().Verify(v => v.AddMany(It.IsAny<List<Tuple<DownloadDecision, PendingReleaseReason>>>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_to_failed_if_already_failed_for_that_protocol()
|
||||
public async Task should_add_to_failed_if_already_failed_for_that_protocol()
|
||||
{
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
@@ -234,12 +245,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
Mocker.GetMock<IDownloadService>().Setup(s => s.DownloadReport(It.IsAny<RemoteMovie>()))
|
||||
.Throws(new DownloadClientUnavailableException("Download client failed"));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
await Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_add_to_failed_if_failed_for_a_different_protocol()
|
||||
public async Task should_not_add_to_failed_if_failed_for_a_different_protocol()
|
||||
{
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p), null, DownloadProtocol.Usenet);
|
||||
var remoteMovie2 = GetRemoteMovie(new QualityModel(Quality.HDTV720p), null, DownloadProtocol.Torrent);
|
||||
@@ -251,13 +262,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
Mocker.GetMock<IDownloadService>().Setup(s => s.DownloadReport(It.Is<RemoteMovie>(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet)))
|
||||
.Throws(new DownloadClientUnavailableException("Download client failed"));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
await Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.Is<RemoteMovie>(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet)), Times.Once());
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.Is<RemoteMovie>(r => r.Release.DownloadProtocol == DownloadProtocol.Torrent)), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_to_rejected_if_release_unavailable_on_indexer()
|
||||
public async Task should_add_to_rejected_if_release_unavailable_on_indexer()
|
||||
{
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
@@ -268,7 +279,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
.Setup(s => s.DownloadReport(It.IsAny<RemoteMovie>()))
|
||||
.Throws(new ReleaseUnavailableException(remoteMovie.Release, "That 404 Error is not just a Quirk"));
|
||||
|
||||
var result = Subject.ProcessDecisions(decisions);
|
||||
var result = await Subject.ProcessDecisions(decisions);
|
||||
|
||||
result.Grabbed.Should().BeEmpty();
|
||||
result.Rejected.Should().NotBeEmpty();
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -66,7 +67,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
protected void GivenFailedDownload()
|
||||
{
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||
.Setup(s => s.GetAsync(It.IsAny<HttpRequest>()))
|
||||
.Throws(new WebException());
|
||||
}
|
||||
|
||||
@@ -144,19 +145,19 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_download_file_if_it_doesnt_exist()
|
||||
public async Task Download_should_download_file_if_it_doesnt_exist()
|
||||
{
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.GetAsync(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_save_magnet_if_enabled()
|
||||
public async Task Download_should_save_magnet_if_enabled()
|
||||
{
|
||||
GivenMagnetFilePath();
|
||||
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
||||
@@ -164,16 +165,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = null;
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.GetAsync(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Never());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_save_magnet_using_specified_extension()
|
||||
public async Task Download_should_save_magnet_using_specified_extension()
|
||||
{
|
||||
var magnetFileExtension = ".url";
|
||||
GivenMagnetFilePath(magnetFileExtension);
|
||||
@@ -183,12 +184,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = null;
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.GetAsync(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Never());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -197,31 +198,31 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = null;
|
||||
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteMovie, CreateIndexer()));
|
||||
Assert.ThrowsAsync<ReleaseDownloadException>(async () => await Subject.Download(remoteMovie, CreateIndexer()));
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.GetAsync(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Never());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_prefer_torrent_over_magnet()
|
||||
public async Task Download_should_prefer_torrent_over_magnet()
|
||||
{
|
||||
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.GetAsync(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_replace_illegal_characters_in_title()
|
||||
public async Task Download_should_replace_illegal_characters_in_title()
|
||||
{
|
||||
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
||||
var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath));
|
||||
@@ -229,11 +230,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.Title = illegalTitle;
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.GetAsync(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -242,7 +243,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = null;
|
||||
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteMovie, CreateIndexer()));
|
||||
Assert.ThrowsAsync<ReleaseDownloadException>(async () => await Subject.Download(remoteMovie, CreateIndexer()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -312,11 +313,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_null_hash()
|
||||
public async Task should_return_null_hash()
|
||||
{
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer()).Should().BeNull();
|
||||
var result = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
result.Should().BeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -115,19 +116,19 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_download_file_if_it_doesnt_exist()
|
||||
public async Task Download_should_download_file_if_it_doesnt_exist()
|
||||
{
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.GetAsync(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_replace_illegal_characters_in_title()
|
||||
public async Task Download_should_replace_illegal_characters_in_title()
|
||||
{
|
||||
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
||||
var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath));
|
||||
@@ -135,11 +136,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.Title = illegalTitle;
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.GetAsync(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -200,26 +201,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")]
|
||||
public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = magnetUrl;
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().Be(expectedHash);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NLog;
|
||||
@@ -36,8 +37,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
.Returns(() => CreateRemoteMovie());
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), Array.Empty<byte>()));
|
||||
.Setup(s => s.GetAsync(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), Array.Empty<byte>())));
|
||||
|
||||
Mocker.GetMock<IRemotePathMappingService>()
|
||||
.Setup(v => v.RemapRemoteToLocal(It.IsAny<string>(), It.IsAny<OsPath>()))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -385,7 +386,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_TvDirectory_should_force_directory()
|
||||
public async Task Download_with_TvDirectory_should_force_directory()
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenTvDirectory();
|
||||
@@ -393,7 +394,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
|
||||
var remoteEpisode = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteEpisode, CreateIndexer());
|
||||
var id = await Subject.Download(remoteEpisode, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -402,7 +403,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_category_should_force_directory()
|
||||
public async Task Download_with_category_should_force_directory()
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenTvCategory();
|
||||
@@ -410,7 +411,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
|
||||
var remoteEpisode = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteEpisode, CreateIndexer());
|
||||
var id = await Subject.Download(remoteEpisode, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -419,14 +420,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_without_TvDirectory_and_Category_should_use_default()
|
||||
public async Task Download_without_TvDirectory_and_Category_should_use_default()
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteEpisode, CreateIndexer());
|
||||
var id = await Subject.Download(remoteEpisode, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -505,7 +506,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
.Setup(s => s.GetSerialNumber(_settings))
|
||||
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
|
||||
|
||||
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Download(remoteEpisode, CreateIndexer()));
|
||||
Assert.ThrowsAsync(Is.InstanceOf<Exception>(), async () => await Subject.Download(remoteEpisode, CreateIndexer()));
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, _settings), Times.Never());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -267,7 +268,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_TvDirectory_should_force_directory()
|
||||
public async Task Download_with_TvDirectory_should_force_directory()
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenTvDirectory();
|
||||
@@ -275,7 +276,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
|
||||
var remoteEpisode = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteEpisode, CreateIndexer());
|
||||
var id = await Subject.Download(remoteEpisode, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -284,7 +285,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_category_should_force_directory()
|
||||
public async Task Download_with_category_should_force_directory()
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenTvCategory();
|
||||
@@ -292,7 +293,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
|
||||
var remoteEpisode = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteEpisode, CreateIndexer());
|
||||
var id = await Subject.Download(remoteEpisode, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -301,14 +302,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_without_TvDirectory_and_Category_should_use_default()
|
||||
public async Task Download_without_TvDirectory_and_Category_should_use_default()
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteEpisode, CreateIndexer());
|
||||
var id = await Subject.Download(remoteEpisode, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -387,7 +388,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
.Setup(s => s.GetSerialNumber(_settings))
|
||||
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
|
||||
|
||||
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Download(remoteEpisode, CreateIndexer()));
|
||||
Assert.ThrowsAsync(Is.InstanceOf<Exception>(), async () => await Subject.Download(remoteEpisode, CreateIndexer()));
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, _settings), Times.Never());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -146,21 +147,21 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_DestinationDirectory_should_force_directory()
|
||||
public async Task Download_with_DestinationDirectory_should_force_directory()
|
||||
{
|
||||
GivenDestinationDirectory();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IFreeboxDownloadProxy>()
|
||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), _encodedDestinationDirectory, It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<double?>(), It.IsAny<FreeboxDownloadSettings>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_Category_should_force_directory()
|
||||
public async Task Download_with_Category_should_force_directory()
|
||||
{
|
||||
GivenDownloadConfiguration();
|
||||
GivenCategory();
|
||||
@@ -168,21 +169,21 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IFreeboxDownloadProxy>()
|
||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), _encodedDefaultDestinationAndCategory, It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<double?>(), It.IsAny<FreeboxDownloadSettings>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_without_DestinationDirectory_and_Category_should_use_default()
|
||||
public async Task Download_without_DestinationDirectory_and_Category_should_use_default()
|
||||
{
|
||||
GivenDownloadConfiguration();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IFreeboxDownloadProxy>()
|
||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), _encodedDefaultDestination, It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<double?>(), It.IsAny<FreeboxDownloadSettings>()), Times.Once());
|
||||
@@ -190,7 +191,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
||||
|
||||
[TestCase(false, false)]
|
||||
[TestCase(true, true)]
|
||||
public void Download_should_pause_torrent_as_expected(bool addPausedSetting, bool toBePausedFlag)
|
||||
public async Task Download_should_pause_torrent_as_expected(bool addPausedSetting, bool toBePausedFlag)
|
||||
{
|
||||
_settings.AddPaused = addPausedSetting;
|
||||
|
||||
@@ -199,7 +200,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IFreeboxDownloadProxy>()
|
||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), It.IsAny<string>(), toBePausedFlag, It.IsAny<bool>(), It.IsAny<double?>(), It.IsAny<FreeboxDownloadSettings>()), Times.Once());
|
||||
@@ -213,7 +214,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
||||
[TestCase(22, (int)FreeboxDownloadPriority.Last, (int)FreeboxDownloadPriority.First, false)]
|
||||
[TestCase(22, (int)FreeboxDownloadPriority.First, (int)FreeboxDownloadPriority.Last, true)]
|
||||
[TestCase(22, (int)FreeboxDownloadPriority.Last, (int)FreeboxDownloadPriority.Last, false)]
|
||||
public void Download_should_queue_torrent_first_as_expected(int ageDay, int olderPriority, int recentPriority, bool toBeQueuedFirstFlag)
|
||||
public async Task Download_should_queue_torrent_first_as_expected(int ageDay, int olderPriority, int recentPriority, bool toBeQueuedFirstFlag)
|
||||
{
|
||||
_settings.OlderPriority = olderPriority;
|
||||
_settings.RecentPriority = recentPriority;
|
||||
@@ -225,7 +226,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
||||
|
||||
remoteMovie.Movie.MovieMetadata.Value.PhysicalRelease = DateTime.UtcNow.AddDays(-ageDay);
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IFreeboxDownloadProxy>()
|
||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), toBeQueuedFirstFlag, It.IsAny<double?>(), It.IsAny<FreeboxDownloadSettings>()), Times.Once());
|
||||
@@ -233,7 +234,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
||||
|
||||
[TestCase(0, 0)]
|
||||
[TestCase(1.5, 150)]
|
||||
public void Download_should_define_seed_ratio_as_expected(double? providerSeedRatio, double? expectedSeedRatio)
|
||||
public async Task Download_should_define_seed_ratio_as_expected(double? providerSeedRatio, double? expectedSeedRatio)
|
||||
{
|
||||
GivenDownloadConfiguration();
|
||||
GivenSuccessfulDownload();
|
||||
@@ -243,7 +244,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
||||
remoteMovie.SeedConfiguration = new TorrentSeedConfiguration();
|
||||
remoteMovie.SeedConfiguration.Ratio = providerSeedRatio;
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IFreeboxDownloadProxy>()
|
||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>(), expectedSeedRatio, It.IsAny<FreeboxDownloadSettings>()), Times.Once());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -103,8 +104,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
||||
protected void GivenSuccessfulDownload()
|
||||
{
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[1000]));
|
||||
.Setup(s => s.GetAsync(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), new byte[1000])));
|
||||
|
||||
Mocker.GetMock<IHadoukenProxy>()
|
||||
.Setup(s => s.AddTorrentUri(It.IsAny<HadoukenSettings>(), It.IsAny<string>()))
|
||||
@@ -196,13 +197,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
@@ -277,7 +278,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_from_magnet_link_should_return_hash_uppercase()
|
||||
public async Task Download_from_magnet_link_should_return_hash_uppercase()
|
||||
{
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
@@ -286,13 +287,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
||||
Mocker.GetMock<IHadoukenProxy>()
|
||||
.Setup(v => v.AddTorrentUri(It.IsAny<HadoukenSettings>(), It.IsAny<string>()));
|
||||
|
||||
var result = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var result = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Assert.IsFalse(result.Any(c => char.IsLower(c)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_from_torrent_file_should_return_hash_uppercase()
|
||||
public async Task Download_from_torrent_file_should_return_hash_uppercase()
|
||||
{
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
@@ -300,7 +301,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
||||
.Setup(v => v.AddTorrentFile(It.IsAny<HadoukenSettings>(), It.IsAny<byte[]>()))
|
||||
.Returns("hash");
|
||||
|
||||
var result = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var result = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Assert.IsFalse(result.Any(c => char.IsLower(c)));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -200,13 +201,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
@@ -218,7 +219,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Assert.Throws<DownloadClientException>(() => Subject.Download(remoteMovie, CreateIndexer()));
|
||||
Assert.ThrowsAsync<DownloadClientException>(async () => await Subject.Download(remoteMovie, CreateIndexer()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -339,13 +340,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
@@ -357,7 +358,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Assert.Throws<DownloadClientRejectedReleaseException>(() => Subject.Download(remoteMovie, CreateIndexer()));
|
||||
Assert.ThrowsAsync<DownloadClientRejectedReleaseException>(async () => await Subject.Download(remoteMovie, CreateIndexer()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NLog;
|
||||
@@ -65,15 +66,15 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
|
||||
private void WithFailedDownload()
|
||||
{
|
||||
Mocker.GetMock<IHttpClient>().Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
|
||||
Mocker.GetMock<IHttpClient>().Setup(c => c.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_download_file_if_it_doesnt_exist()
|
||||
public async Task should_download_file_if_it_doesnt_exist()
|
||||
{
|
||||
Subject.Download(_remoteMovie, _indexer);
|
||||
await Subject.Download(_remoteMovie, _indexer);
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(_nzbUrl, _nzbPath), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(_nzbUrl, _nzbPath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -81,7 +82,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
{
|
||||
WithFailedDownload();
|
||||
|
||||
Assert.Throws<WebException>(() => Subject.Download(_remoteMovie, _indexer));
|
||||
Assert.ThrowsAsync<WebException>(async () => await Subject.Download(_remoteMovie, _indexer));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -91,15 +92,15 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_replace_illegal_characters_in_title()
|
||||
public async Task should_replace_illegal_characters_in_title()
|
||||
{
|
||||
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
||||
var expectedFilename = Path.Combine(_pneumaticFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV].nzb");
|
||||
_remoteMovie.Release.Title = illegalTitle;
|
||||
|
||||
Subject.Download(_remoteMovie, _indexer);
|
||||
await Subject.Download(_remoteMovie, _indexer);
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFileAsync(It.IsAny<string>(), expectedFilename), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -448,26 +449,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")]
|
||||
public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = magnetUrl;
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().Be(expectedHash);
|
||||
}
|
||||
@@ -482,7 +483,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = "magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR";
|
||||
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteMovie, CreateIndexer()));
|
||||
Assert.ThrowsAsync<ReleaseDownloadException>(async () => await Subject.Download(remoteMovie, CreateIndexer()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -495,28 +496,28 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = "magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp://abc";
|
||||
|
||||
Assert.DoesNotThrow(() => Subject.Download(remoteMovie, CreateIndexer()));
|
||||
Assert.DoesNotThrowAsync(async () => await Subject.Download(remoteMovie, CreateIndexer()));
|
||||
|
||||
Mocker.GetMock<IQBittorrentProxy>()
|
||||
.Verify(s => s.AddTorrentFromUrl(It.IsAny<string>(), It.IsAny<TorrentSeedConfiguration>(), It.IsAny<QBittorrentSettings>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_set_top_priority()
|
||||
public async Task Download_should_set_top_priority()
|
||||
{
|
||||
GivenHighPriority();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<IQBittorrentProxy>()
|
||||
.Verify(v => v.MoveTorrentToTopInQueue(It.IsAny<string>(), It.IsAny<QBittorrentSettings>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_not_fail_if_top_priority_not_available()
|
||||
public async Task Download_should_not_fail_if_top_priority_not_available()
|
||||
{
|
||||
GivenHighPriority();
|
||||
GivenSuccessfulDownload();
|
||||
@@ -527,7 +528,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -554,27 +555,27 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_handle_http_redirect_to_magnet()
|
||||
public async Task Download_should_handle_http_redirect_to_magnet()
|
||||
{
|
||||
GivenRedirectToMagnet();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_handle_http_redirect_to_torrent()
|
||||
public async Task Download_should_handle_http_redirect_to_torrent()
|
||||
{
|
||||
GivenRedirectToTorrent();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -111,13 +112,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteEpisode, CreateIndexer());
|
||||
var id = await Subject.Download(remoteEpisode, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -299,27 +300,27 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
}
|
||||
|
||||
[TestCase("[ TOWN ]-[ http://www.town.ag ]-[ ANIME ]-[Usenet Provider >> http://www.ssl- <<] - [Commie] Aldnoah Zero 18 [234C8FC7]", "[ TOWN ]-[ http++www.town.ag ]-[ ANIME ]-[Usenet Provider http++www.ssl- ] - [Commie] Aldnoah Zero 18 [234C8FC7].nzb")]
|
||||
public void Download_should_use_clean_title(string title, string filename)
|
||||
public async Task Download_should_use_clean_title(string title, string filename)
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.Title = title;
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<ISabnzbdProxy>()
|
||||
.Verify(v => v.DownloadNzb(It.IsAny<byte[]>(), filename, It.IsAny<string>(), It.IsAny<int>(), It.IsAny<SabnzbdSettings>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
@@ -353,7 +354,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
|
||||
[Test]
|
||||
[Ignore("Series")]
|
||||
public void Download_should_use_sabRecentTvPriority_when_recentEpisode_is_true()
|
||||
public async Task Download_should_use_sabRecentTvPriority_when_recentEpisode_is_true()
|
||||
{
|
||||
Mocker.GetMock<ISabnzbdProxy>()
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), (int)SabnzbdPriority.High, It.IsAny<SabnzbdSettings>()))
|
||||
@@ -366,7 +367,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
.Build()
|
||||
.ToList();*/
|
||||
|
||||
Subject.Download(remoteMovie, CreateIndexer());
|
||||
await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
Mocker.GetMock<ISabnzbdProxy>()
|
||||
.Verify(v => v.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), (int)SabnzbdPriority.High, It.IsAny<SabnzbdSettings>()), Times.Once());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -55,26 +56,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_MovieDirectory_should_force_directory()
|
||||
public async Task Download_with_MovieDirectory_should_force_directory()
|
||||
{
|
||||
GivenMovieDirectory();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -83,14 +84,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_category_should_force_directory()
|
||||
public async Task Download_with_category_should_force_directory()
|
||||
{
|
||||
GivenMovieCategory();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -99,7 +100,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_category_should_not_have_double_slashes()
|
||||
public async Task Download_with_category_should_not_have_double_slashes()
|
||||
{
|
||||
GivenMovieCategory();
|
||||
GivenSuccessfulDownload();
|
||||
@@ -108,7 +109,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -117,13 +118,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_without_TvDirectory_and_Category_should_use_default()
|
||||
public async Task Download_without_TvDirectory_and_Category_should_use_default()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -132,14 +133,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
}
|
||||
|
||||
[TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")]
|
||||
public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = magnetUrl;
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().Be(expectedHash);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -228,13 +229,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
@@ -252,14 +253,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
||||
|
||||
// Proxy.GetTorrents does not return original url. So item has to be found via magnet url.
|
||||
[TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")]
|
||||
public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = magnetUrl;
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().Be(expectedHash);
|
||||
}
|
||||
@@ -350,27 +351,27 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_handle_http_redirect_to_magnet()
|
||||
public async Task Download_should_handle_http_redirect_to_magnet()
|
||||
{
|
||||
GivenRedirectToMagnet();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_handle_http_redirect_to_torrent()
|
||||
public async Task Download_should_handle_http_redirect_to_torrent()
|
||||
{
|
||||
GivenRedirectToTorrent();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -63,26 +64,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
public async Task Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_MovieDirectory_should_force_directory()
|
||||
public async Task Download_with_MovieDirectory_should_force_directory()
|
||||
{
|
||||
GivenMovieDirectory();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -91,14 +92,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_category_should_force_directory()
|
||||
public async Task Download_with_category_should_force_directory()
|
||||
{
|
||||
GivenMovieCategory();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -107,7 +108,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_category_should_not_have_double_slashes()
|
||||
public async Task Download_with_category_should_not_have_double_slashes()
|
||||
{
|
||||
GivenMovieCategory();
|
||||
GivenSuccessfulDownload();
|
||||
@@ -116,7 +117,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -125,13 +126,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_without_MovieDirectory_and_Category_should_use_default()
|
||||
public async Task Download_without_MovieDirectory_and_Category_should_use_default()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -140,14 +141,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
}
|
||||
|
||||
[TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")]
|
||||
public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash)
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = magnetUrl;
|
||||
|
||||
var id = Subject.Download(remoteMovie, CreateIndexer());
|
||||
var id = await Subject.Download(remoteMovie, CreateIndexer());
|
||||
|
||||
id.Should().Be(expectedHash);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -70,23 +71,23 @@ namespace NzbDrone.Core.Test.Download
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_report_should_publish_on_grab_event()
|
||||
public async Task Download_report_should_publish_on_grab_event()
|
||||
{
|
||||
var mock = WithUsenetClient();
|
||||
mock.Setup(s => s.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()));
|
||||
|
||||
Subject.DownloadReport(_parseResult);
|
||||
await Subject.DownloadReport(_parseResult);
|
||||
|
||||
VerifyEventPublished<MovieGrabbedEvent>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_report_should_grab_using_client()
|
||||
public async Task Download_report_should_grab_using_client()
|
||||
{
|
||||
var mock = WithUsenetClient();
|
||||
mock.Setup(s => s.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()));
|
||||
|
||||
Subject.DownloadReport(_parseResult);
|
||||
await Subject.DownloadReport(_parseResult);
|
||||
|
||||
mock.Verify(s => s.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()), Times.Once());
|
||||
}
|
||||
@@ -98,7 +99,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
mock.Setup(s => s.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()))
|
||||
.Throws(new WebException());
|
||||
|
||||
Assert.Throws<WebException>(() => Subject.DownloadReport(_parseResult));
|
||||
Assert.ThrowsAsync<WebException>(async () => await Subject.DownloadReport(_parseResult));
|
||||
|
||||
VerifyEventNotPublished<MovieGrabbedEvent>();
|
||||
}
|
||||
@@ -113,7 +114,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
throw new ReleaseDownloadException(v.Release, "Error", new WebException());
|
||||
});
|
||||
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.DownloadReport(_parseResult));
|
||||
Assert.ThrowsAsync<ReleaseDownloadException>(async () => await Subject.DownloadReport(_parseResult));
|
||||
|
||||
Mocker.GetMock<IIndexerStatusService>()
|
||||
.Verify(v => v.RecordFailure(It.IsAny<int>(), It.IsAny<TimeSpan>()), Times.Once());
|
||||
@@ -133,7 +134,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
throw new ReleaseDownloadException(v.Release, "Error", new TooManyRequestsException(request, response));
|
||||
});
|
||||
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.DownloadReport(_parseResult));
|
||||
Assert.ThrowsAsync<ReleaseDownloadException>(async () => await Subject.DownloadReport(_parseResult));
|
||||
|
||||
Mocker.GetMock<IIndexerStatusService>()
|
||||
.Verify(v => v.RecordFailure(It.IsAny<int>(), TimeSpan.FromMinutes(5.0)), Times.Once());
|
||||
@@ -153,7 +154,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
throw new ReleaseDownloadException(v.Release, "Error", new TooManyRequestsException(request, response));
|
||||
});
|
||||
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.DownloadReport(_parseResult));
|
||||
Assert.ThrowsAsync<ReleaseDownloadException>(async () => await Subject.DownloadReport(_parseResult));
|
||||
|
||||
Mocker.GetMock<IIndexerStatusService>()
|
||||
.Verify(v => v.RecordFailure(It.IsAny<int>(),
|
||||
@@ -167,7 +168,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
mock.Setup(s => s.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()))
|
||||
.Throws(new DownloadClientException("Some Error"));
|
||||
|
||||
Assert.Throws<DownloadClientException>(() => Subject.DownloadReport(_parseResult));
|
||||
Assert.ThrowsAsync<DownloadClientException>(async () => await Subject.DownloadReport(_parseResult));
|
||||
|
||||
Mocker.GetMock<IIndexerStatusService>()
|
||||
.Verify(v => v.RecordFailure(It.IsAny<int>(), It.IsAny<TimeSpan>()), Times.Never());
|
||||
@@ -183,7 +184,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
throw new ReleaseUnavailableException(v.Release, "Error", new WebException());
|
||||
});
|
||||
|
||||
Assert.Throws<ReleaseUnavailableException>(() => Subject.DownloadReport(_parseResult));
|
||||
Assert.ThrowsAsync<ReleaseUnavailableException>(async () => await Subject.DownloadReport(_parseResult));
|
||||
|
||||
Mocker.GetMock<IIndexerStatusService>()
|
||||
.Verify(v => v.RecordFailure(It.IsAny<int>(), It.IsAny<TimeSpan>()), Times.Never());
|
||||
@@ -192,14 +193,14 @@ namespace NzbDrone.Core.Test.Download
|
||||
[Test]
|
||||
public void should_not_attempt_download_if_client_isnt_configured()
|
||||
{
|
||||
Assert.Throws<DownloadClientUnavailableException>(() => Subject.DownloadReport(_parseResult));
|
||||
Assert.ThrowsAsync<DownloadClientUnavailableException>(async () => await Subject.DownloadReport(_parseResult));
|
||||
|
||||
Mocker.GetMock<IDownloadClient>().Verify(c => c.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()), Times.Never());
|
||||
VerifyEventNotPublished<MovieGrabbedEvent>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_attempt_download_even_if_client_is_disabled()
|
||||
public async Task should_attempt_download_even_if_client_is_disabled()
|
||||
{
|
||||
var mockUsenet = WithUsenetClient();
|
||||
|
||||
@@ -214,7 +215,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
}
|
||||
});
|
||||
|
||||
Subject.DownloadReport(_parseResult);
|
||||
await Subject.DownloadReport(_parseResult);
|
||||
|
||||
Mocker.GetMock<IDownloadClientStatusService>().Verify(c => c.GetBlockedProviders(), Times.Never());
|
||||
mockUsenet.Verify(c => c.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()), Times.Once());
|
||||
@@ -222,26 +223,26 @@ namespace NzbDrone.Core.Test.Download
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_send_download_to_correct_usenet_client()
|
||||
public async Task should_send_download_to_correct_usenet_client()
|
||||
{
|
||||
var mockTorrent = WithTorrentClient();
|
||||
var mockUsenet = WithUsenetClient();
|
||||
|
||||
Subject.DownloadReport(_parseResult);
|
||||
await Subject.DownloadReport(_parseResult);
|
||||
|
||||
mockTorrent.Verify(c => c.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()), Times.Never());
|
||||
mockUsenet.Verify(c => c.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_send_download_to_correct_torrent_client()
|
||||
public async Task should_send_download_to_correct_torrent_client()
|
||||
{
|
||||
var mockTorrent = WithTorrentClient();
|
||||
var mockUsenet = WithUsenetClient();
|
||||
|
||||
_parseResult.Release.DownloadProtocol = DownloadProtocol.Torrent;
|
||||
|
||||
Subject.DownloadReport(_parseResult);
|
||||
await Subject.DownloadReport(_parseResult);
|
||||
|
||||
mockTorrent.Verify(c => c.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()), Times.Once());
|
||||
mockUsenet.Verify(c => c.Download(It.IsAny<RemoteMovie>(), It.IsAny<IIndexer>()), Times.Never());
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
Subject.Clean();
|
||||
|
||||
// BeCloseTo handles Postgres rounding times
|
||||
AllStoredModels.ToList().ForEach(t => t.LastExecution.Should().BeCloseTo(expectedTime));
|
||||
AllStoredModels.ToList().ForEach(t => t.LastExecution.Should().BeCloseTo(expectedTime, TimeSpan.FromMilliseconds(20)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -53,13 +54,13 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
|
||||
_mockIndexer.Setup(v => v.Fetch(It.IsAny<MovieSearchCriteria>()))
|
||||
.Callback<MovieSearchCriteria>(s => result.Add(s))
|
||||
.Returns(new List<Parser.Model.ReleaseInfo>());
|
||||
.Returns(Task.FromResult<IList<Parser.Model.ReleaseInfo>>(new List<Parser.Model.ReleaseInfo>()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Tags_IndexerTags_MovieNoTags_IndexerNotIncluded()
|
||||
public async Task Tags_IndexerTags_MovieNoTags_IndexerNotIncluded()
|
||||
{
|
||||
_mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition
|
||||
{
|
||||
@@ -69,7 +70,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
|
||||
var allCriteria = WatchForSearchCriteria();
|
||||
|
||||
Subject.MovieSearch(_movie, true, false);
|
||||
await Subject.MovieSearch(_movie, true, false);
|
||||
|
||||
var criteria = allCriteria.OfType<MovieSearchCriteria>().ToList();
|
||||
|
||||
@@ -77,7 +78,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Tags_IndexerNoTags_MovieTags_IndexerIncluded()
|
||||
public async Task Tags_IndexerNoTags_MovieTags_IndexerIncluded()
|
||||
{
|
||||
_mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition
|
||||
{
|
||||
@@ -95,7 +96,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
|
||||
var allCriteria = WatchForSearchCriteria();
|
||||
|
||||
Subject.MovieSearch(_movie, true, false);
|
||||
await Subject.MovieSearch(_movie, true, false);
|
||||
|
||||
var criteria = allCriteria.OfType<MovieSearchCriteria>().ToList();
|
||||
|
||||
@@ -103,7 +104,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Tags_IndexerAndMovieTagsMatch_IndexerIncluded()
|
||||
public async Task Tags_IndexerAndMovieTagsMatch_IndexerIncluded()
|
||||
{
|
||||
_mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition
|
||||
{
|
||||
@@ -122,7 +123,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
|
||||
var allCriteria = WatchForSearchCriteria();
|
||||
|
||||
Subject.MovieSearch(_movie, true, false);
|
||||
await Subject.MovieSearch(_movie, true, false);
|
||||
|
||||
var criteria = allCriteria.OfType<MovieSearchCriteria>().ToList();
|
||||
|
||||
@@ -130,7 +131,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Tags_IndexerAndMovieTagsMismatch_IndexerNotIncluded()
|
||||
public async Task Tags_IndexerAndMovieTagsMismatch_IndexerNotIncluded()
|
||||
{
|
||||
_mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition
|
||||
{
|
||||
@@ -149,7 +150,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
|
||||
var allCriteria = WatchForSearchCriteria();
|
||||
|
||||
Subject.MovieSearch(_movie, true, false);
|
||||
await Subject.MovieSearch(_movie, true, false);
|
||||
|
||||
var criteria = allCriteria.OfType<MovieSearchCriteria>().ToList();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -26,15 +27,15 @@ namespace NzbDrone.Core.Test.IndexerTests.FileListTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_FileList()
|
||||
public async Task should_parse_recent_feed_from_FileList()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/FileList/RecentFeed.json");
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(4);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.IndexerTests.FileListTests
|
||||
|
||||
var page = results.GetAllTiers().First().First();
|
||||
|
||||
page.Url.Query.Should().Contain("&category=1,2&");
|
||||
page.Url.Query.Should().Contain("&category=1,2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -30,15 +31,15 @@ namespace NzbDrone.Core.Test.IndexerTests.HDBitsTests
|
||||
|
||||
[TestCase("Files/Indexers/HdBits/RecentFeedLongIDs.json")]
|
||||
[TestCase("Files/Indexers/HdBits/RecentFeedStringIDs.json")]
|
||||
public void should_parse_recent_feed_from_HDBits(string fileName)
|
||||
public async Task should_parse_recent_feed_from_HDBits(string fileName)
|
||||
{
|
||||
var responseJson = ReadAllText(fileName);
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.Post)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), responseJson));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Post)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), responseJson)));
|
||||
|
||||
var torrents = Subject.FetchRecent();
|
||||
var torrents = await Subject.FetchRecent();
|
||||
|
||||
torrents.Should().HaveCount(2);
|
||||
torrents.First().Should().BeOfType<HDBitsInfo>();
|
||||
@@ -59,15 +60,15 @@ namespace NzbDrone.Core.Test.IndexerTests.HDBitsTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_warn_on_wrong_passkey()
|
||||
public async Task should_warn_on_wrong_passkey()
|
||||
{
|
||||
var responseJson = new { status = 5, message = "Invalid authentication credentials" }.ToJson();
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(v => v.Execute(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), Encoding.UTF8.GetBytes(responseJson)));
|
||||
.Setup(v => v.ExecuteAsync(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), Encoding.UTF8.GetBytes(responseJson))));
|
||||
|
||||
var torrents = Subject.FetchRecent();
|
||||
var torrents = await Subject.FetchRecent();
|
||||
|
||||
torrents.Should().BeEmpty();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -84,15 +85,15 @@ namespace NzbDrone.Core.Test.IndexerTests.IPTorrentsTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_IPTorrents()
|
||||
public async Task should_parse_recent_feed_from_IPTorrents()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/IPTorrents/IPTorrents.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));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -37,15 +38,15 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_newznab_nzb_su()
|
||||
public async Task should_parse_recent_feed_from_newznab_nzb_su()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Newznab/newznab_nzb_su.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));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(100);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -58,15 +59,15 @@ namespace NzbDrone.Core.Test.IndexerTests.NyaaTests
|
||||
}*/
|
||||
|
||||
[Test]
|
||||
public void should_parse_2021_recent_feed_from_Nyaa()
|
||||
public async Task 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));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(3);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -27,7 +28,7 @@ namespace NzbDrone.Core.Test.IndexerTests.PTPTests
|
||||
}
|
||||
|
||||
[TestCase("Files/Indexers/PTP/imdbsearch.json")]
|
||||
public void should_parse_feed_from_PTP(string fileName)
|
||||
public async Task should_parse_feed_from_PTP(string fileName)
|
||||
{
|
||||
var authResponse = new PassThePopcornAuthResponse { Result = "Ok" };
|
||||
|
||||
@@ -36,14 +37,14 @@ namespace NzbDrone.Core.Test.IndexerTests.PTPTests
|
||||
var responseJson = ReadAllText(fileName);
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.Post)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), authStream.ToString()));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Post)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), authStream.ToString())));
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader { ContentType = HttpAccept.Json.Value }, responseJson));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader { ContentType = HttpAccept.Json.Value }, responseJson)));
|
||||
|
||||
var torrents = Subject.FetchRecent();
|
||||
var torrents = await Subject.FetchRecent();
|
||||
|
||||
torrents.Should().HaveCount(293);
|
||||
torrents.First().Should().BeOfType<PassThePopcornInfo>();
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
{
|
||||
var result = new List<ValidationFailure>();
|
||||
SetupNLog(); // Enable this to enable trace logging with nlog for debugging purposes
|
||||
Test(result);
|
||||
Test(result).GetAwaiter().GetResult();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -34,17 +35,21 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/" + rssXmlFile);
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.ExecuteAsync(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.IsAny<HttpRequest>()))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_ImmortalSeed()
|
||||
public async Task should_parse_recent_feed_from_ImmortalSeed()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/ImmortalSeed.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(50);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
@@ -66,11 +71,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_Ezrss()
|
||||
public async Task should_parse_recent_feed_from_Ezrss()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/Ezrss.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(3);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
@@ -92,13 +97,13 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_ShowRSS_info()
|
||||
public async Task should_parse_recent_feed_from_ShowRSS_info()
|
||||
{
|
||||
Subject.Definition.Settings.As<TorrentRssIndexerSettings>().AllowZeroSize = true;
|
||||
|
||||
GivenRecentFeedResponse("TorrentRss/ShowRSS.info.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
@@ -120,13 +125,13 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_Doki()
|
||||
public async Task should_parse_recent_feed_from_Doki()
|
||||
{
|
||||
Subject.Definition.Settings.As<TorrentRssIndexerSettings>().AllowZeroSize = true;
|
||||
|
||||
GivenRecentFeedResponse("TorrentRss/Doki.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
@@ -148,11 +153,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_ExtraTorrents()
|
||||
public async Task should_parse_recent_feed_from_ExtraTorrents()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/ExtraTorrents.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
@@ -174,11 +179,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_LimeTorrents()
|
||||
public async Task should_parse_recent_feed_from_LimeTorrents()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/LimeTorrents.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
@@ -200,11 +205,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_AnimeTosho_without_size()
|
||||
public async Task should_parse_recent_feed_from_AnimeTosho_without_size()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/AnimeTosho_NoSize.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(2);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
@@ -226,11 +231,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_multi_enclosure_from_AnimeTosho()
|
||||
public async Task should_parse_multi_enclosure_from_AnimeTosho()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/AnimeTosho_NoSize.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(2);
|
||||
releases.Last().Should().BeOfType<TorrentInfo>();
|
||||
@@ -243,11 +248,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_AlphaRatio()
|
||||
public async Task should_parse_recent_feed_from_AlphaRatio()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/AlphaRatio.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(2);
|
||||
releases.Last().Should().BeOfType<TorrentInfo>();
|
||||
@@ -260,12 +265,12 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_EveolutionWorld_without_size()
|
||||
public async Task should_parse_recent_feed_from_EveolutionWorld_without_size()
|
||||
{
|
||||
Subject.Definition.Settings.As<TorrentRssIndexerSettings>().AllowZeroSize = true;
|
||||
GivenRecentFeedResponse("TorrentRss/EvolutionWorld.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(2);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
@@ -287,11 +292,13 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_record_indexer_failure_if_unsupported_feed()
|
||||
public async Task should_record_indexer_failure_if_unsupported_feed()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/invalid/TorrentDay_NoPubDate.xml");
|
||||
|
||||
Subject.FetchRecent().Should().BeEmpty();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().BeEmpty();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusService>()
|
||||
.Verify(v => v.RecordFailure(It.IsAny<int>(), TimeSpan.Zero), Times.Once());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -44,15 +45,15 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_torznab_hdaccess_net()
|
||||
public async Task should_parse_recent_feed_from_torznab_hdaccess_net()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_hdaccess_net.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));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
|
||||
@@ -73,15 +74,15 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_torznab_tpb()
|
||||
public async Task should_parse_recent_feed_from_torznab_tpb()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_tpb.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));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
|
||||
@@ -103,15 +104,15 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_torznab_animetosho()
|
||||
public async Task should_parse_recent_feed_from_torznab_animetosho()
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_animetosho.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));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
var releases = await Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(2);
|
||||
|
||||
@@ -170,8 +171,8 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
||||
(Subject.Definition.Settings as TorznabSettings).BaseUrl = baseUrl;
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
var result = new NzbDroneValidationResult(Subject.Test());
|
||||
result.IsValid.Should().BeTrue();
|
||||
@@ -185,8 +186,8 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_tpb.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));
|
||||
.Setup(o => o.ExecuteAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
||||
.Returns<HttpRequest>(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed)));
|
||||
|
||||
(Subject.Definition.Settings as TorznabSettings).ApiPath = apiPath;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.English);
|
||||
result.Languages.Should().Contain(Language.English);
|
||||
}
|
||||
|
||||
[TestCase("The Danish Movie 2015")]
|
||||
@@ -25,7 +25,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Unknown);
|
||||
result.Languages.Should().Contain(Language.Unknown);
|
||||
}
|
||||
|
||||
[TestCase("Movie Title - 2022.en.sub")]
|
||||
@@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.French);
|
||||
result.Languages.Should().Contain(Language.French);
|
||||
}
|
||||
|
||||
[TestCase("Movie 1990 1080p Eng Fra [mkvonly]")]
|
||||
@@ -78,7 +78,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Spanish);
|
||||
result.Languages.Should().Contain(Language.Spanish);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.German.1080p.XviD-LOL")]
|
||||
@@ -87,7 +87,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.German);
|
||||
result.Languages.Should().Contain(Language.German);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Italian.1080p.XviD-LOL")]
|
||||
@@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Italian);
|
||||
result.Languages.Should().Contain(Language.Italian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Danish.1080p.XviD-LOL")]
|
||||
@@ -103,7 +103,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Danish);
|
||||
result.Languages.Should().Contain(Language.Danish);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Dutch.1080p.XviD-LOL")]
|
||||
@@ -111,7 +111,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Dutch);
|
||||
result.Languages.Should().Contain(Language.Dutch);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Japanese.1080p.XviD-LOL")]
|
||||
@@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Japanese);
|
||||
result.Languages.Should().Contain(Language.Japanese);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Icelandic.1080p.XviD-LOL")]
|
||||
@@ -127,7 +127,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Icelandic);
|
||||
result.Languages.Should().Contain(Language.Icelandic);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Chinese.1080p.XviD-LOL")]
|
||||
@@ -135,7 +135,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Chinese);
|
||||
result.Languages.Should().Contain(Language.Chinese);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Russian.1080p.XviD-LOL")]
|
||||
@@ -143,7 +143,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Russian);
|
||||
result.Languages.Should().Contain(Language.Russian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Romanian.1080p.XviD-LOL")]
|
||||
@@ -152,7 +152,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Romanian);
|
||||
result.Languages.Should().Contain(Language.Romanian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Hindi.1080p.XviD-LOL")]
|
||||
@@ -160,7 +160,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Hindi);
|
||||
result.Languages.Should().Contain(Language.Hindi);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Thai.1080p.XviD-LOL")]
|
||||
@@ -168,7 +168,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Thai);
|
||||
result.Languages.Should().Contain(Language.Thai);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Bulgarian.1080p.XviD-LOL")]
|
||||
@@ -178,7 +178,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Bulgarian);
|
||||
result.Languages.Should().Contain(Language.Bulgarian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Dublado.1080p.XviD-LOL")]
|
||||
@@ -188,7 +188,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.PortugueseBR);
|
||||
result.Languages.Should().Contain(Language.PortugueseBR);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Polish.1080p.XviD-LOL")]
|
||||
@@ -204,7 +204,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Polish);
|
||||
result.Languages.Should().Contain(Language.Polish);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.PL-SUB.1080p.XviD-LOL")]
|
||||
@@ -214,7 +214,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Unknown);
|
||||
result.Languages.Should().Contain(Language.Unknown);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Vietnamese.1080p.XviD-LOL")]
|
||||
@@ -222,7 +222,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Vietnamese);
|
||||
result.Languages.Should().Contain(Language.Vietnamese);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Swedish.1080p.XviD-LOL")]
|
||||
@@ -230,7 +230,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Swedish);
|
||||
result.Languages.Should().Contain(Language.Swedish);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Norwegian.1080p.XviD-LOL")]
|
||||
@@ -238,7 +238,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Norwegian);
|
||||
result.Languages.Should().Contain(Language.Norwegian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Finnish.1080p.XviD-LOL")]
|
||||
@@ -246,7 +246,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Finnish);
|
||||
result.Languages.Should().Contain(Language.Finnish);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Turkish.1080p.XviD-LOL")]
|
||||
@@ -254,7 +254,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Turkish);
|
||||
result.Languages.Should().Contain(Language.Turkish);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Portuguese.1080p.XviD-LOL")]
|
||||
@@ -262,7 +262,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Portuguese);
|
||||
result.Languages.Should().Contain(Language.Portuguese);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Flemish.1080p.XviD-LOL")]
|
||||
@@ -270,7 +270,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Flemish);
|
||||
result.Languages.Should().Contain(Language.Flemish);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Greek.1080p.XviD-LOL")]
|
||||
@@ -278,7 +278,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Greek);
|
||||
result.Languages.Should().Contain(Language.Greek);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Korean.1080p.XviD-LOL")]
|
||||
@@ -286,7 +286,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Korean);
|
||||
result.Languages.Should().Contain(Language.Korean);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Hungarian.1080p.XviD-LOL")]
|
||||
@@ -294,7 +294,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Hungarian);
|
||||
result.Languages.Should().Contain(Language.Hungarian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.Hebrew.1080p.XviD-LOL")]
|
||||
@@ -302,7 +302,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Hebrew);
|
||||
result.Languages.Should().Contain(Language.Hebrew);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.AC3.LT.EN-CNN")]
|
||||
@@ -310,7 +310,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Lithuanian);
|
||||
result.Languages.Should().Contain(Language.Lithuanian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.1994.CZ.1080p.XviD-LOL")]
|
||||
@@ -318,14 +318,14 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Czech);
|
||||
result.Languages.Should().Contain(Language.Czech);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.2019.ARABIC.WEBRip.x264-VXT")]
|
||||
public void should_parse_language_arabic(string postTitle)
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle);
|
||||
result.Languages.Should().BeEquivalentTo(Language.Arabic);
|
||||
result.Languages.Should().Contain(Language.Arabic);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title [1989, BDRip] MVO + DVO + UKR (MVO) + Sub")]
|
||||
@@ -336,7 +336,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Ukrainian);
|
||||
result.Languages.Should().Contain(Language.Ukrainian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title [1937, BDRip 1080p] Dub UKR/Eng + Sub rus")]
|
||||
@@ -352,14 +352,14 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
public void should_parse_language_persian(string postTitle)
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle);
|
||||
result.Languages.Should().BeEquivalentTo(Language.Persian);
|
||||
result.Languages.Should().Contain(Language.Persian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.2019.BENGALI.WEBRip.x264-VXT")]
|
||||
public void should_parse_language_bengali(string postTitle)
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle);
|
||||
result.Languages.Should().BeEquivalentTo(Language.Bengali);
|
||||
result.Languages.Should().Contain(Language.Bengali);
|
||||
}
|
||||
|
||||
[TestCase("Movie Title (2018) Telugu DVDScr X264 AAC 700 MB")]
|
||||
@@ -378,7 +378,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
public void should_parse_language_slovak(string postTitle)
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle);
|
||||
result.Languages.Should().BeEquivalentTo(Language.Slovak);
|
||||
result.Languages.Should().Contain(Language.Slovak);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.2022.LV.WEBRip.XviD-LOL")]
|
||||
@@ -388,7 +388,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
public void should_parse_language_latvian(string postTitle)
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle);
|
||||
result.Languages.Should().BeEquivalentTo(Language.Latvian);
|
||||
result.Languages.Should().Contain(Language.Latvian);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.2019.720p_Eng-Spa(Latino)_MovieClubMx")]
|
||||
@@ -408,7 +408,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
var result = Parser.Parser.ParseMovieTitle(postTitle, true);
|
||||
|
||||
result.Languages.Should().BeEquivalentTo(Language.Catalan);
|
||||
result.Languages.Should().Contain(Language.Catalan);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.en.sub")]
|
||||
|
||||
@@ -20,4 +20,9 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="IndexerTests\BroadcastheNetTests\" />
|
||||
<Folder Include="IndexerTests\FanzubTests\" />
|
||||
<Folder Include="IndexerTests\TorrentleechTests\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace NzbDrone.Core.Test.ThingiProviderTests
|
||||
|
||||
public class ProviderStatusServiceFixture : CoreTest<MockProviderStatusService>
|
||||
{
|
||||
private readonly TimeSpan _disabledTillPrecision = TimeSpan.FromMilliseconds(500);
|
||||
private DateTime _epoch;
|
||||
|
||||
[SetUp]
|
||||
@@ -90,7 +91,7 @@ namespace NzbDrone.Core.Test.ThingiProviderTests
|
||||
var status = Subject.GetBlockedProviders().FirstOrDefault();
|
||||
status.Should().NotBeNull();
|
||||
status.DisabledTill.Should().HaveValue();
|
||||
status.DisabledTill.Value.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(5), 500);
|
||||
status.DisabledTill.Value.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(1), _disabledTillPrecision);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -133,7 +134,7 @@ namespace NzbDrone.Core.Test.ThingiProviderTests
|
||||
var status = Subject.GetBlockedProviders().FirstOrDefault();
|
||||
status.Should().NotBeNull();
|
||||
status.DisabledTill.Should().HaveValue();
|
||||
status.DisabledTill.Value.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(15), 500);
|
||||
status.DisabledTill.Value.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(5), _disabledTillPrecision);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -160,7 +161,7 @@ namespace NzbDrone.Core.Test.ThingiProviderTests
|
||||
status.Should().NotBeNull();
|
||||
|
||||
origStatus.EscalationLevel.Should().Be(3);
|
||||
status.DisabledTill.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(5), 500);
|
||||
status.DisabledTill.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(5), _disabledTillPrecision);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public LanguageSpecificationValidator()
|
||||
{
|
||||
RuleFor(c => c.Value).NotEmpty();
|
||||
RuleFor(c => c.Value).Custom((value, context) =>
|
||||
{
|
||||
if (!Language.All.Any(o => o.Id == value))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
@@ -33,7 +34,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||
|
||||
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
||||
|
||||
public override string Download(RemoteMovie remoteMovie, IIndexer indexer)
|
||||
public override async Task<string> Download(RemoteMovie remoteMovie, IIndexer indexer)
|
||||
{
|
||||
var url = remoteMovie.Release.DownloadUrl;
|
||||
var title = remoteMovie.Release.Title;
|
||||
@@ -49,7 +50,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||
var nzbFile = Path.Combine(Settings.NzbFolder, title + ".nzb");
|
||||
|
||||
_logger.Debug("Downloading NZB from: {0} to: {1}", url, nzbFile);
|
||||
_httpClient.DownloadFile(url, nzbFile);
|
||||
await _httpClient.DownloadFileAsync(url, nzbFile);
|
||||
|
||||
_logger.Debug("NZB Download succeeded, saved to: {0}", nzbFile);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
@@ -62,7 +63,7 @@ namespace NzbDrone.Core.Download
|
||||
get;
|
||||
}
|
||||
|
||||
public abstract string Download(RemoteMovie remoteMovie, IIndexer indexer);
|
||||
public abstract Task<string> Download(RemoteMovie remoteMovie, IIndexer indexer);
|
||||
public abstract IEnumerable<DownloadClientItem> GetItems();
|
||||
|
||||
public virtual DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt)
|
||||
|
||||
@@ -74,10 +74,19 @@ namespace NzbDrone.Core.Download
|
||||
{
|
||||
var result = base.Test(definition);
|
||||
|
||||
if ((result == null || result.IsValid) && definition.Id != 0)
|
||||
if (definition.Id == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result == null || result.IsValid)
|
||||
{
|
||||
_downloadClientStatusService.RecordSuccess(definition.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_downloadClientStatusService.RecordFailure(definition.Id);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -16,7 +17,7 @@ namespace NzbDrone.Core.Download
|
||||
{
|
||||
public interface IDownloadService
|
||||
{
|
||||
void DownloadReport(RemoteMovie remoteMovie);
|
||||
Task DownloadReport(RemoteMovie remoteMovie);
|
||||
}
|
||||
|
||||
public class DownloadService : IDownloadService
|
||||
@@ -49,14 +50,22 @@ namespace NzbDrone.Core.Download
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void DownloadReport(RemoteMovie remoteMovie)
|
||||
public async Task DownloadReport(RemoteMovie remoteMovie)
|
||||
{
|
||||
var filterBlockedClients = remoteMovie.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable;
|
||||
|
||||
var tags = remoteMovie.Movie?.Tags;
|
||||
|
||||
var downloadClient = _downloadClientProvider.GetDownloadClient(remoteMovie.Release.DownloadProtocol, remoteMovie.Release.IndexerId, filterBlockedClients, tags);
|
||||
|
||||
await DownloadReport(remoteMovie, downloadClient);
|
||||
}
|
||||
|
||||
public async Task DownloadReport(RemoteMovie remoteMovie, IDownloadClient downloadClient)
|
||||
{
|
||||
Ensure.That(remoteMovie.Movie, () => remoteMovie.Movie).IsNotNull();
|
||||
|
||||
var downloadTitle = remoteMovie.Release.Title;
|
||||
var filterBlockedClients = remoteMovie.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable;
|
||||
var tags = remoteMovie.Movie?.Tags;
|
||||
var downloadClient = _downloadClientProvider.GetDownloadClient(remoteMovie.Release.DownloadProtocol, remoteMovie.Release.IndexerId, filterBlockedClients, tags);
|
||||
|
||||
if (downloadClient == null)
|
||||
{
|
||||
@@ -70,7 +79,7 @@ namespace NzbDrone.Core.Download
|
||||
if (remoteMovie.Release.DownloadUrl.IsNotNullOrWhiteSpace() && !remoteMovie.Release.DownloadUrl.StartsWith("magnet:"))
|
||||
{
|
||||
var url = new HttpUri(remoteMovie.Release.DownloadUrl);
|
||||
_rateLimitService.WaitAndPulse(url.Host, TimeSpan.FromSeconds(2));
|
||||
await _rateLimitService.WaitAndPulseAsync(url.Host, TimeSpan.FromSeconds(2));
|
||||
}
|
||||
|
||||
IIndexer indexer = null;
|
||||
@@ -83,7 +92,7 @@ namespace NzbDrone.Core.Download
|
||||
string downloadClientId;
|
||||
try
|
||||
{
|
||||
downloadClientId = downloadClient.Download(remoteMovie, indexer);
|
||||
downloadClientId = await downloadClient.Download(remoteMovie, indexer);
|
||||
_downloadClientStatusService.RecordSuccess(downloadClient.Definition.Id);
|
||||
_indexerStatusService.RecordSuccess(remoteMovie.Release.IndexerId);
|
||||
}
|
||||
@@ -99,8 +108,7 @@ namespace NzbDrone.Core.Download
|
||||
}
|
||||
catch (ReleaseDownloadException ex)
|
||||
{
|
||||
var http429 = ex.InnerException as TooManyRequestsException;
|
||||
if (http429 != null)
|
||||
if (ex.InnerException is TooManyRequestsException http429)
|
||||
{
|
||||
_indexerStatusService.RecordFailure(remoteMovie.Release.IndexerId, http429.RetryAfter);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
@@ -8,7 +9,7 @@ namespace NzbDrone.Core.Download
|
||||
public interface IDownloadClient : IProvider
|
||||
{
|
||||
DownloadProtocol Protocol { get; }
|
||||
string Download(RemoteMovie remoteMovie, IIndexer indexer);
|
||||
Task<string> Download(RemoteMovie remoteMovie, IIndexer indexer);
|
||||
IEnumerable<DownloadClientItem> GetItems();
|
||||
DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt);
|
||||
void RemoveItem(DownloadClientItem item, bool deleteData);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
@@ -12,7 +13,7 @@ namespace NzbDrone.Core.Download
|
||||
{
|
||||
public interface IProcessDownloadDecisions
|
||||
{
|
||||
ProcessedDecisions ProcessDecisions(List<DownloadDecision> decisions);
|
||||
Task<ProcessedDecisions> ProcessDecisions(List<DownloadDecision> decisions);
|
||||
}
|
||||
|
||||
public class ProcessDownloadDecisions : IProcessDownloadDecisions
|
||||
@@ -33,7 +34,7 @@ namespace NzbDrone.Core.Download
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public ProcessedDecisions ProcessDecisions(List<DownloadDecision> decisions)
|
||||
public async Task<ProcessedDecisions> ProcessDecisions(List<DownloadDecision> decisions)
|
||||
{
|
||||
var qualifiedReports = GetQualifiedReports(decisions);
|
||||
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisionsForMovies(qualifiedReports);
|
||||
@@ -73,7 +74,7 @@ namespace NzbDrone.Core.Download
|
||||
try
|
||||
{
|
||||
_logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteMovie.Release.Indexer, remoteMovie.Release.IndexerPriority);
|
||||
_downloadService.DownloadReport(remoteMovie);
|
||||
await _downloadService.DownloadReport(remoteMovie);
|
||||
grabbed.Add(report);
|
||||
}
|
||||
catch (ReleaseUnavailableException)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using MonoTorrent;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
@@ -42,7 +43,7 @@ namespace NzbDrone.Core.Download
|
||||
protected abstract string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink);
|
||||
protected abstract string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent);
|
||||
|
||||
public override string Download(RemoteMovie remoteMovie, IIndexer indexer)
|
||||
public override async Task<string> Download(RemoteMovie remoteMovie, IIndexer indexer)
|
||||
{
|
||||
var torrentInfo = remoteMovie.Release as TorrentInfo;
|
||||
|
||||
@@ -69,7 +70,7 @@ namespace NzbDrone.Core.Download
|
||||
{
|
||||
try
|
||||
{
|
||||
return DownloadFromWebUrl(remoteMovie, indexer, torrentUrl);
|
||||
return await DownloadFromWebUrl(remoteMovie, indexer, torrentUrl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -115,14 +116,14 @@ namespace NzbDrone.Core.Download
|
||||
|
||||
if (torrentUrl.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return DownloadFromWebUrl(remoteMovie, indexer, torrentUrl);
|
||||
return await DownloadFromWebUrl(remoteMovie, indexer, torrentUrl);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string DownloadFromWebUrl(RemoteMovie remoteMovie, IIndexer indexer, string torrentUrl)
|
||||
private async Task<string> DownloadFromWebUrl(RemoteMovie remoteMovie, IIndexer indexer, string torrentUrl)
|
||||
{
|
||||
byte[] torrentFile = null;
|
||||
|
||||
@@ -133,7 +134,7 @@ namespace NzbDrone.Core.Download
|
||||
request.Headers.Accept = "application/x-bittorrent";
|
||||
request.AllowAutoRedirect = false;
|
||||
|
||||
var response = _httpClient.Get(request);
|
||||
var response = await _httpClient.GetAsync(request);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.MovedPermanently ||
|
||||
response.StatusCode == HttpStatusCode.Found ||
|
||||
@@ -152,7 +153,7 @@ namespace NzbDrone.Core.Download
|
||||
|
||||
request.Url += new HttpUri(locationHeader);
|
||||
|
||||
return DownloadFromWebUrl(remoteMovie, indexer, request.Url.ToString());
|
||||
return await DownloadFromWebUrl(remoteMovie, indexer, request.Url.ToString());
|
||||
}
|
||||
|
||||
throw new WebException("Remote website tried to redirect without providing a location.");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
@@ -35,7 +36,7 @@ namespace NzbDrone.Core.Download
|
||||
|
||||
protected abstract string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents);
|
||||
|
||||
public override string Download(RemoteMovie remoteMovie, IIndexer indexer)
|
||||
public override async Task<string> Download(RemoteMovie remoteMovie, IIndexer indexer)
|
||||
{
|
||||
var url = remoteMovie.Release.DownloadUrl;
|
||||
var filename = FileNameBuilder.CleanFileName(remoteMovie.Release.Title) + ".nzb";
|
||||
@@ -46,7 +47,10 @@ namespace NzbDrone.Core.Download
|
||||
{
|
||||
var request = indexer?.GetDownloadRequest(url) ?? new HttpRequest(url);
|
||||
request.RateLimitKey = remoteMovie?.Release?.IndexerId.ToString();
|
||||
nzbData = _httpClient.Get(request).ResponseData;
|
||||
|
||||
var response = await _httpClient.GetAsync(request);
|
||||
|
||||
nzbData = response.ResponseData;
|
||||
|
||||
_logger.Debug("Downloaded nzb for movie '{0}' finished ({1} bytes from {2})", remoteMovie.Release.Title, nzbData.Length, url);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,11 @@ namespace NzbDrone.Core.Extras.Files
|
||||
public DateTime Added { get; set; }
|
||||
public DateTime LastUpdated { get; set; }
|
||||
public string Extension { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{Id}] {RelativePath}";
|
||||
}
|
||||
}
|
||||
|
||||
public enum ExtraFileType
|
||||
|
||||
@@ -93,6 +93,8 @@ namespace NzbDrone.Core.Extras.Files
|
||||
|
||||
protected TExtraFile MoveFile(Movie movie, MovieFile movieFile, TExtraFile extraFile, string fileNameSuffix = null)
|
||||
{
|
||||
_logger.Trace("Renaming extra file: {0}", extraFile);
|
||||
|
||||
var newFolder = Path.GetDirectoryName(Path.Combine(movie.Path, movieFile.RelativePath));
|
||||
var filenameBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(movieFile.RelativePath));
|
||||
|
||||
@@ -110,9 +112,13 @@ namespace NzbDrone.Core.Extras.Files
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Trace("Renaming extra file: {0} to {1}", extraFile, newFileName);
|
||||
|
||||
_diskProvider.MoveFile(existingFileName, newFileName);
|
||||
extraFile.RelativePath = movie.Path.GetRelativePath(newFileName);
|
||||
|
||||
_logger.Trace("Renamed extra file from: {0}", extraFile);
|
||||
|
||||
return extraFile;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -18,5 +18,10 @@ namespace NzbDrone.Core.Extras.Subtitles
|
||||
public List<string> LanguageTags { get; set; }
|
||||
|
||||
private string LanguageTagsAsString => string.Join(".", LanguageTags);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{Id}] {RelativePath} ({Language}{(LanguageTags.Count > 0 ? "." : "")}{LanguageTagsAsString}{Extension})";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ namespace NzbDrone.Core.Extras.Subtitles
|
||||
foreach (var subtitleFile in group)
|
||||
{
|
||||
var suffix = GetSuffix(subtitleFile.Language, copy, subtitleFile.LanguageTags, groupCount > 1);
|
||||
|
||||
movedFiles.AddIfNotNull(MoveFile(movie, movieFile, subtitleFile, suffix));
|
||||
|
||||
copy++;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
@@ -77,5 +78,26 @@ namespace NzbDrone.Core.ImportLists
|
||||
yield return importList;
|
||||
}
|
||||
}
|
||||
|
||||
public override ValidationResult Test(ImportListDefinition definition)
|
||||
{
|
||||
var result = base.Test(definition);
|
||||
|
||||
if (definition.Id == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result == null || result.IsValid)
|
||||
{
|
||||
_importListStatusService.RecordSuccess(definition.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_importListStatusService.RecordFailure(definition.Id);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,9 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
continue;
|
||||
}
|
||||
|
||||
var decisions = _releaseSearchService.MovieSearch(movieId, userInvokedSearch, false);
|
||||
downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count;
|
||||
var decisions = _releaseSearchService.MovieSearch(movieId, userInvokedSearch, false).GetAwaiter().GetResult();
|
||||
var processDecisions = _processDownloadDecisions.ProcessDecisions(decisions).GetAwaiter().GetResult();
|
||||
downloadedCount += processDecisions.Grabbed.Count;
|
||||
}
|
||||
|
||||
_logger.ProgressInfo("Movie search completed. {0} reports downloaded.", downloadedCount);
|
||||
@@ -107,7 +108,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
|
||||
try
|
||||
{
|
||||
decisions = _releaseSearchService.MovieSearch(movieId.Key, userInvokedSearch, false);
|
||||
decisions = _releaseSearchService.MovieSearch(movieId.Key, userInvokedSearch, false).GetAwaiter().GetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -116,9 +117,8 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
continue;
|
||||
}
|
||||
|
||||
var processed = _processDownloadDecisions.ProcessDecisions(decisions);
|
||||
|
||||
downloadedCount += processed.Grabbed.Count;
|
||||
var processDecisions = _processDownloadDecisions.ProcessDecisions(decisions).GetAwaiter().GetResult();
|
||||
downloadedCount += processDecisions.Grabbed.Count;
|
||||
}
|
||||
|
||||
_logger.ProgressInfo("Completed missing search for {0} movies. {1} reports downloaded.", movies.Count, downloadedCount);
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Common.TPL;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
@@ -18,8 +17,8 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
{
|
||||
public interface ISearchForReleases
|
||||
{
|
||||
List<DownloadDecision> MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch);
|
||||
List<DownloadDecision> MovieSearch(Movie movie, bool userInvokedSearch, bool interactiveSearch);
|
||||
Task<List<DownloadDecision>> MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch);
|
||||
Task<List<DownloadDecision>> MovieSearch(Movie movie, bool userInvokedSearch, bool interactiveSearch);
|
||||
}
|
||||
|
||||
public class ReleaseSearchService : ISearchForReleases
|
||||
@@ -46,21 +45,21 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public List<DownloadDecision> MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch)
|
||||
public async Task<List<DownloadDecision>> MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch)
|
||||
{
|
||||
var movie = _movieService.GetMovie(movieId);
|
||||
movie.MovieMetadata.Value.Translations = _movieTranslationService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId);
|
||||
|
||||
return MovieSearch(movie, userInvokedSearch, interactiveSearch);
|
||||
return await MovieSearch(movie, userInvokedSearch, interactiveSearch);
|
||||
}
|
||||
|
||||
public List<DownloadDecision> MovieSearch(Movie movie, bool userInvokedSearch, bool interactiveSearch)
|
||||
public async Task<List<DownloadDecision>> MovieSearch(Movie movie, bool userInvokedSearch, bool interactiveSearch)
|
||||
{
|
||||
var downloadDecisions = new List<DownloadDecision>();
|
||||
|
||||
var searchSpec = Get<MovieSearchCriteria>(movie, userInvokedSearch, interactiveSearch);
|
||||
|
||||
var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||
var decisions = await Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||
downloadDecisions.AddRange(decisions);
|
||||
|
||||
return DeDupeDecisions(downloadDecisions);
|
||||
@@ -96,7 +95,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
return spec;
|
||||
}
|
||||
|
||||
private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>> searchAction, SearchCriteriaBase criteriaBase)
|
||||
private async Task<List<DownloadDecision>> Dispatch(Func<IIndexer, Task<IList<ReleaseInfo>>> searchAction, SearchCriteriaBase criteriaBase)
|
||||
{
|
||||
var indexers = criteriaBase.InteractiveSearch ?
|
||||
_indexerFactory.InteractiveSearchEnabled() :
|
||||
@@ -105,42 +104,33 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
// Filter indexers to untagged indexers and indexers with intersecting tags
|
||||
indexers = indexers.Where(i => i.Definition.Tags.Empty() || i.Definition.Tags.Intersect(criteriaBase.Movie.Tags).Any()).ToList();
|
||||
|
||||
var reports = new List<ReleaseInfo>();
|
||||
|
||||
_logger.ProgressInfo("Searching indexers for {0}. {1} active indexers", criteriaBase, indexers.Count);
|
||||
|
||||
var taskList = new List<Task>();
|
||||
var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
|
||||
var tasks = indexers.Select(indexer => DispatchIndexer(searchAction, indexer, criteriaBase));
|
||||
|
||||
foreach (var indexer in indexers)
|
||||
{
|
||||
var indexerLocal = indexer;
|
||||
var batch = await Task.WhenAll(tasks);
|
||||
|
||||
taskList.Add(taskFactory.StartNew(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var indexerReports = searchAction(indexerLocal);
|
||||
|
||||
lock (reports)
|
||||
{
|
||||
reports.AddRange(indexerReports);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e, "Error while searching for {0}", criteriaBase);
|
||||
}
|
||||
}).LogExceptions());
|
||||
}
|
||||
|
||||
Task.WaitAll(taskList.ToArray());
|
||||
var reports = batch.SelectMany(x => x).ToList();
|
||||
|
||||
_logger.Debug("Total of {0} reports were found for {1} from {2} indexers", reports.Count, criteriaBase, indexers.Count);
|
||||
|
||||
return _makeDownloadDecision.GetSearchDecision(reports, criteriaBase).ToList();
|
||||
}
|
||||
|
||||
private async Task<IList<ReleaseInfo>> DispatchIndexer(Func<IIndexer, Task<IList<ReleaseInfo>>> searchAction, IIndexer indexer, SearchCriteriaBase criteriaBase)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await searchAction(indexer);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex, "Error while searching for {0}", criteriaBase);
|
||||
}
|
||||
|
||||
return Array.Empty<ReleaseInfo>();
|
||||
}
|
||||
|
||||
private List<DownloadDecision> DeDupeDecisions(List<DownloadDecision> decisions)
|
||||
{
|
||||
// De-dupe reports by guid so duplicate results aren't returned. Pick the one with the least rejections and higher indexer priority.
|
||||
|
||||
@@ -3,14 +3,13 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.TPL;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
public interface IFetchAndParseRss
|
||||
{
|
||||
List<ReleaseInfo> Fetch();
|
||||
Task<List<ReleaseInfo>> Fetch();
|
||||
}
|
||||
|
||||
public class FetchAndParseRssService : IFetchAndParseRss
|
||||
@@ -24,54 +23,42 @@ namespace NzbDrone.Core.Indexers
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public List<ReleaseInfo> Fetch()
|
||||
public async Task<List<ReleaseInfo>> Fetch()
|
||||
{
|
||||
var result = new List<ReleaseInfo>();
|
||||
|
||||
var indexers = _indexerFactory.RssEnabled();
|
||||
|
||||
if (!indexers.Any())
|
||||
{
|
||||
_logger.Warn("No available indexers. check your configuration.");
|
||||
return result;
|
||||
|
||||
return new List<ReleaseInfo>();
|
||||
}
|
||||
|
||||
_logger.Debug("Available indexers {0}", indexers.Count);
|
||||
|
||||
var taskList = new List<Task>();
|
||||
var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
|
||||
var tasks = indexers.Select(FetchIndexer);
|
||||
|
||||
foreach (var indexer in indexers)
|
||||
{
|
||||
var indexerLocal = indexer;
|
||||
var batch = await Task.WhenAll(tasks);
|
||||
|
||||
var task = taskFactory.StartNew(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var indexerReports = indexerLocal.FetchRecent();
|
||||
|
||||
lock (result)
|
||||
{
|
||||
_logger.Debug("Found {0} from {1}", indexerReports.Count, indexer.Name);
|
||||
|
||||
result.AddRange(indexerReports);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e, "Error during RSS Sync");
|
||||
}
|
||||
}).LogExceptions();
|
||||
|
||||
taskList.Add(task);
|
||||
}
|
||||
|
||||
Task.WaitAll(taskList.ToArray());
|
||||
var result = batch.SelectMany(x => x).ToList();
|
||||
|
||||
_logger.Debug("Found {0} reports", result.Count);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<IList<ReleaseInfo>> FetchIndexer(IIndexer indexer)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await indexer.FetchRecent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex, "Error during RSS Sync");
|
||||
}
|
||||
|
||||
return Array.Empty<ReleaseInfo>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,12 @@ namespace NzbDrone.Core.Indexers.FileList
|
||||
{
|
||||
var categoriesQuery = string.Join(",", Settings.Categories.Distinct());
|
||||
|
||||
var baseUrl = string.Format("{0}/api.php?action={1}&category={2}&username={3}&passkey={4}{5}", Settings.BaseUrl.TrimEnd('/'), searchType, categoriesQuery, Settings.Username.Trim(), Settings.Passkey.Trim(), parameters);
|
||||
var baseUrl = string.Format("{0}/api.php?action={1}&category={2}{3}", Settings.BaseUrl.TrimEnd('/'), searchType, categoriesQuery, parameters);
|
||||
|
||||
yield return new IndexerRequest(baseUrl, HttpAccept.Json);
|
||||
var request = new IndexerRequest(baseUrl, HttpAccept.Json);
|
||||
request.HttpRequest.Credentials = new BasicNetworkCredential(Settings.Username.Trim(), Settings.Passkey.Trim());
|
||||
|
||||
yield return request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,21 +40,21 @@ namespace NzbDrone.Core.Indexers
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public override IList<ReleaseInfo> FetchRecent()
|
||||
public override Task<IList<ReleaseInfo>> FetchRecent()
|
||||
{
|
||||
if (!SupportsRss)
|
||||
{
|
||||
return Array.Empty<ReleaseInfo>();
|
||||
return Task.FromResult<IList<ReleaseInfo>>(Array.Empty<ReleaseInfo>());
|
||||
}
|
||||
|
||||
return FetchReleases(g => g.GetRecentRequests(), true);
|
||||
}
|
||||
|
||||
public override IList<ReleaseInfo> Fetch(MovieSearchCriteria searchCriteria)
|
||||
public override Task<IList<ReleaseInfo>> Fetch(MovieSearchCriteria searchCriteria)
|
||||
{
|
||||
if (!SupportsSearch)
|
||||
{
|
||||
return Array.Empty<ReleaseInfo>();
|
||||
return Task.FromResult<IList<ReleaseInfo>>(Array.Empty<ReleaseInfo>());
|
||||
}
|
||||
|
||||
return FetchReleases(g => g.GetSearchRequests(searchCriteria));
|
||||
@@ -92,7 +92,7 @@ namespace NzbDrone.Core.Indexers
|
||||
return new HttpRequest(link);
|
||||
}
|
||||
|
||||
protected virtual IList<ReleaseInfo> FetchReleases(Func<IIndexerRequestGenerator, IndexerPageableRequestChain> pageableRequestChainSelector, bool isRecent = false)
|
||||
protected virtual async Task<IList<ReleaseInfo>> FetchReleases(Func<IIndexerRequestGenerator, IndexerPageableRequestChain> pageableRequestChainSelector, bool isRecent = false)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var url = string.Empty;
|
||||
@@ -128,7 +128,7 @@ namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
url = request.Url.FullUri;
|
||||
|
||||
var page = FetchPage(request, parser);
|
||||
var page = await FetchPage(request, parser);
|
||||
|
||||
pagedReleases.AddRange(page);
|
||||
|
||||
@@ -292,9 +292,9 @@ namespace NzbDrone.Core.Indexers
|
||||
return PageSize != 0 && page.Count >= PageSize;
|
||||
}
|
||||
|
||||
protected virtual IList<ReleaseInfo> FetchPage(IndexerRequest request, IParseIndexerResponse parser)
|
||||
protected virtual async Task<IList<ReleaseInfo>> FetchPage(IndexerRequest request, IParseIndexerResponse parser)
|
||||
{
|
||||
var response = FetchIndexerResponse(request);
|
||||
var response = await FetchIndexerResponse(request);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -308,7 +308,7 @@ namespace NzbDrone.Core.Indexers
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IndexerResponse FetchIndexerResponse(IndexerRequest request)
|
||||
protected virtual async Task<IndexerResponse> FetchIndexerResponse(IndexerRequest request)
|
||||
{
|
||||
_logger.Debug("Downloading Feed " + request.HttpRequest.ToString(false));
|
||||
|
||||
@@ -321,15 +321,17 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
request.HttpRequest.AllowAutoRedirect = true;
|
||||
|
||||
return new IndexerResponse(request, _httpClient.Execute(request.HttpRequest));
|
||||
var response = await _httpClient.ExecuteAsync(request.HttpRequest);
|
||||
|
||||
return new IndexerResponse(request, response);
|
||||
}
|
||||
|
||||
protected override void Test(List<ValidationFailure> failures)
|
||||
protected override async Task Test(List<ValidationFailure> failures)
|
||||
{
|
||||
failures.AddIfNotNull(TestConnection());
|
||||
failures.AddIfNotNull(await TestConnection());
|
||||
}
|
||||
|
||||
protected virtual ValidationFailure TestConnection()
|
||||
protected virtual async Task<ValidationFailure> TestConnection()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -346,7 +348,7 @@ namespace NzbDrone.Core.Indexers
|
||||
return new ValidationFailure(string.Empty, "No rss feed query available. This may be an issue with the indexer or your indexer category settings.");
|
||||
}
|
||||
|
||||
var releases = FetchPage(firstRequest, parser);
|
||||
var releases = await FetchPage(firstRequest, parser);
|
||||
|
||||
if (releases.Empty())
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
@@ -12,8 +13,8 @@ namespace NzbDrone.Core.Indexers
|
||||
bool SupportsSearch { get; }
|
||||
DownloadProtocol Protocol { get; }
|
||||
|
||||
IList<ReleaseInfo> FetchRecent();
|
||||
IList<ReleaseInfo> Fetch(MovieSearchCriteria searchCriteria);
|
||||
Task<IList<ReleaseInfo>> FetchRecent();
|
||||
Task<IList<ReleaseInfo>> Fetch(MovieSearchCriteria searchCriteria);
|
||||
HttpRequest GetDownloadRequest(string link);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -71,8 +72,8 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
protected TSettings Settings => (TSettings)Definition.Settings;
|
||||
|
||||
public abstract IList<ReleaseInfo> FetchRecent();
|
||||
public abstract IList<ReleaseInfo> Fetch(MovieSearchCriteria searchCriteria);
|
||||
public abstract Task<IList<ReleaseInfo>> FetchRecent();
|
||||
public abstract Task<IList<ReleaseInfo>> Fetch(MovieSearchCriteria searchCriteria);
|
||||
public abstract HttpRequest GetDownloadRequest(string link);
|
||||
|
||||
protected virtual IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> releases)
|
||||
@@ -103,7 +104,7 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
try
|
||||
{
|
||||
Test(failures);
|
||||
Test(failures).GetAwaiter().GetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -114,7 +115,7 @@ namespace NzbDrone.Core.Indexers
|
||||
return new ValidationResult(failures);
|
||||
}
|
||||
|
||||
protected abstract void Test(List<ValidationFailure> failures);
|
||||
protected abstract Task Test(List<ValidationFailure> failures);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -93,9 +94,10 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||
return settings;
|
||||
}
|
||||
|
||||
protected override void Test(List<ValidationFailure> failures)
|
||||
protected override async Task Test(List<ValidationFailure> failures)
|
||||
{
|
||||
base.Test(failures);
|
||||
await base.Test(failures);
|
||||
|
||||
if (failures.HasErrors())
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
@@ -39,16 +40,16 @@ namespace NzbDrone.Core.Indexers
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private ProcessedDecisions Sync()
|
||||
private async Task<ProcessedDecisions> Sync()
|
||||
{
|
||||
_logger.ProgressInfo("Starting RSS Sync");
|
||||
|
||||
var rssReleases = _rssFetcherAndParser.Fetch();
|
||||
var rssReleases = await _rssFetcherAndParser.Fetch();
|
||||
var pendingReleases = _pendingReleaseService.GetPending();
|
||||
|
||||
var reports = rssReleases.Concat(pendingReleases).ToList();
|
||||
var decisions = _downloadDecisionMaker.GetRssDecision(reports);
|
||||
var processed = _processDownloadDecisions.ProcessDecisions(decisions);
|
||||
var processed = await _processDownloadDecisions.ProcessDecisions(decisions);
|
||||
|
||||
var message = string.Format("RSS Sync Completed. Reports found: {0}, Reports grabbed: {1}", reports.Count, processed.Grabbed.Count);
|
||||
|
||||
@@ -64,7 +65,7 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
public void Execute(RssSyncCommand message)
|
||||
{
|
||||
var processed = Sync();
|
||||
var processed = Sync().GetAwaiter().GetResult();
|
||||
var grabbedOrPending = processed.Grabbed.Concat(processed.Pending).ToList();
|
||||
|
||||
_eventAggregator.PublishEvent(new RssSyncCompleteEvent(processed));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -83,9 +84,10 @@ namespace NzbDrone.Core.Indexers.Torznab
|
||||
return settings;
|
||||
}
|
||||
|
||||
protected override void Test(List<ValidationFailure> failures)
|
||||
protected override async Task Test(List<ValidationFailure> failures)
|
||||
{
|
||||
base.Test(failures);
|
||||
await base.Test(failures);
|
||||
|
||||
if (failures.HasErrors())
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -1021,6 +1021,8 @@
|
||||
"ShowCutoffUnmetIconHelpText": "Show icon for files when the cutoff hasn't been met",
|
||||
"ShowDateAdded": "Show Date Added",
|
||||
"ShowGenres": "Show Genres",
|
||||
"ShowImdbRating": "Show IMDb Rating",
|
||||
"ShowImdbRatingHelpText": "Show IMDb rating under poster",
|
||||
"ShowMonitored": "Show Monitored",
|
||||
"ShowMonitoredHelpText": "Show monitored status under poster",
|
||||
"ShowMovieInformation": "Show Movie Information",
|
||||
@@ -1033,12 +1035,16 @@
|
||||
"ShowRatings": "Show Ratings",
|
||||
"ShowReleaseDate": "Show Release Date",
|
||||
"ShowReleaseDateHelpText": "Show release date under poster",
|
||||
"ShowRottenTomatoesRating": "Show Tomato Rating",
|
||||
"ShowRottenTomatoesRatingHelpText": "Show Tomato rating under poster",
|
||||
"ShowSearch": "Show Search",
|
||||
"ShowSearchHelpText": "Show search button on hover",
|
||||
"ShowSizeOnDisk": "Show Size on Disk",
|
||||
"ShowStudio": "Show Studio",
|
||||
"ShowTitle": "Show Title",
|
||||
"ShowTitleHelpText": "Show movie title under poster",
|
||||
"ShowTmdbRating": "Show TMDb Rating",
|
||||
"ShowTmdbRatingHelpText": "Show TMDb rating under poster",
|
||||
"ShowUnknownMovieItems": "Show Unknown Movie Items",
|
||||
"ShowYear": "Show Year",
|
||||
"ShownClickToHide": "Shown, click to hide",
|
||||
|
||||
@@ -48,11 +48,11 @@
|
||||
"Calendar": "Calendrier",
|
||||
"BackupNow": "Sauvegarder maintenant",
|
||||
"Backup": "Sauvegarde",
|
||||
"AppDataLocationHealthCheckMessage": "La mise à jour ne sera pas possible pour empêcher la suppression de AppData lors de la mise à jour",
|
||||
"Analytics": "Analytique",
|
||||
"AppDataLocationHealthCheckMessage": "La mise à jour ne sera pas possible afin empêcher la suppression de AppData lors de la mise à jour",
|
||||
"Analytics": "Statistiques",
|
||||
"All": "Tout",
|
||||
"AddNewTmdbIdMessage": "Vous pouvez également effectuer une recherche à l'aide de l'identifiant TMDb d'un film. exemple. tmdb:71663",
|
||||
"AddNewMessage": "Il est facile d'ajouter un nouveau film, commencez simplement à taper le nom du film que vous souhaitez ajouter",
|
||||
"AddNewTmdbIdMessage": "Vous pouvez aussi effectuer une recherche de film à l'aide de son identifiant TMDb. exemple : \"tmdb:71663\"",
|
||||
"AddNewMessage": "C'est facile d'ajouter un nouveau film, vous avez juste a taper le nom du film que vous voulez ajouter",
|
||||
"AddMovies": "Ajouter des films",
|
||||
"AddExclusion": "Ajouter une exclusion",
|
||||
"AddNew": "Ajouter un nouveau",
|
||||
@@ -308,26 +308,26 @@
|
||||
"Conditions": "Conditions",
|
||||
"ColonReplacementFormatHelpText": "Changer la manière dont Radarr remplace les 'deux-points'",
|
||||
"ColonReplacement": "Remplacement pour le 'deux-points'",
|
||||
"CloneProfile": "Cloner le profil",
|
||||
"CloneIndexer": "Cloner l'indexeur",
|
||||
"CloneProfile": "Dupliqué le profil",
|
||||
"CloneIndexer": "Dupliqué l'indexeur",
|
||||
"ClientPriority": "Priorité du client",
|
||||
"ClickToChangeQuality": "Cliquer pour changer la qualité",
|
||||
"ClickToChangeLanguage": "Cliquer pour changer la langue",
|
||||
"CheckForFinishedDownloadsInterval": "Intervalle de vérification des téléchargements terminés",
|
||||
"ChangeHasNotBeenSavedYet": "Les changements n'ont pas encore été sauvegardés",
|
||||
"ChangeFileDate": "Changer la date du fichier",
|
||||
"CertificationCountryHelpText": "Choisir un pays pour les classifications de films",
|
||||
"CertificationCountryHelpText": "Choisir un pays pour la classification des films",
|
||||
"CertificateValidationHelpText": "Modifier le degré de rigueur de la validation de la certification HTTPS. Ne changez rien si vous ne comprenez pas les risques.",
|
||||
"CertificateValidation": "Validation du certificat",
|
||||
"BypassProxyForLocalAddresses": "Contourner le proxy pour les adresses locales",
|
||||
"Branch": "Branche",
|
||||
"BindAddressHelpText": "Adresse IPv4 valide, localhost ou '*' pour toutes les interfaces",
|
||||
"BindAddressHelpText": "Adresse IP valide, localhost 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",
|
||||
"BackupIntervalHelpText": "Intervalle entre les sauvegardes automatiques",
|
||||
"AvailabilityDelay": "Délai de disponibilité",
|
||||
"AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Les films qui sont effacés du disque dur sont automatiquement non-surveillés dans Radarr",
|
||||
"AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Les films qui sont effacés du disque dur ne seront plus surveillés dans Radarr",
|
||||
"AutoRedownloadFailedHelpText": "Chercher et essayer de télécharger une version différente automatiquement",
|
||||
"Automatic": "Automatique",
|
||||
"AuthenticationMethodHelpText": "Exiger un identifiant et un mot de passe pour accéder à Radarr",
|
||||
@@ -338,11 +338,11 @@
|
||||
"ApiKey": "Clé API",
|
||||
"AnalyticsEnabledHelpText": "Envoyer des informations anonymes sur l'utilisation et les erreurs vers les serveurs de Radarr. Cela inclut des informations sur votre navigateur, quelle page Radarr WebUI vous utilisez, les rapports d'erreur ainsi que le système d'exploitation et sa version. Nous utiliserons ces informations pour prioriser les nouvelles fonctionnalités et les corrections de bugs.",
|
||||
"AnalyseVideoFiles": "Analyser les fichiers vidéo",
|
||||
"AlreadyInYourLibrary": "Déjà présent dans votre collection",
|
||||
"AlreadyInYourLibrary": "Déjà disponible dans votre librairie",
|
||||
"AllowHardcodedSubsHelpText": "Les sous-titres incrustés détectés seront automatiquement téléchargés",
|
||||
"AllowHardcodedSubs": "Autoriser les sous-titres incrustés",
|
||||
"AllowHardcodedSubs": "Autoriser les sous-titres incrustés (Hardcoded)",
|
||||
"AgeWhenGrabbed": "Age (au moment du téléchargement)",
|
||||
"AddListExclusion": "Ajouter une exclusion de liste",
|
||||
"AddListExclusion": "Ajouter une liste d'exclusion",
|
||||
"IgnoreDeletedMovies": "Annuler la surveillance des films supprimés",
|
||||
"IgnoredAddresses": "Adresses ignorées",
|
||||
"IconForCutoffUnmet": "Icône pour limite non atteinte",
|
||||
@@ -413,7 +413,7 @@
|
||||
"CertificationCountry": "Pays de classification",
|
||||
"BackupFolderHelpText": "Les chemins relatifs pointeront sous le repertoire AppData de Radarr",
|
||||
"AvailabilityDelayHelpText": "Temps à laisser s’écouler (avant ou après la date de disponibilité) avant de chercher le film",
|
||||
"AddImportExclusionHelpText": "Empêcher le film d’être ajouté automatiquement à Radarr par des listes",
|
||||
"AddImportExclusionHelpText": "Empêcher Radarr d'ajouter le films automatiquement via une liste.",
|
||||
"ImportExtraFilesHelpText": "Importer les fichiers extra correspondants (sous-titres, .nfo etc.) après avoir importé un fichier film",
|
||||
"ImportExtraFiles": "Importer les fichiers extra",
|
||||
"ImportedTo": "Importé vers",
|
||||
@@ -423,11 +423,11 @@
|
||||
"CouldNotFindResults": "Pas de résultats pour '{0}'",
|
||||
"ClickToChangeMovie": "Cliquer pour changer le film",
|
||||
"CheckDownloadClientForDetails": "Vérifier le client de téléchargement pour plus de détails",
|
||||
"CantFindMovie": "Pourquoi ne puis-je pas trouver mon film ?",
|
||||
"CantFindMovie": "Pourquoi je ne parviens pas trouver mon film ?",
|
||||
"CancelPendingTask": "Êtes-vous sur de vouloir annuler cette tâche en attente ?",
|
||||
"BranchUpdateMechanism": "Branche utilisée par le mécanisme de mise à jour extérieur",
|
||||
"BranchUpdate": "Branche à utiliser pour mettre à jour Radarr",
|
||||
"BeforeUpdate": "Avant mise à jour",
|
||||
"BeforeUpdate": "Avant la mise à jour",
|
||||
"ApplyTagsHelpTextHowToApplyMovies": "Comment appliquer des tags au film sélectionné",
|
||||
"DeleteDownloadClientMessageText": "Êtes-vous sûr de vouloir supprimer le client de téléchargement '{0}' ?",
|
||||
"DeleteBackupMessageText": "Êtes-vous sûr de vouloir supprimer la sauvegarde '{0}' ?",
|
||||
@@ -486,7 +486,7 @@
|
||||
"DelayingDownloadUntilInterp": "Retarder le téléchargement jusqu'au {0} à {1}",
|
||||
"CustomFormatUnknownConditionOption": "Option inconnue '{0}' pour la condition '{1}'",
|
||||
"CustomFormatUnknownCondition": "Condition de format personnalisé inconnue '{0}'",
|
||||
"CloneCustomFormat": "Cloner le format personnalisé",
|
||||
"CloneCustomFormat": "Dupliqué le format personnalisé",
|
||||
"UnableToLoadRootFolders": "Impossible de charger les dossiers racine",
|
||||
"UnableToLoadRestrictions": "Impossible de charger les restrictions",
|
||||
"UnableToLoadRemotePathMappings": "Impossible de charger les mappages de chemins distants",
|
||||
@@ -782,7 +782,7 @@
|
||||
"CloseCurrentModal": "Fermer le modal actuel",
|
||||
"AddingTag": "Ajouter un tag",
|
||||
"OnHealthIssueHelpText": "Lors d'un problème de santé",
|
||||
"AcceptConfirmationModal": "Accepter la fenêtre de confirmation",
|
||||
"AcceptConfirmationModal": "Accepter les modalités d'utilisations",
|
||||
"StartSearchForMissingMovie": "Lancer la recherche de film manquant",
|
||||
"StartProcessing": "Lancer le traitement",
|
||||
"StartImport": "Lancer l'importation",
|
||||
@@ -797,9 +797,9 @@
|
||||
"ImportErrors": "Erreurs d'importation",
|
||||
"Existing": "Existant",
|
||||
"EditRestriction": "Modifier la restriction",
|
||||
"CancelProcessing": "Annuler le traitement",
|
||||
"AddRestriction": "Ajouter Restriction",
|
||||
"AddMovie": "Ajouter Film",
|
||||
"CancelProcessing": "Annuler la tâche",
|
||||
"AddRestriction": "Ajouter une restriction",
|
||||
"AddMovie": "Ajouter un film",
|
||||
"IndexerLongTermStatusCheckSingleClientMessage": "Indexeurs indisponibles en raison de pannes pendant plus de 6 heures : {0}",
|
||||
"IndexerLongTermStatusCheckAllClientMessage": "Tous les indexeurs sont indisponibles en raison d'échecs de plus de 6 heures",
|
||||
"EditMovieFile": "Modifier Fichier Vidéo",
|
||||
@@ -833,11 +833,11 @@
|
||||
"AfterManualRefresh": "Après un rafraichissement manuel",
|
||||
"AllFiles": "Tous les fichiers",
|
||||
"AllMoviesInPathHaveBeenImported": "Tous les films dans {0} ont été importés",
|
||||
"AllResultsHiddenFilter": "Tous les résultats ont été dissimulés par le filtre actuellement appliqué",
|
||||
"AllResultsHiddenFilter": "Tous les résultats ont été masqués par le filtre actuellement appliqué",
|
||||
"Always": "Toujours",
|
||||
"AptUpdater": "Utiliser apt pour installer la mise à jour",
|
||||
"AuthBasic": "Authentification de base (popup)",
|
||||
"AuthForm": "Authentification par formulaire (page de connexion)",
|
||||
"AuthBasic": "Authentification de base (Basic) (popup dans le navigateur)",
|
||||
"AuthForm": "Authentification par un formulaire (page de connexion)",
|
||||
"BuiltIn": "Natif",
|
||||
"CalendarOptions": "Options du calendrier",
|
||||
"CertValidationNoLocal": "Désactivé pour les adresses IP locales",
|
||||
@@ -1044,11 +1044,11 @@
|
||||
"RemotePathMappingCheckFileRemoved": "Le fichier {0} a été supprimé pendant le processus.",
|
||||
"UnableToAddRootFolder": "Impossible de charger les dossiers racine",
|
||||
"Blocklist": "Liste noire",
|
||||
"BlocklistHelpText": "Empêche Radarr de récupérer automatiquement cette version",
|
||||
"BlocklistRelease": "Mettre cette release sur la liste noire",
|
||||
"BlocklistHelpText": "Prévenir Radarr de ne pas récupérer automatiquement cette version",
|
||||
"BlocklistRelease": "Version sur liste noire",
|
||||
"RemoveFromBlocklist": "Supprimer de la liste noire",
|
||||
"UnableToLoadBlocklist": "Impossible de charger la liste noire",
|
||||
"Blocklisted": "Liste noire",
|
||||
"Blocklisted": "Dans le liste noire",
|
||||
"BlocklistReleases": "Mettre cette release sur la liste noire",
|
||||
"RemotePathMappingCheckGenericPermissions": "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.",
|
||||
"RemotePathMappingCheckLocalWrongOSPath": "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.",
|
||||
@@ -1124,7 +1124,7 @@
|
||||
"ShowCollectionDetails": "Afficher l'état de la collection",
|
||||
"EditCollection": "Modifier la collection",
|
||||
"ApplicationURL": "URL de l'application",
|
||||
"ApplicationUrlHelpText": "URL externe de cette application, y compris http(s)://, le port et l'URL de base",
|
||||
"ApplicationUrlHelpText": "URL externe de cette application, y compris http(s)://, le port ainsi que la base de URL",
|
||||
"InstanceName": "Nom de l'instance",
|
||||
"InstanceNameHelpText": "Nom de l'instance dans l'onglet du navigateur et pour le nom d'application dans Syslog",
|
||||
"CollectionShowPostersHelpText": "Afficher les affiches des éléments de la collection",
|
||||
@@ -1174,14 +1174,16 @@
|
||||
"DeleteFormatMessageText": "Êtes-vous sûr de vouloir supprimer le tag {0} ?",
|
||||
"DeleteImportListExclusionMessageText": "Êtes vous sûr de vouloir effacer cette exclusion de liste d'imports ?",
|
||||
"DeleteSelectedDownloadClients": "Supprimer le client de téléchargement",
|
||||
"ApplyTagsHelpTextAdd": "Ajouter : Ajouter les étiquettes à la liste des étiquettes existantes",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "Comment appliquer des étiquettes aux indexeurs sélectionnés",
|
||||
"ApplyTagsHelpTextRemove": "Retirer : Retire les étiquettes renseignées",
|
||||
"ApplyTagsHelpTextAdd": "Ajouter : Ajouter les tags à la liste de tags existantes",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "Comment appliquer des tags aux indexeurs sélectionnés",
|
||||
"ApplyTagsHelpTextRemove": "Suprimer : Suprime les étiquettes renseignées",
|
||||
"ApplyTagsHelpTextReplace": "Remplacer : Remplace les tags par les tags renseignés (ne pas renseigner de tags pour effacer tous les tags)",
|
||||
"DeleteSelectedIndexers": "Supprimer l'indexeur",
|
||||
"RemoveSelectedItemsQueueMessageText": "Êtes-vous sûr de vouloir supprimer {0} objet(s) de la file d'attente ?",
|
||||
"DeleteSelectedIndexersMessageText": "Voulez-vous vraiment supprimer l'indexeur '{0}' ?",
|
||||
"EditSelectedIndexers": "Modifier les indexeurs sélectionnés",
|
||||
"CountDownloadClientsSelected": "{0} client(s) de téléchargement sélectionné(s)",
|
||||
"EditSelectedDownloadClients": "Modifier les clients de téléchargement sélectionnés"
|
||||
"EditSelectedDownloadClients": "Modifier les clients de téléchargement sélectionnés",
|
||||
"AddAutoTag": "Ajouter un tag automatique",
|
||||
"AddCondition": "Ajouter une condition"
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
"Failed": "נִכשָׁל",
|
||||
"InCinemas": "בבתי הקולנוע",
|
||||
"IncludeCustomFormatWhenRenaming": "כלול פורמט מותאם אישית בעת שינוי שם",
|
||||
"Indexer": "מַפתְחָן",
|
||||
"Indexer": "אינדקסר",
|
||||
"IndexerFlags": "אינדקס דגלים",
|
||||
"IndexerLongTermStatusCheckAllClientMessage": "כל האינדקסים אינם זמינים עקב כשלים במשך יותר מ -6 שעות",
|
||||
"IndexerLongTermStatusCheckSingleClientMessage": "אינדקסים לא זמינים עקב כשלים במשך יותר משש שעות: {0}",
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
"CreateEmptyMovieFoldersHelpText": "Crea le cartelle dei film mancanti durante la scansione del disco",
|
||||
"CreateEmptyMovieFolders": "Crea cartelle vuote per i film",
|
||||
"CopyUsingHardlinksHelpTextWarning": "Occasionalmente i file bloccatti possono impedire la rinomina dei file in seeding. Puoi disattivare temporaneamente il seeding e utilizzare la funzione di rinomina di Radarr per evitare il problema.",
|
||||
"CopyUsingHardlinksHelpText": "Utilizzare gli Hardlink quando si cerca di copiare file di un torrent che è ancora in seeding",
|
||||
"CopyUsingHardlinksHelpText": "Gli Hardlink permettono a Radarr di importare torrent in seeding nella cartella film senza occupare ulteriore spazio su disco o copiare l'intero contenuto del file.\nGli Hardlink funzionano solo se il file sorgente e di destinazione sono sullo stesso volume",
|
||||
"ConnectSettings": "Impostazioni di Connessione",
|
||||
"ConnectionLostMessage": "Radarr ha perso la connessione al backend e dovrà essere ricaricato per ripristinare la funzionalità.",
|
||||
"ConnectionLostAutomaticMessage": "Radarr cercherà di connettersi automaticamente, oppure clicca su ricarica qui sotto.",
|
||||
@@ -388,7 +388,7 @@
|
||||
"SetPermissions": "Imposta permessi",
|
||||
"SendAnonymousUsageData": "Invia dati anonimi sull'uso",
|
||||
"SelectFolder": "Seleziona cartella",
|
||||
"SearchOnAddHelpText": "Cerca i film in questa lista quando aggiunti a Radarr",
|
||||
"SearchOnAddHelpText": "Cerca i film in questa lista quando aggiunti alla libreria",
|
||||
"SearchOnAdd": "Cerca dopo aggiunta",
|
||||
"SearchMovie": "Trova Film",
|
||||
"SearchForMovie": "Trova Film",
|
||||
@@ -443,7 +443,7 @@
|
||||
"ReadTheWikiForMoreInformation": "Leggi la Wiki per maggiori informazioni",
|
||||
"RadarrSupportsAnyIndexer": "Radarr supporta qualunque indexer che usi gli standard Newznab, cosi come gli altri Indexer sotto.",
|
||||
"RadarrSupportsAnyRSSMovieListsAsWellAsTheOneStatedBelow": "Radarr supporta qualunque Lista di film RSS, cosi come le altre sotto.",
|
||||
"RadarrSupportsAnyDownloadClient": "Radarr supporta qualunque client di download che usi gli standard Newznab, cosi come gli altri client sotto.",
|
||||
"RadarrSupportsAnyDownloadClient": "Radarr supporta molti tra i più popolari client di download torrent e usenet.",
|
||||
"QuickImport": "Sposta automaticamente",
|
||||
"Queued": "In coda",
|
||||
"QualitySettings": "Impostazione di Qualità",
|
||||
@@ -651,7 +651,7 @@
|
||||
"UpdateAutomaticallyHelpText": "Scarica e installa automaticamente gli aggiornamenti. Sarai comunque in grado in installarli da Sistema: Aggiornamenti",
|
||||
"UnsavedChanges": "Modifiche non salvate",
|
||||
"UnmonitoredHelpText": "Includi i film non monitorati nei feed di iCal",
|
||||
"Unreleased": "Non disponibile",
|
||||
"Unreleased": "Non rilasciato",
|
||||
"Ungroup": "Separa",
|
||||
"UnableToLoadUISettings": "Impossibile caricare le impostazioni interfaccia",
|
||||
"UnableToLoadTheCalendar": "Non riesco a caricare il calendario",
|
||||
@@ -945,7 +945,7 @@
|
||||
"Months": "Mesi",
|
||||
"MoreControlCFText": "Desideri un maggiore controllo sui download preferiti? Aggiungere un",
|
||||
"MoveFolders1": "Spostare le cartelle dei film in \"{0}\"?",
|
||||
"MovieChat": "Chat di film",
|
||||
"MovieChat": "Movie Chat",
|
||||
"MovieInvalidFormat": "Film: formato non valido",
|
||||
"MultiLanguage": "Multi lingua",
|
||||
"Negate": "Negare",
|
||||
@@ -978,7 +978,7 @@
|
||||
"SearchCutoffUnmet": "Cerca Cutoff Unmet",
|
||||
"SearchMissing": "Ricerca mancante",
|
||||
"Seconds": "Secondi",
|
||||
"SelectDotDot": "'Selezionare...",
|
||||
"SelectDotDot": "Seleziona...",
|
||||
"SelectLanguage": "Seleziona la lingua",
|
||||
"SelectMovie": "Seleziona Film",
|
||||
"SelectQuality": "Seleziona qualità",
|
||||
@@ -989,11 +989,11 @@
|
||||
"Sunday": "Domenica",
|
||||
"TagDetails": "Dettagli tag - {0}",
|
||||
"TheLogLevelDefault": "Il livello di registro predefinito è \"Info\" e può essere modificato in",
|
||||
"ThisCannotBeCancelled": "Questo non può essere annullato una volta avviato senza riavviare Radarr.",
|
||||
"ThisCannotBeCancelled": "Questo non può essere annullato una volta avviato senza disabilitare tutti i tuoi indexers.",
|
||||
"TorrentDelayTime": "Ritardo torrent: {0}",
|
||||
"TorrentsDisabled": "Torrent disabilitato",
|
||||
"Trace": "Traccia",
|
||||
"Trailer": "trailer",
|
||||
"Trailer": "Trailer",
|
||||
"Trakt": "Trakt",
|
||||
"Trigger": "Trigger",
|
||||
"UnableToImportCheckLogs": "Scaricato - Impossibile importare: controlla i log per i dettagli",
|
||||
@@ -1078,7 +1078,7 @@
|
||||
"InstanceNameHelpText": "Nome istanza nella scheda e per il nome dell'app nel Syslog",
|
||||
"InstanceName": "Nome Istanza",
|
||||
"AllCollectionsHiddenDueToFilter": "Tutti i film sono nascosti a causa del filtro applicato.",
|
||||
"Collections": "Collezione",
|
||||
"Collections": "Collezioni",
|
||||
"MonitorMovies": "Monitora Film",
|
||||
"NoCollections": "Nessun film trovato, per iniziare ti consigliamo di aggiungere un nuovo film o importarne alcuni esistenti.",
|
||||
"RssSyncHelpText": "Intervallo in minuti. Imposta zero per disabilitarlo (ciò fermerà il recupero automatico di tutte le release)",
|
||||
@@ -1104,24 +1104,26 @@
|
||||
"TmdbRating": "Valutazione IMDb",
|
||||
"TmdbVotes": "Voti IMDb",
|
||||
"EditMovies": "Modifica Film",
|
||||
"DeleteRemotePathMapping": "Modifica la Mappatura dei Percorsi Remoti",
|
||||
"DeleteRemotePathMapping": "Elimina la Mappatura dei Percorsi Remoti",
|
||||
"ApplyTagsHelpTextReplace": "Sostituire: Sostituisce le etichette con quelle inserite (non inserire nessuna etichette per eliminarle tutte)",
|
||||
"DownloadClientTagHelpText": "Usa questo indicizzatore per i film con almeno un tag corrispondente. Lascia in bianco per usarlo con tutti i film.",
|
||||
"DeleteConditionMessageText": "Sei sicuro di voler eliminare l'etichetta '{0}'?",
|
||||
"DeleteCustomFormatMessageText": "Sei sicuro di voler eliminare l'indexer '{0}'?",
|
||||
"DeleteConditionMessageText": "Sei sicuro di voler eliminare la condizione '{0}'?",
|
||||
"DeleteCustomFormatMessageText": "Sei sicuro di voler eliminare il formato personalizzato '{0}'?",
|
||||
"DeleteDelayProfileMessageText": "Sei sicuro di voler cancellare questo profilo di ritardo?",
|
||||
"DeleteFormatMessageText": "Sei sicuro di voler cancellare il formato etichetta {0} ?",
|
||||
"DeleteImportListExclusionMessageText": "Sei sicuro di voler cancellare questa lista di esclusioni delle importazioni?",
|
||||
"DeleteIndexers": "Cancella Indexer",
|
||||
"CountIndexersSelected": "{0} Indicizzatore(i) Selezionato(i)",
|
||||
"DeleteIndexersMessageText": "Sei sicuro di voler eliminare l'indexer '{0}'?",
|
||||
"DeleteIndexers": "Cancella Indicizzatore(i)",
|
||||
"CountIndexersSelected": "{0} indicizzatore(i) selezionato(i)",
|
||||
"DeleteIndexersMessageText": "Sei sicuro di voler eliminare {0} indicizzatore(i)?",
|
||||
"RemoveSelectedItemQueueMessageText": "Sei sicuro di voler rimuovere {0} dalla coda?",
|
||||
"RemoveSelectedItemsQueueMessageText": "Sei sicuro di voler rimuovere {0} dalla coda?",
|
||||
"ResetAPIKeyMessageText": "Sei sicuro di voler reimpostare la tua chiave API?",
|
||||
"ApplyTagsHelpTextAdd": "Aggiungi: Aggiunge le etichette alla lista esistente di etichette",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "Come applicare etichette agli indicizzatori selezionati",
|
||||
"ApplyTagsHelpTextRemove": "Rimuovi: Rimuove le etichette inserite",
|
||||
"DeleteSelectedDownloadClients": "Cancella il Client di Download",
|
||||
"DeleteSelectedDownloadClients": "Cancella i Client di Download",
|
||||
"DeleteSelectedImportLists": "Cancella la lista di importazione",
|
||||
"DeleteSelectedIndexers": "Cancella Indexer"
|
||||
"DeleteSelectedIndexers": "Cancella Indexer",
|
||||
"MoveAutomatically": "Sposta Automaticamente",
|
||||
"UpdateFiltered": "Aggiorna Filtrati"
|
||||
}
|
||||
|
||||
@@ -273,5 +273,7 @@
|
||||
"DeleteSelectedIndexersMessageText": "Er du sikker på at du vil slette formattaggen {0}?",
|
||||
"AllTitles": "Alle titler",
|
||||
"ApplyChanges": "Bekreft endringer",
|
||||
"ApiKeyValidationHealthCheckMessage": "Vennligst oppdater din API-nøkkel til å være minst {0} tegn lang. Du kan gjøre dette via innstillinger eller konfigurasjonsfilen"
|
||||
"ApiKeyValidationHealthCheckMessage": "Vennligst oppdater din API-nøkkel til å være minst {0} tegn lang. Du kan gjøre dette via innstillinger eller konfigurasjonsfilen",
|
||||
"AddAutoTag": "Legg til automatisk tagg",
|
||||
"AddCondition": "Legg til betingelse"
|
||||
}
|
||||
|
||||
@@ -1172,5 +1172,9 @@
|
||||
"ApplyTagsHelpTextHowToApplyDownloadClients": "Hoe tags toepassen op de geselecteerde download clients",
|
||||
"ApplyChanges": "Pas Wijzigingen Toe",
|
||||
"CloneCondition": "Kloon Conditie",
|
||||
"AutomaticAdd": "Automatisch Toevoegen"
|
||||
"AutomaticAdd": "Automatisch Toevoegen",
|
||||
"AddAutoTag": "Voeg Automatische Tag toe",
|
||||
"AddCondition": "Voeg Conditie toe",
|
||||
"AutoTagging": "Automatisch Taggen",
|
||||
"CloneAutoTag": "Kopieer Automatische Tag"
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
"AddingTag": "Dodawanie tagu",
|
||||
"AddNotification": "Dodaj powiadomienie",
|
||||
"AddQualityProfile": "Dodaj profil jakości",
|
||||
"Announced": "Ogłoszony",
|
||||
"Announced": "Zapowiedziany",
|
||||
"AutoRedownloadFailedHelpText": "Automatycznie wyszukuj i próbuj pobrać inną wersję",
|
||||
"AddRootFolder": "Dodaj folder główny",
|
||||
"AvailabilityDelay": "Opóźnienie dostępności",
|
||||
@@ -197,9 +197,9 @@
|
||||
"LastDuration": "Ostatni czas trwania",
|
||||
"LastExecution": "Ostatnia egzekucja",
|
||||
"AppDataDirectory": "Katalog AppData",
|
||||
"Apply": "Zastosować",
|
||||
"Apply": "Zastosuj",
|
||||
"AptUpdater": "Użyj apt, aby zainstalować aktualizację",
|
||||
"AudioInfo": "Informacje audio",
|
||||
"AudioInfo": "Informacje o audio",
|
||||
"OnLatestVersion": "Najnowsza wersja Radarr jest już zainstalowana",
|
||||
"OnlyTorrent": "Tylko Torrent",
|
||||
"OnlyUsenet": "Tylko Usenet",
|
||||
@@ -210,7 +210,7 @@
|
||||
"AuthenticationMethodHelpText": "Wymagaj nazwy użytkownika i hasła, aby uzyskać dostęp do Radarr",
|
||||
"AuthForm": "Formularze (strona logowania)",
|
||||
"Automatic": "Automatyczny",
|
||||
"AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Filmy usunięte z dysku są automatycznie niemonitorowane w Radarr",
|
||||
"AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Filmy usunięte z dysku automatycznie przestają być monitorowane w Radarr",
|
||||
"BackupRetentionHelpText": "Automatyczne kopie zapasowe starsze niż okres przechowywania zostaną automatycznie wyczyszczone",
|
||||
"WhatsNew": "Co nowego?",
|
||||
"Branch": "Gałąź",
|
||||
@@ -263,7 +263,7 @@
|
||||
"NoMoveFilesSelf": " Nie, sam przeniosę pliki",
|
||||
"NoMoviesExist": "Nie znaleziono żadnych filmów. Aby rozpocząć, musisz dodać nowy film lub zaimportować istniejące.",
|
||||
"NoResultsFound": "Nie znaleziono wyników",
|
||||
"BranchUpdate": "Oddział do użycia do aktualizacji Radarr",
|
||||
"BranchUpdate": "Gałąź do użycia do aktualizacji Radarr",
|
||||
"BranchUpdateMechanism": "Gałąź używana przez zewnętrzny mechanizm aktualizacji",
|
||||
"BypassProxyForLocalAddresses": "Pomijaj serwer proxy dla adresów lokalnych",
|
||||
"Cancel": "Anuluj",
|
||||
@@ -339,7 +339,7 @@
|
||||
"MovieIsDownloadingInterp": "Film jest pobierany - {0}% {1}",
|
||||
"MovieIsMonitored": "Film jest monitorowany",
|
||||
"AsAllDayHelpText": "Wydarzenia pojawią się w Twoim kalendarzu jako wydarzenia całodniowe",
|
||||
"Authentication": "Poświadczenie",
|
||||
"Authentication": "Autoryzacja",
|
||||
"Backups": "Kopie zapasowe",
|
||||
"BeforeUpdate": "Przed aktualizacją",
|
||||
"BindAddress": "Adres powiązania",
|
||||
@@ -431,7 +431,7 @@
|
||||
"AllowHardcodedSubsHelpText": "Wykryte wbudowane napisy zostaną automatycznie pobrane",
|
||||
"AlreadyInYourLibrary": "Już w Twojej bibliotece",
|
||||
"SystemTimeCheckMessage": "Czas systemowy jest wyłączony o więcej niż 1 dzień. Zaplanowane zadania mogą nie działać poprawnie, dopóki czas nie zostanie skorygowany",
|
||||
"AnalyticsEnabledHelpText": "Wysyłaj anonimowe informacje o użytkowaniu i błędach do serwerów Radarr. Obejmuje to informacje o Twojej przeglądarce, z których stron Radarr WebUI używasz, raportowanie błędów, a także wersję systemu operacyjnego i środowiska wykonawczego. Wykorzystamy te informacje, aby nadać priorytet funkcjom i poprawkom błędów.",
|
||||
"AnalyticsEnabledHelpText": "Wysyłaj anonimowe informacje o użytkowaniu i błędach do serwerów Radarr. Obejmuje to informacje o Twojej przeglądarce, z których stron Radarr WebUI korzystasz, raportowanie błędów, a także wersję systemu operacyjnego i środowiska wykonawczego. Wykorzystamy te informacje, aby nadać priorytet funkcjom i poprawkom błędów.",
|
||||
"MinimumFreeSpace": "Minimalna wolna przestrzeń",
|
||||
"MinimumLimits": "Minimalne limity",
|
||||
"ReleaseRejected": "Wersja odrzucona",
|
||||
@@ -442,7 +442,7 @@
|
||||
"PosterSize": "Rozmiar plakatu",
|
||||
"TimeFormat": "Format czasu",
|
||||
"Timeleft": "Pozostały czas",
|
||||
"AddImportExclusionHelpText": "Zapobiegaj dodawaniu filmu do Radarr według list",
|
||||
"AddImportExclusionHelpText": "Zapobiegaj dodawaniu filmu do Radarr przez listy",
|
||||
"ImportListStatusCheckAllClientMessage": "Wszystkie listy są niedostępne z powodu błędów",
|
||||
"ImportListStatusCheckSingleClientMessage": "Listy niedostępne z powodu błędów: {0}",
|
||||
"New": "Nowy",
|
||||
@@ -1030,11 +1030,11 @@
|
||||
"DeleteFileLabel": "Usuń {0} pliki filmowe",
|
||||
"UnableToAddRootFolder": "Nie można dodać folderu głównego",
|
||||
"Blocklist": "Czarna lista",
|
||||
"BlocklistRelease": "Wydanie czarnej listy",
|
||||
"BlocklistRelease": "Dodaj wersję do czarnej listy",
|
||||
"RemoveFromBlocklist": "Usuń z czarnej listy",
|
||||
"UnableToLoadBlocklist": "Nie można załadować listy blokowania",
|
||||
"Blocklisted": "Czarna lista",
|
||||
"BlocklistReleases": "Wydanie czarnej listy",
|
||||
"BlocklistReleases": "Dodaj wersje do czarnej listy",
|
||||
"Filters": "Filtry",
|
||||
"LocalPath": "Ścieżka lokalna",
|
||||
"List": "Lista",
|
||||
@@ -1127,7 +1127,7 @@
|
||||
"CollectionShowOverviewsHelpText": "Pokaż przegląd kolekcji",
|
||||
"TotalMovies": "Filmów całkowicie",
|
||||
"RottenTomatoesRating": "Ocena Tomato",
|
||||
"ApplicationUrlHelpText": "Zewnętrzny URL tej aplikacji zawiera http(s)://, port i adres URL",
|
||||
"ApplicationUrlHelpText": "Zewnętrzny URL tej aplikacji zawierający http(s)://, port i adres URL",
|
||||
"ApplicationURL": "Link do aplikacji",
|
||||
"File": "Plik",
|
||||
"Language": "Język",
|
||||
@@ -1150,7 +1150,17 @@
|
||||
"RemoveSelectedItemBlocklistMessageText": "Czy na pewno chcesz usunąć wybrane elementy z czarnej listy?",
|
||||
"RemoveSelectedItemQueueMessageText": "Czy na pewno chcesz usunąć {0} element {1} z kolejki?",
|
||||
"ApplyTagsHelpTextAdd": "Dodaj: dodaj tagi do istniejącej listy tagów",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "Jak zastosować tagi do wybranych filmów",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "Jak zastosować tagi do wybranych indeksatorów",
|
||||
"ApplyTagsHelpTextRemove": "Usuń: usuń wprowadzone tagi",
|
||||
"ApplyTagsHelpTextReplace": "Zastąp: Zastąp tagi wprowadzonymi tagami (nie wprowadzaj tagów, aby usunąć wszystkie tagi)"
|
||||
"ApplyTagsHelpTextReplace": "Zastąp: Zastąp tagi wprowadzonymi tagami (nie wprowadzaj tagów, aby usunąć wszystkie tagi)",
|
||||
"ApplyTagsHelpTextHowToApplyMovies": "Jak zastosować tagi do wybranych filmów",
|
||||
"ApplyChanges": "Zastosuj zmiany",
|
||||
"AddCondition": "Dodaj warunek",
|
||||
"AutoTagging": "Automatyczne tagowanie",
|
||||
"AllTitles": "Wszystkie tytuły",
|
||||
"ApplyTagsHelpTextHowToApplyImportLists": "Jak zastosować tagi do wybranych list",
|
||||
"ApplyTagsHelpTextHowToApplyDownloadClients": "Jak",
|
||||
"ApiKeyValidationHealthCheckMessage": "Zaktualizuj swój klucz API aby był długi na co najmniej {0} znaków. Możesz to zrobić poprzez ustawienia lub plik konfiguracyjny",
|
||||
"AddAutoTag": "Dodaj automatyczne tagi",
|
||||
"AutoTaggingNegateHelpText": "Jeśli zaznaczone, zasada automatycznego tagowania nie będzie zastosowana, jeśli ten {0} warunek będzie spełniony"
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
"Language": "Idioma",
|
||||
"KeyboardShortcuts": "Atalhos de teclado",
|
||||
"KeepAndUnmonitorMovie": "Manter e não monitorar filme",
|
||||
"InvalidFormat": "Formato inválido",
|
||||
"InvalidFormat": "Formato Inválido",
|
||||
"Interval": "Intervalo",
|
||||
"InteractiveSearch": "Pesquisa interativa",
|
||||
"InteractiveSearch": "Pesquisa Interativa",
|
||||
"InteractiveImportErrQuality": "Escolha a qualidade para cada arquivo selecionado",
|
||||
"InteractiveImportErrMovie": "Escolha o filme para cada arquivo selecionado",
|
||||
"InteractiveImportErrLanguage": "Escolha o idioma para cada arquivo selecionado",
|
||||
@@ -18,7 +18,7 @@
|
||||
"IndexerStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas: {0}",
|
||||
"IndexerStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas",
|
||||
"IndexersSettingsSummary": "Indexadores e restrições de lançamento",
|
||||
"IndexerSettings": "Configurações do indexador",
|
||||
"IndexerSettings": "Configurações do Indexador",
|
||||
"IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a Pesquisa interativa habilitada, o Radarr não fornecerá nenhum resultado de pesquisa interativa",
|
||||
"IndexerSearchCheckNoAvailableIndexersMessage": "Todos os indexadores com capacidade de pesquisa estão temporariamente indisponíveis devido a erros recentes do indexador",
|
||||
"IndexerSearchCheckNoAutomaticMessage": "Nenhum indexador disponível com a Pesquisa automática habilitada, o Radarr não fornecerá nenhum resultado de pesquisa automática",
|
||||
@@ -26,7 +26,7 @@
|
||||
"IndexerRssHealthCheckNoIndexers": "Nenhum indexador disponível com sincronização RSS habilitada, o Radarr não capturará novas versões automaticamente",
|
||||
"IndexerRssHealthCheckNoAvailableIndexers": "Todos os indexadores compatíveis com rss estão temporariamente indisponíveis devido a erros recentes do indexador",
|
||||
"IndexerPriorityHelpText": "Prioridade do indexador de 1 (maior) a 50 (menor). Padrão: 25. Usado quando obtendo lançamentos como um desempate para lançamentos iguais, o Radarr ainda usará todos os indexadores habilitados para Sync e pesquisa de RSS",
|
||||
"IndexerPriority": "Prioridade do indexador",
|
||||
"IndexerPriority": "Prioridade do Indexador",
|
||||
"IndexerLongTermStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas por mais de 6 horas: {0}",
|
||||
"IndexerLongTermStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas por mais de 6 horas",
|
||||
"IndexerFlags": "Sinalizadores do indexador",
|
||||
@@ -37,7 +37,7 @@
|
||||
"IncludeRadarrRecommendations": "Incluir recomendações do Radarr",
|
||||
"IncludeHealthWarningsHelpText": "Incluir avisos de integridade",
|
||||
"IncludeCustomFormatWhenRenamingHelpText": "Incluir no formato de renomeação {Custom Formats}",
|
||||
"IncludeCustomFormatWhenRenaming": "Incluir formato personalizado ao renomear",
|
||||
"IncludeCustomFormatWhenRenaming": "Incluir Formato Personalizado ao Renomear",
|
||||
"InCinemasMsg": "O filme está nos cinemas",
|
||||
"InCinemasDate": "Data de lançamento nos cinemas",
|
||||
"InCinemas": "Nos cinemas",
|
||||
@@ -53,12 +53,12 @@
|
||||
"ImportFailedInterp": "Falha na importação: {0}",
|
||||
"ImportFailed": "Falha na importação: {0}",
|
||||
"ImportExtraFilesHelpText": "Importar arquivos adicionais correspondentes (legendas, nfo, etc.) após importar um arquivo de filme",
|
||||
"ImportExtraFiles": "Importar arquivos adicionais",
|
||||
"ImportExtraFiles": "Importar Arquivos Extras",
|
||||
"ImportExistingMovies": "Importar filmes existentes",
|
||||
"ImportErrors": "Erros da importação",
|
||||
"ImportErrors": "Erros de Importação",
|
||||
"ImportedTo": "Importado para",
|
||||
"Imported": "Importado",
|
||||
"ImportCustomFormat": "Importar formato personalizado",
|
||||
"ImportCustomFormat": "Importar Formato Personalizado",
|
||||
"Import": "Importar",
|
||||
"IMDb": "IMDb",
|
||||
"Images": "Imagens",
|
||||
@@ -66,7 +66,7 @@
|
||||
"IgnoredPlaceHolder": "Adicionar nova restrição",
|
||||
"IgnoredHelpText": "O lançamento será rejeitado se contiver um ou mais desses termos (não diferencia maiúsculas de minúsculas)",
|
||||
"IgnoreDeletedMovies": "Não monitorar filmes excluídos",
|
||||
"IgnoredAddresses": "Endereços ignorados",
|
||||
"IgnoredAddresses": "Endereços Ignorados",
|
||||
"Ignored": "Ignorado",
|
||||
"IconForCutoffUnmet": "Ícone para Limite não atingido",
|
||||
"iCalLink": "Link do iCal",
|
||||
@@ -74,7 +74,7 @@
|
||||
"ICalFeed": "Feed do iCal",
|
||||
"HttpHttps": "HTTP(S)",
|
||||
"Hours": "Horas",
|
||||
"Hostname": "Nome do host",
|
||||
"Hostname": "Hostname",
|
||||
"Host": "Host",
|
||||
"HomePage": "Página Inicial",
|
||||
"History": "Histórico",
|
||||
@@ -109,16 +109,16 @@
|
||||
"Folder": "Pasta",
|
||||
"FocusSearchBox": "Selecionar caixa de pesquisa",
|
||||
"Fixed": "Corrigido",
|
||||
"FirstDayOfWeek": "Primeiro dia da semana",
|
||||
"FirstDayOfWeek": "Primeiro Dia da Semana",
|
||||
"FilterPlaceHolder": "Pesquisar filmes",
|
||||
"Filter": "Filtrar",
|
||||
"FileWasDeletedByViaUI": "Arquivo foi excluído através da interface do usuário",
|
||||
"FileWasDeletedByUpgrade": "Arquivo foi excluído para importar uma atualização",
|
||||
"Files": "Arquivos",
|
||||
"FileNameTokens": "Tokens de nome de arquivo",
|
||||
"FileNames": "Nomes dos arquivos",
|
||||
"FileNameTokens": "Tokens de Nome de Arquivo",
|
||||
"FileNames": "Nomes de Arquivo",
|
||||
"Filename": "Nome do arquivo",
|
||||
"FileManagement": "Gerenciamento de arquivo",
|
||||
"FileManagement": "Gerenciamento de Arquivo",
|
||||
"FileDateHelpText": "Alterar a data do arquivo ao importar/verificar novamente",
|
||||
"FeatureRequests": "Solicitações de recursos",
|
||||
"FailedToLoadQueue": "Falha ao carregar a fila",
|
||||
@@ -150,39 +150,39 @@
|
||||
"EnableRSS": "Habilitar RSS",
|
||||
"EnableMediaInfoHelpText": "Extrair informações do vídeo, como resolução, duração e informações do codec de arquivos. Isso requer que o Radarr leia partes do arquivo que podem causar alta atividade no disco ou na rede durante as verificações.",
|
||||
"EnableInteractiveSearchHelpTextWarning": "A pesquisa não é compatível com este indexador",
|
||||
"EnableInteractiveSearchHelpText": "Será usado com a pesquisa interativa",
|
||||
"EnableInteractiveSearchHelpText": "Será usado quando a pesquisa interativa for usada",
|
||||
"EnableInteractiveSearch": "Ativar pesquisa interativa",
|
||||
"EnableHelpText": "Habilitar a criação de um arquivo de metadados para este tipo de metadados",
|
||||
"EnableHelpText": "Habilitar criação de arquivo de metadados para este tipo de metadados",
|
||||
"EnabledHelpText": "Habilitar esta lista para uso no Radarr",
|
||||
"Enabled": "Habilitado",
|
||||
"EnableCompletedDownloadHandlingHelpText": "Importar automaticamente downloads concluídos do cliente de download",
|
||||
"EnableColorImpairedModeHelpText": "Estilo alterado para permitir que usuários com daltonismo distingam melhor as informações codificadas por cores",
|
||||
"EnableColorImpairedMode": "Habilitar modo para daltonismo",
|
||||
"EnableAutomaticSearchHelpTextWarning": "Será usado com a pesquisa interativa",
|
||||
"EnableColorImpairedModeHelpText": "Estilo alterado para permitir que usuários com deficiência de cor distingam melhor as informações codificadas por cores",
|
||||
"EnableColorImpairedMode": "Habilitar Modo para Deficientes Visuais",
|
||||
"EnableAutomaticSearchHelpTextWarning": "Será usado quando a pesquisa interativa for usada",
|
||||
"EnableAutomaticSearchHelpText": "Será usado ao realizar pesquisas automáticas pela interface ou pelo Radarr",
|
||||
"EnableAutomaticSearch": "Ativar pesquisa automática",
|
||||
"EnableAutomaticAdd": "Habilitar adição automática",
|
||||
"EnableAutomaticAdd": "Habilitar Adição Automática",
|
||||
"EnableAutoHelpText": "Se habilitada, os filmes serão automaticamente adicionados ao Radarr a partir desta lista",
|
||||
"Enable": "Habilitar",
|
||||
"EditRestriction": "Editar restrição",
|
||||
"EditRemotePathMapping": "Editar mapeamento de caminho remoto",
|
||||
"EditQualityProfile": "Editar perfil de qualidade",
|
||||
"EditRestriction": "Editar Restrição",
|
||||
"EditRemotePathMapping": "Editar Mapeamento do Caminho Remoto",
|
||||
"EditQualityProfile": "Editar Perfil de Qualidade",
|
||||
"EditPerson": "Editar pessoa",
|
||||
"EditMovieFile": "Editar arquivo do filme",
|
||||
"EditMovie": "Editar filme",
|
||||
"EditListExclusion": "Editar exclusão da lista",
|
||||
"EditListExclusion": "Editar Exclusão da Lista",
|
||||
"Edition": "Edição",
|
||||
"EditIndexer": "Editar indexador",
|
||||
"EditIndexer": "Editar Indexador",
|
||||
"EditGroups": "Editar Grupos",
|
||||
"EditDelayProfile": "Editar perfil de atraso",
|
||||
"EditCustomFormat": "Editar formato personalizado",
|
||||
"EditDelayProfile": "Editar Perfil de Atraso",
|
||||
"EditCustomFormat": "Editar Formato Personalizado",
|
||||
"Edit": "Editar",
|
||||
"DownloadWarningCheckDownloadClientForMoreDetails": "Aviso de download: verifique o cliente de download para saber mais",
|
||||
"DownloadWarning": "Aviso de download: {0}",
|
||||
"DownloadPropersAndRepacksHelpTextWarning": "Usar formatos personalizados para atualizações automáticas para Propers/Repacks",
|
||||
"DownloadPropersAndRepacksHelpTextWarning": "Use formatos personalizados para atualizações automáticas para Propers/Repacks",
|
||||
"DownloadPropersAndRepacksHelpText2": "Use \"Não preferir\" para classificar por pontuação de formato personalizado em relação a Propers/Repacks",
|
||||
"DownloadPropersAndRepacksHelpText1": "Se deve ou não atualizar automaticamente para Propers/Repacks",
|
||||
"DownloadPropersAndRepacks": "Propers e repacks",
|
||||
"DownloadPropersAndRepacks": "Propers e Repacks",
|
||||
"Downloading": "Baixando",
|
||||
"DownloadFailedInterp": "Falha no download: {0}",
|
||||
"DownloadFailedCheckDownloadClientForMoreDetails": "Falha no download: verifique o cliente de download para saber mais",
|
||||
@@ -193,15 +193,15 @@
|
||||
"DownloadClientUnavailable": "O cliente de download está indisponível",
|
||||
"DownloadClientStatusCheckSingleClientMessage": "Clientes de download indisponíveis devido a falhas: {0}",
|
||||
"DownloadClientStatusCheckAllClientMessage": "Todos os clientes de download estão indisponíveis devido a falhas",
|
||||
"DownloadClientsSettingsSummary": "Clientes de download, gerenciamento do download e mapeamento remoto de caminhos",
|
||||
"DownloadClientSettings": "Configurações do cliente de download",
|
||||
"DownloadClientsSettingsSummary": "Clientes de download, gerenciamento de download e mapeamentos de caminhos remotos",
|
||||
"DownloadClientSettings": "Configurações do Cliente de Download",
|
||||
"DownloadClients": "Clientes de download",
|
||||
"DownloadClientCheckUnableToCommunicateMessage": "Não é possível se comunicar com {0}.",
|
||||
"DownloadClientCheckNoneAvailableMessage": "Nenhum cliente de download está disponível",
|
||||
"DownloadClient": "Cliente de Download",
|
||||
"DoNotUpgradeAutomatically": "Não atualizar automaticamente",
|
||||
"DoNotUpgradeAutomatically": "Não Atualizar Automaticamente",
|
||||
"DoNotPrefer": "Não preferir",
|
||||
"DoneEditingGroups": "Concluído a Edição de Grupos",
|
||||
"DoneEditingGroups": "Concluir Edição de Grupos",
|
||||
"Donations": "Doações",
|
||||
"DockerUpdater": "atualizar o contêiner do Docker para receber a atualização",
|
||||
"Docker": "Docker",
|
||||
@@ -223,16 +223,16 @@
|
||||
"DeleteSelectedMovie": "Excluir filme(s) selecionado(s)",
|
||||
"DeleteRestrictionHelpText": "Tem certeza de que deseja excluir esta restrição?",
|
||||
"DeleteRestriction": "Excluir restrição",
|
||||
"DeleteQualityProfile": "Excluir perfil de qualidade",
|
||||
"DeleteQualityProfile": "Excluir Perfil de Qualidade",
|
||||
"DeleteNotificationMessageText": "Tem certeza de que deseja excluir a notificação \"{0}\"?",
|
||||
"DeleteNotification": "Excluir notificação",
|
||||
"DeleteNotification": "Excluir Notificação",
|
||||
"DeleteMovieFolderLabel": "Excluir pasta do filme",
|
||||
"DeleteMovieFolderHelpText": "Excluir a pasta do filme e seu conteúdo",
|
||||
"DeleteListMessageText": "Tem certeza de que deseja excluir a lista \"{0}\"?",
|
||||
"DeleteList": "Excluir lista",
|
||||
"DeleteIndexerMessageText": "Tem certeza de que deseja excluir o indexador \"{0}\"?",
|
||||
"DeleteIndexer": "Excluir indexador",
|
||||
"DeleteImportListExclusion": "Remover exclusão da lista de importação",
|
||||
"DeleteIndexer": "Excluir Indexador",
|
||||
"DeleteImportListExclusion": "Excluir Exclusão da Lista de Importação",
|
||||
"DeleteHeader": "Excluir: {0}",
|
||||
"DeleteFilesLabel": "Excluir {0} arquivos do filme",
|
||||
"DeleteFilesHelpText": "Excluir os arquivos e a pasta do filme",
|
||||
@@ -240,19 +240,19 @@
|
||||
"DeleteEmptyFoldersHelpText": "Exclua pastas de filmes vazias durante a verificação do disco e quando os arquivos de filme forem excluídos",
|
||||
"DeleteEmptyFolders": "Excluir pastas vazias",
|
||||
"DeleteDownloadClientMessageText": "Tem certeza que deseja excluir o cliente de download \"{0}\"?",
|
||||
"DeleteDownloadClient": "Excluir cliente de download",
|
||||
"DeleteDownloadClient": "Excluir Cliente de Download",
|
||||
"DeletedMsg": "Filme excluído do TMDb",
|
||||
"DeleteDelayProfile": "Excluir perfil de atraso",
|
||||
"DeleteDelayProfile": "Excluir Perfil de Atraso",
|
||||
"Deleted": "Excluído",
|
||||
"DeleteCustomFormat": "Excluir formato personalizado",
|
||||
"DeleteBackupMessageText": "Tem certeza que deseja excluir o backup \"{0}\"?",
|
||||
"DeleteBackup": "Excluir Backup",
|
||||
"Delete": "Excluir",
|
||||
"DelayProfiles": "Perfis de atraso",
|
||||
"DelayProfile": "Perfil de atraso",
|
||||
"DelayProfiles": "Perfis de Atraso",
|
||||
"DelayProfile": "Perfil de Atraso",
|
||||
"DelayingDownloadUntilInterp": "Atrasando o download até {0} às {1}",
|
||||
"DefaultDelayProfile": "Este é o perfil padrão. Ele se aplica a todos os filmes que não possuem um perfil explícito.",
|
||||
"Debug": "Depurar",
|
||||
"Debug": "Depuração",
|
||||
"DBMigration": "Migração de banco de dados",
|
||||
"Dates": "Datas",
|
||||
"Days": "Dias",
|
||||
@@ -261,18 +261,18 @@
|
||||
"CutoffUnmet": "Limite não atingido",
|
||||
"CutoffHelpText": "Quando essa qualidade for atingida, o Radarr não fará mais o download de filmes depois que a pontuação de corte do formato personalizado for atingida ou excedida",
|
||||
"CutoffFormatScoreHelpText": "Uma vez que o corte de qualidade é atingido ou excedido e esta pontuação de formato personalizado é alcançada, o Radarr não irá mais capturar ou importar atualizações para esses filmes",
|
||||
"Cutoff": "Limite",
|
||||
"Cutoff": "Corte",
|
||||
"CustomFormatUnknownConditionOption": "Opção \"{0}\" desconhecida para a condição \"{1}\"",
|
||||
"CustomFormatUnknownCondition": "Condição de formato personalizado \"{0}\" desconhecida",
|
||||
"CustomFormatsSettingsSummary": "Configurações e formatos personalizados",
|
||||
"CustomFormatsSettings": "Configurações de formatos personalizados",
|
||||
"CustomFormatsSettingsSummary": "Configurações e Formatos Personalizados",
|
||||
"CustomFormatsSettings": "Configurações de Formatos Personalizados",
|
||||
"CustomFormatScore": "Pontuação de formato personalizado",
|
||||
"CustomFormats": "Formatos Personalizados",
|
||||
"CustomFormatJSON": "JSON de formato personalizado",
|
||||
"CustomFormatHelpText": "O Radarr pontua cada versão usando a soma das pontuações para formatos personalizados encontrados. Se uma nova versão tiver melhor pontuação, com a mesma qualidade ou melhor, o Radarr o capturará.",
|
||||
"CustomFormat": "Formato Personalizado",
|
||||
"CustomFilters": "Filtros Personalizados",
|
||||
"Custom": "Personalizado",
|
||||
"Custom": "Personalizar",
|
||||
"CurrentlyInstalled": "Atualmente instalado",
|
||||
"Crew": "Equipe técnica",
|
||||
"CreateGroup": "Criar grupo",
|
||||
@@ -282,10 +282,10 @@
|
||||
"CouldNotConnectSignalR": "Não é possível conectar ao SignalR, a interface não atualizará",
|
||||
"CopyUsingHardlinksHelpTextWarning": "Ocasionalmente, os bloqueios de arquivo podem impedir a renomeação de arquivos que estão sendo semeados. Você pode desabilitar temporariamente a semeadura e usar a função de renomeação do Radarr como uma solução alternativa.",
|
||||
"CopyUsingHardlinksHelpText": "Os hardlinks permitem que o Radarr importe torrents de propagação para a pasta do filme sem ocupar espaço extra em disco ou copiar todo o conteúdo do arquivo. Hardlinks só funcionarão se a origem e o destino estiverem no mesmo volume",
|
||||
"CopyToClipboard": "Copiar para área de transferência",
|
||||
"CopyToClipboard": "Copiar para Área de Transferência",
|
||||
"ConsideredAvailable": "Considerado disponível",
|
||||
"ConnectSettingsSummary": "Notificações, conexões com servidores/reprodutores de mídia, e scripts personalizados",
|
||||
"ConnectSettings": "Configurações de conexão",
|
||||
"ConnectSettingsSummary": "Notificações, conexões com servidores/reprodutores de mídia e scripts personalizados",
|
||||
"ConnectSettings": "Configurações de Conexão",
|
||||
"Connections": "Conexões",
|
||||
"ConnectionLostMessage": "O Radarr perdeu a conexão com o backend e precisará ser recarregado para restaurar a funcionalidade.",
|
||||
"ConnectionLostAutomaticMessage": "O Radarr tentará se conectar automaticamente, ou você pode clicar em Recarregar abaixo.",
|
||||
@@ -294,17 +294,17 @@
|
||||
"Connect": "Conectar",
|
||||
"Conditions": "Condições",
|
||||
"Component": "Componente",
|
||||
"CompletedDownloadHandling": "Gerenciamento de download concluído",
|
||||
"CompletedDownloadHandling": "Gerenciamento de Downloads Completos",
|
||||
"Columns": "Colunas",
|
||||
"ColonReplacementFormatHelpText": "Alterar como o Radarr lida com a substituição de dois-pontos",
|
||||
"ColonReplacement": "Substituição de Dois Pontos",
|
||||
"ColonReplacement": "Substituto para dois-pontos",
|
||||
"Collection": "Coleção",
|
||||
"CloseCurrentModal": "Fechar modal atual",
|
||||
"Close": "Fechar",
|
||||
"CloneProfile": "Clonar perfil",
|
||||
"CloneIndexer": "Clonar indexador",
|
||||
"CloneProfile": "Clonar Perfil",
|
||||
"CloneIndexer": "Clonar Indexador",
|
||||
"CloneCustomFormat": "Clonar formato personalizado",
|
||||
"ClientPriority": "Prioridade do cliente",
|
||||
"ClientPriority": "Prioridade do Cliente",
|
||||
"ClickToChangeQuality": "Clique para alterar a qualidade",
|
||||
"ClickToChangeMovie": "Clique para alterar o filme",
|
||||
"ClickToChangeLanguage": "Clique para alterar o idioma",
|
||||
@@ -314,30 +314,30 @@
|
||||
"ChmodGroupHelpText": "Nome ou ID do grupo. Use a ID para sistemas de arquivos remotos.",
|
||||
"ChmodGroup": "Grupo chmod",
|
||||
"ChmodFolderHelpTextWarning": "Isso só funciona se o usuário que está executando o Radarr for o proprietário do arquivo. É melhor garantir que o cliente de download defina as permissões corretamente.",
|
||||
"ChmodFolderHelpText": "Octal, aplicado durante a importação/renomeação a pastas e arquivos de mídia (sem executar bits)",
|
||||
"ChmodFolder": "Pasta chmod",
|
||||
"ChmodFolderHelpText": "Octal, aplicado durante a importação/renomeação de pastas e arquivos de mídia (sem bits de execução)",
|
||||
"ChmodFolder": "chmod Pasta",
|
||||
"CheckForFinishedDownloadsInterval": "Verifique o intervalo de downloads concluídos",
|
||||
"CheckDownloadClientForDetails": "verifique o cliente de download para saber mais",
|
||||
"ChangeHasNotBeenSavedYet": "Mudar o que não foi salvo ainda",
|
||||
"ChangeFileDate": "Mudar Data do Arquivo",
|
||||
"ChangeFileDate": "Alterar Data do Arquivo",
|
||||
"CertValidationNoLocal": "Desabilitado para endereços locais",
|
||||
"CertificationCountryHelpText": "Selecione o país para as certificações de filmes",
|
||||
"CertificationCountry": "País da certificação",
|
||||
"Certification": "Certificação",
|
||||
"CertificateValidationHelpText": "Mudar o quão rigorosa é a validação de certificação HTTPS. Não mude a menos que você entenda os riscos.",
|
||||
"CertificateValidation": "Validação do Certificado",
|
||||
"CertificateValidationHelpText": "Altere a rigidez da validação da certificação HTTPS. Não mude a menos que você entenda os riscos.",
|
||||
"CertificateValidation": "Validação de Certificado",
|
||||
"Cast": "Elenco",
|
||||
"CantFindMovie": "Por que não consigo encontrar meu filme?",
|
||||
"CancelProcessing": "Cancelar processamento",
|
||||
"CancelProcessing": "Cancelar Processamento",
|
||||
"CancelPendingTask": "Tem certeza de que deseja cancelar esta tarefa pendente?",
|
||||
"Cancel": "Cancelar",
|
||||
"CalendarOptions": "Opções de calendário",
|
||||
"Calendar": "Calendário",
|
||||
"BypassProxyForLocalAddresses": "Ignorar proxy para endereços locais",
|
||||
"BuiltIn": "Embutido",
|
||||
"BranchUpdateMechanism": "Ramificação usada pelo mecanismo de atualização externo",
|
||||
"BranchUpdateMechanism": "Ramificação usada pelo mecanismo externo de atualização",
|
||||
"BranchUpdate": "Ramificação para atualização do Radarr",
|
||||
"Branch": "Ramo",
|
||||
"Branch": "Ramificação",
|
||||
"BindAddressHelpText": "Endereço IP válido, localhost ou '*' para todas as interfaces",
|
||||
"BindAddress": "Fixar Endereço",
|
||||
"BeforeUpdate": "Antes de atualizar",
|
||||
@@ -350,13 +350,13 @@
|
||||
"AvailabilityDelayHelpText": "Quantidade de tempo antes ou depois da data de disponibilidade para pesquisar pelo filme",
|
||||
"AvailabilityDelay": "Atraso de disponibilidade",
|
||||
"AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Filmes excluídos do disco automaticamente deixam de ser monitorados no Radarr",
|
||||
"AutoRedownloadFailedHelpText": "Procure automaticamente e tente fazer o download de uma versão diferente",
|
||||
"AutomaticSearch": "Pesquisa automática",
|
||||
"AutoRedownloadFailedHelpText": "Procurar automaticamente e tente baixar uma versão diferente",
|
||||
"AutomaticSearch": "Pesquisa Automática",
|
||||
"Automatic": "Automático",
|
||||
"AuthForm": "Formulários (página de entrada)",
|
||||
"AuthForm": "Formulário (Página de login)",
|
||||
"AuthenticationMethodHelpText": "Requer nome de usuário e senha para acessar o Radarr",
|
||||
"Authentication": "Autenticação",
|
||||
"AuthBasic": "Básico (pop-up do navegador)",
|
||||
"AuthBasic": "Básico (Balão do Navegador)",
|
||||
"AudioInfo": "Info do Áudio",
|
||||
"AsAllDayHelpText": "Eventos aparecerão como eventos de dia inteiro em seu calendário",
|
||||
"AptUpdater": "Usar apt para instalar atualizações",
|
||||
@@ -365,7 +365,7 @@
|
||||
"Apply": "Aplicar",
|
||||
"AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData na atualização",
|
||||
"AppDataDirectory": "Diretório AppData",
|
||||
"ApiKey": "Chave da API",
|
||||
"ApiKey": "Chave API",
|
||||
"Announced": "Anunciado",
|
||||
"AnalyticsEnabledHelpText": "Envie informações anônimas de uso e erro para os servidores do Radarr. Isso inclui informações sobre seu navegador, quais páginas da interface Web do Radarr você usa, relatórios de erros, e a versão do sistema operacional e do tempo de execução. Usaremos essas informações para priorizar recursos e correções de bugs.",
|
||||
"AnalyseVideoFiles": "Analisar arquivos de vídeo",
|
||||
@@ -388,29 +388,29 @@
|
||||
"MinutesNinety": "90 minutos: {0}",
|
||||
"MinutesHundredTwenty": "120 minutos: {0}",
|
||||
"Minutes": "Minutos",
|
||||
"MinimumLimits": "Limites mínimos",
|
||||
"MinimumLimits": "Limites Mínimos",
|
||||
"MinimumFreeSpaceWhenImportingHelpText": "Impedir a importação se deixar menos do que esta quantidade de espaço em disco disponível",
|
||||
"MinimumFreeSpace": "Mínimo de espaço livre",
|
||||
"MinimumCustomFormatScore": "Pontuação mínima de formato personalizado",
|
||||
"MinimumAgeHelpText": "Somente Usenet: tempo de vida mínimo, em minutos, dos NZBs, para que sejam capturados. Use isto para dar às novas versões tempo de propagar-se em seu fornecedor de Usenet.",
|
||||
"MinimumAge": "Tempo de vida mínimo",
|
||||
"MinimumFreeSpace": "Espaço Livre Mínimo",
|
||||
"MinimumCustomFormatScore": "Pontuação Mínima de Formato Personalizado",
|
||||
"MinimumAgeHelpText": "Somente Usenet: Idade mínima em minutos dos NZBs antes de serem capturados. Use isso para dar aos novos lançamentos tempo para se propagar para seu provedor usenet.",
|
||||
"MinimumAge": "Idade Miníma",
|
||||
"MinimumAvailability": "Disponibilidade mínima",
|
||||
"MinFormatScoreHelpText": "Pontuação mínima de formato personalizado permitida para download",
|
||||
"MinAvailability": "Disponibilidade mínina",
|
||||
"MetadataSettingsSummary": "Criar arquivos de metadados quando os filmes são importados ou atualizados",
|
||||
"Metadata": "Metadados",
|
||||
"MetadataSettings": "Configurações de metadados",
|
||||
"MetadataSettings": "Configurações de Metadados",
|
||||
"Message": "Mensagem",
|
||||
"MegabytesPerMinute": "Megabytes por minuto",
|
||||
"Medium": "Médio",
|
||||
"MediaManagementSettingsSummary": "Configurações de nomenclatura e gerenciamento de arquivos",
|
||||
"MediaManagement": "Gerenciamento de Mídia",
|
||||
"MediaManagementSettings": "Configurações de gerenciamento de mídia",
|
||||
"MediaManagementSettings": "Configurações de Gerenciamento de Mídia",
|
||||
"MediaInfo": "Informações da mídia",
|
||||
"Mechanism": "Mecanismo",
|
||||
"MaximumSizeHelpText": "Tamanho máximo para um lançamento ser capturado, em MB. Digite zero para definir como ilimitado",
|
||||
"MaximumSize": "Tamanho máximo",
|
||||
"MaximumLimits": "Limites máximos",
|
||||
"MaximumSizeHelpText": "Tamanho máximo para uma liberação a ser capturada em MB. Defina como zero para definir como ilimitado",
|
||||
"MaximumSize": "Tamanho Máximo",
|
||||
"MaximumLimits": "Limites Máximos",
|
||||
"Max": "Máx.",
|
||||
"MassMovieSearch": "Pesquisar filmes em massa",
|
||||
"MarkAsFailed": "Marcar como falhado",
|
||||
@@ -425,10 +425,10 @@
|
||||
"LowerCase": "Minúsculas",
|
||||
"LookingForReleaseProfiles2": "em vez disso.",
|
||||
"LookingForReleaseProfiles1": "Procurando pelos perfis de versões? Tente",
|
||||
"Logs": "Logs",
|
||||
"Logs": "Registros",
|
||||
"LogOnly": "Somente log",
|
||||
"LogLevelTraceHelpTextWarning": "O registro de rastreamento deve ser ativado apenas temporariamente",
|
||||
"LogLevel": "Nível do log",
|
||||
"LogLevel": "Nível de Registro",
|
||||
"LogFiles": "Arquivos de log",
|
||||
"Location": "Localização",
|
||||
"Local": "Local",
|
||||
@@ -458,13 +458,13 @@
|
||||
"AgeWhenGrabbed": "Tempo de vida (quando obtido)",
|
||||
"Agenda": "Programação",
|
||||
"Age": "Idade",
|
||||
"AfterManualRefresh": "Após atualização manual",
|
||||
"AfterManualRefresh": "Depois da Atualização Manual",
|
||||
"AddToDownloadQueue": "Adicionar à fila de download",
|
||||
"AddRootFolder": "Adicionar Pasta Raiz",
|
||||
"AddRestriction": "Adicionar restrição",
|
||||
"AddRemotePathMapping": "Adicionar mapeamento de caminho remoto",
|
||||
"AddQualityProfile": "Adicionar perfil de qualidade",
|
||||
"AddNotification": "Adicionar notificação",
|
||||
"AddRemotePathMapping": "Adicionar Mapeamento de Caminho Remoto",
|
||||
"AddQualityProfile": "Adicionar Perfil de Qualidade",
|
||||
"AddNotification": "Adicionar Notificação",
|
||||
"AddNewTmdbIdMessage": "Você também pode pesquisar usando a ID do TMDb de um filme. Por exemplo, \"tmdb:71663\"",
|
||||
"AddNewMovie": "Adicionar novo filme",
|
||||
"AddNewMessage": "É fácil adicionar um novo filme, basta começar a digitar o nome do filme que deseja acrescentar",
|
||||
@@ -474,20 +474,20 @@
|
||||
"AddListExclusion": "Adicionar exclusão à lista",
|
||||
"AddList": "Adicionar Lista",
|
||||
"AddingTag": "Adicionar tag",
|
||||
"AddIndexer": "Adicionar indexador",
|
||||
"AddIndexer": "Adicionar Indexador",
|
||||
"AddImportExclusionHelpText": "Impedir a adição do filme ao Radarr por listas",
|
||||
"AddExclusion": "Adicionar exclusão",
|
||||
"AddExclusion": "Adicionar Exclusão",
|
||||
"AddedToDownloadQueue": "Adicionado à fila de download",
|
||||
"Added": "Adicionado",
|
||||
"AddDownloadClient": "Adicionar cliente de download",
|
||||
"AddDelayProfile": "Adicionar perfil de atraso",
|
||||
"AddCustomFormat": "Adicionar formato personalizado",
|
||||
"AddDownloadClient": "Adicionar Cliente de Download",
|
||||
"AddDelayProfile": "Adicionar Perfil de Atraso",
|
||||
"AddCustomFormat": "Adicionar Formato Personalizado",
|
||||
"Add": "Adicionar",
|
||||
"Activity": "Atividade",
|
||||
"Actions": "Ações",
|
||||
"AcceptConfirmationModal": "Aceitar o pop-up de confirmação",
|
||||
"About": "Sobre",
|
||||
"Analytics": "Análises",
|
||||
"Analytics": "Analítica",
|
||||
"Month": "Mês",
|
||||
"MovieYearHelpText": "O ano do filme a excluir",
|
||||
"MovieYear": "Ano do filme",
|
||||
@@ -529,25 +529,25 @@
|
||||
"MoreControlCFText": "Quer mais controle sobre quais downloads são preferidos? Adicione um",
|
||||
"Months": "Meses",
|
||||
"Min": "Mín.",
|
||||
"Logging": "Registro em log",
|
||||
"Logging": "Registrando",
|
||||
"NegateHelpText": "Se marcado, o formato personalizado não será aplicado se esta condição {0} corresponder.",
|
||||
"Negated": "Negado",
|
||||
"Negate": "Negar",
|
||||
"NamingSettings": "Configurações de nomenclatura",
|
||||
"NamingSettings": "Configurações de Nomes",
|
||||
"Name": "Nome",
|
||||
"MustNotContain": "Não deve conter",
|
||||
"MustContain": "Deve conter",
|
||||
"MustNotContain": "Não Deve Conter",
|
||||
"MustContain": "Deve Conter",
|
||||
"MultiLanguage": "Vários idiomas",
|
||||
"View": "Exibir",
|
||||
"Week": "Semana",
|
||||
"WeekColumnHeader": "Cabeçalho da coluna da semana",
|
||||
"WeekColumnHeader": "Cabeçalho da Coluna da Semana",
|
||||
"Weeks": "Semanas",
|
||||
"Wiki": "Wiki",
|
||||
"Year": "Ano",
|
||||
"YesCancel": "Sim, Cancelar",
|
||||
"YesMoveFiles": "Sim, Mover os Arquivos",
|
||||
"YouCanAlsoSearch": "Você também pode pesquisar usando TMDb ID ou IMDb ID de um filme. Por exemplo: `tmdb: 71663`",
|
||||
"NoMatchFound": "Nenhuma correspondência encontrada",
|
||||
"NoMatchFound": "Nenhum resultado encontrado!",
|
||||
"NoLogFiles": "Nenhum arquivo de log",
|
||||
"NoListRecommendations": "Não foram encontrados itens da lista ou recomendações. Para começar, adicione um novo filme, importe alguns existentes ou adicione uma lista.",
|
||||
"NoLinks": "Sem Links",
|
||||
@@ -555,7 +555,7 @@
|
||||
"NoLeaveIt": "Não, deixe-o",
|
||||
"NoHistory": "Não há histórico",
|
||||
"NoEventsFound": "Nenhum evento encontrado",
|
||||
"NoChanges": "Sem alterações",
|
||||
"NoChanges": "Sem Alterações",
|
||||
"NoChange": "Sem alteração",
|
||||
"NoBackupsAreAvailable": "Não há backups disponíveis",
|
||||
"NoAltTitle": "Nenhum título alternativo.",
|
||||
@@ -570,23 +570,23 @@
|
||||
"RootFolderCheckSingleMessage": "Pasta raiz ausente: {0}",
|
||||
"RootFolderCheckMultipleMessage": "Faltam várias pastas raiz: {0}",
|
||||
"RetryingDownloadInterp": "Tentando novamente o download {0} em {1}",
|
||||
"RetentionHelpText": "Apenas Usenet: use 0 para definir para retenção ilimitada",
|
||||
"RetentionHelpText": "Somente Usenet: defina como zero para definir a retenção ilimitada",
|
||||
"RestartReloadNote": "Observação: o Radarr reiniciará automaticamente e recarregará a interface durante o processo de restauração.",
|
||||
"RejectionCount": "Número de rejeição",
|
||||
"Redownload": "Baixar novamente",
|
||||
"UpgradeAllowedHelpText": "Se desabilitada, as qualidades não serão atualizadas",
|
||||
"UpgradesAllowed": "Atualizações Permitidas",
|
||||
"UpgradeUntilCustomFormatScore": "Atualizar até a pontuação do formato personalizado",
|
||||
"UpgradeUntilThisQualityIsMetOrExceeded": "Atualizar até que essa qualidade seja alcançada ou excedida",
|
||||
"UpgradeUntilCustomFormatScore": "Atualizar até pontuação de formato personalizado",
|
||||
"UpgradeUntilThisQualityIsMetOrExceeded": "Atualize até que essa qualidade seja atendida ou excedida",
|
||||
"UpgradeUntilQuality": "Atualizar até a qualidade",
|
||||
"UpperCase": "Maiúsculas",
|
||||
"URLBase": "URL base",
|
||||
"UrlBaseHelpText": "Para suporte de proxy reverso, o padrão é vazio",
|
||||
"UseHardlinksInsteadOfCopy": "Usar Vínculos reais em vez de Copiar",
|
||||
"UrlBaseHelpText": "Para suporte a proxy reverso, o padrão é vazio",
|
||||
"UseHardlinksInsteadOfCopy": "Usar links rígidos ao invés de Copiar",
|
||||
"Usenet": "Usenet",
|
||||
"UsenetDisabled": "Usenet desabilitada",
|
||||
"UseProxy": "Usar proxy",
|
||||
"Username": "Nome de usuário",
|
||||
"UsenetDisabled": "Usenet Desabilitada",
|
||||
"UseProxy": "Usar Proxy",
|
||||
"Username": "Nome do usuário",
|
||||
"Version": "Versão",
|
||||
"VideoCodec": "Codec de Vídeo",
|
||||
"WaitingToProcess": "Aguardando para processar",
|
||||
@@ -605,15 +605,15 @@
|
||||
"UILanguageHelpText": "Idioma que o Radarr usará para a interface",
|
||||
"TotalSpace": "Espaço Total",
|
||||
"TotalFileSize": "Tamanho total do arquivo",
|
||||
"TorrentsDisabled": "Torrents desabilitados",
|
||||
"TorrentDelayHelpText": "Atraso, em minutos, para aguardar antes de obter um torrent",
|
||||
"TorrentDelay": "Atraso do torrent",
|
||||
"TorrentsDisabled": "Torrents Desabilitados",
|
||||
"TorrentDelayHelpText": "Demora em minutos para esperar antes de pegar um torrent",
|
||||
"TorrentDelay": "Atraso do Torrent",
|
||||
"Tomorrow": "Amanhã",
|
||||
"Today": "Hoje",
|
||||
"Titles": "Títulos",
|
||||
"Title": "Título",
|
||||
"Timeleft": "Tempo restante",
|
||||
"TimeFormat": "Formato de hora",
|
||||
"TimeFormat": "Formato da Hora",
|
||||
"Time": "Horário",
|
||||
"ThisCannotBeCancelled": "Isso não pode ser cancelado uma vez iniciado sem desabilitar todos os seus indexadores.",
|
||||
"TheLogLevelDefault": "O nível de registro é padronizado como \"Informações\" e pode ser alterado em",
|
||||
@@ -623,10 +623,10 @@
|
||||
"TestAll": "Testar Tudo",
|
||||
"Test": "Testar",
|
||||
"Tasks": "Tarefas",
|
||||
"TagsSettingsSummary": "Veja todas as tags e como são usadas. Tags não utilizadas podem ser removidas",
|
||||
"TagsSettingsSummary": "Veja todas as tags e como elas são usadas. Tags não utilizadas podem ser removidas",
|
||||
"TagsHelpText": "Aplica-se a filmes com pelo menos uma tag correspondente",
|
||||
"Tags": "Tags",
|
||||
"TagIsNotUsedAndCanBeDeleted": "A tag não está em uso e pode ser excluída",
|
||||
"TagIsNotUsedAndCanBeDeleted": "A tag não é usada e pode ser excluída",
|
||||
"TagDetails": "Detalhes da tag: {0}",
|
||||
"TagCannotBeDeletedWhileInUse": "Não pode ser excluído durante o uso",
|
||||
"TableOptionsColumnsMessage": "Escolha quais colunas são visíveis e em que ordem aparecem",
|
||||
@@ -643,8 +643,8 @@
|
||||
"StartupDirectory": "Diretório de inicialização",
|
||||
"StartTypingOrSelectAPathBelow": "Comece a digitar ou selecione um caminho abaixo",
|
||||
"StartSearchForMissingMovie": "Iniciar a pesquisa pelo filme ausente",
|
||||
"StartProcessing": "Iniciar processamento",
|
||||
"StartImport": "Iniciar importação",
|
||||
"StartProcessing": "Iniciar Processamento",
|
||||
"StartImport": "Iniciar Importação",
|
||||
"StandardMovieFormat": "Formato de filme padrão",
|
||||
"SSLPort": "Porta SSL",
|
||||
"SourceTitle": "Título da Fonte",
|
||||
@@ -654,7 +654,7 @@
|
||||
"Sort": "Classificar",
|
||||
"SorryThatMovieCannotBeFound": "Desculpe, esse filme não pode ser encontrado.",
|
||||
"SomeResultsHiddenFilter": "Alguns resultados estão ocultos pelo filtro aplicado",
|
||||
"Socks5": "Socks5 (suporte ao TOR)",
|
||||
"Socks5": "Socks5 (Suporte à TOR)",
|
||||
"Small": "Pequeno",
|
||||
"SkipFreeSpaceCheckWhenImportingHelpText": "Use quando o Radarr não conseguir detectar espaço livre na pasta raiz do filme",
|
||||
"SkipFreeSpaceCheck": "Ignorar verificação de espaço livre",
|
||||
@@ -698,9 +698,9 @@
|
||||
"SettingsFirstDayOfWeek": "Primeiro dia da semana",
|
||||
"Settings": "Configurações",
|
||||
"SetTags": "Definir etiquetas",
|
||||
"SetPermissionsLinuxHelpTextWarning": "Se você não tem certeza do que essas configurações fazem, não as altere.",
|
||||
"SetPermissionsLinuxHelpTextWarning": "Se você não tiver certeza do que essas configurações fazem, não as altere.",
|
||||
"SetPermissionsLinuxHelpText": "O chmod deve ser executado quando os arquivos são importados/renomeados?",
|
||||
"SetPermissions": "Definir permissões",
|
||||
"SetPermissions": "Definir Permissões",
|
||||
"SendAnonymousUsageData": "Enviar dados de uso anônimos",
|
||||
"SelectQuality": "Selecionar qualidade",
|
||||
"SelectMovie": "Selecionar filme",
|
||||
@@ -722,11 +722,11 @@
|
||||
"SearchCutoffUnmet": "Pesquisar Limite não atingido",
|
||||
"SearchAll": "Pesquisar tudo",
|
||||
"Search": "Pesquisar",
|
||||
"ScriptPath": "Caminho do script",
|
||||
"ScriptPath": "Caminho do Script",
|
||||
"Score": "Pontuação",
|
||||
"Scheduled": "Agendado",
|
||||
"SaveSettings": "Salvar configurações",
|
||||
"SaveChanges": "Salvar alterações",
|
||||
"SaveSettings": "Salvar Configurações",
|
||||
"SaveChanges": "Salvar Mudanças",
|
||||
"Save": "Salvar",
|
||||
"Runtime": "Duração",
|
||||
"RSSSyncInterval": "Intervalo da sincronização RSS",
|
||||
@@ -740,11 +740,11 @@
|
||||
"Restrictions": "Restrições",
|
||||
"RestoreBackup": "Restaurar backup",
|
||||
"Restore": "Restaurar",
|
||||
"RestartRequiredHelpTextWarning": "Requer reinicialização para ter efeito",
|
||||
"RestartRequiredHelpTextWarning": "Requer reinicialização para entrar em vigor",
|
||||
"RestartRadarr": "Reiniciar o Radarr",
|
||||
"RestartNow": "Reiniciar agora",
|
||||
"RestartNow": "Reiniciar Agora",
|
||||
"Restart": "Reiniciar",
|
||||
"ResetAPIKey": "Redefinir chave da API",
|
||||
"ResetAPIKey": "Redefinir chave de API",
|
||||
"Reset": "Redefinir",
|
||||
"RescanMovieFolderAfterRefresh": "Verificar novamente a pasta do filme após atualizar",
|
||||
"RescanAfterRefreshHelpTextWarning": "O Radarr não detectará automaticamente as alterações nos arquivos se não estiver definido como \"Sempre\"",
|
||||
@@ -753,9 +753,9 @@
|
||||
"RequiredRestrictionHelpText": "A versão deve conter pelo menos um desses termos (não diferencia maiúsculas de minúsculas)",
|
||||
"Required": "Requerido",
|
||||
"ReplaceIllegalCharactersHelpText": "Substituir caracteres ilegais. Se desmarcada, o Radarr irá removê-los",
|
||||
"ReplaceIllegalCharacters": "Substituir caracteres ilegais",
|
||||
"ReplaceIllegalCharacters": "Substituir Caracteres Ilegais",
|
||||
"Replace": "Substituir",
|
||||
"Reorder": "Reorganizar",
|
||||
"Reorder": "Reordenar",
|
||||
"RenameMoviesHelpText": "O Radarr usará o nome de arquivo existente se a renomeação estiver desativada",
|
||||
"RenameMovies": "Renomear filmes",
|
||||
"RenameFiles": "Renomear Arquivos",
|
||||
@@ -770,13 +770,13 @@
|
||||
"RemoveFromQueue": "Remover da fila",
|
||||
"RemoveFromDownloadClient": "Remover Do Cliente de Download",
|
||||
"RemoveFilter": "Remover filtro",
|
||||
"RemoveFailedDownloadsHelpText": "Remover downloads com falha do histórico do cliente de download",
|
||||
"RemoveFailedDownloadsHelpText": "Remova downloads com falha do histórico do cliente de download",
|
||||
"RemovedMovieCheckSingleMessage": "O filme {0} foi removido do TMDb",
|
||||
"RemovedMovieCheckMultipleMessage": "Os filmes {0} foram removidos do TMDb",
|
||||
"RemovedFromTaskQueue": "Removido da fila de tarefas",
|
||||
"RemoveCompletedDownloadsHelpText": "Remover downloads importados do histórico do cliente de download",
|
||||
"Remove": "Remover",
|
||||
"RemotePathMappings": "Mapeamentos de caminho remoto",
|
||||
"RemotePathMappings": "Mapeamentos de Caminho Remoto",
|
||||
"Reload": "Recarregar",
|
||||
"ReleaseWillBeProcessedInterp": "A versão será processada {0}",
|
||||
"ReleaseTitle": "Título do Lançamento",
|
||||
@@ -793,7 +793,7 @@
|
||||
"RefreshInformationAndScanDisk": "Atualizar as informações e verificar o disco",
|
||||
"RefreshAndScan": "Atualizar & Escanear",
|
||||
"Refresh": "Atualizar",
|
||||
"RecyclingBinCleanup": "Esvaziar lixeira",
|
||||
"RecyclingBinCleanup": "Esvaziar Lixeira",
|
||||
"RecyclingBin": "Lixeira",
|
||||
"RecycleBinHelpText": "Arquivos de filme virão para cá quando excluídos, em vez de serem apagados permanentemente",
|
||||
"RecycleBinCleanupDaysHelpTextWarning": "Os arquivos na lixeira mais antigos do que o número de dias selecionado serão limpos automaticamente",
|
||||
@@ -832,59 +832,59 @@
|
||||
"Queued": "Enfileirados",
|
||||
"Queue": "Fila",
|
||||
"QualitySettingsSummary": "Tamanhos de qualidade e nomenclatura",
|
||||
"QualitySettings": "Configurações de qualidade",
|
||||
"QualityProfiles": "Perfis de qualidade",
|
||||
"QualitySettings": "Configurações de Qualidade",
|
||||
"QualityProfiles": "Perfis de Qualidade",
|
||||
"QualityProfileInUse": "Não é possível excluir um perfil de qualidade anexado a um filme, lista ou coleção",
|
||||
"QualityProfileDeleteConfirm": "Tem certeza que deseja excluir o perfil de qualidade {0}",
|
||||
"QualityProfile": "Perfil de Qualidade",
|
||||
"QualityOrLangCutoffHasNotBeenMet": "Limite de qualidade ou de idioma não atingido",
|
||||
"QualityLimitsHelpText": "Os limites são ajustados automaticamente para o tempo de execução do filme.",
|
||||
"QualityDefinitions": "Definições de qualidade",
|
||||
"QualityDefinitions": "Definições de Qualidade",
|
||||
"QualityCutoffHasNotBeenMet": "Limite de qualidade não atingido",
|
||||
"Quality": "Qualidade",
|
||||
"QualitiesHelpText": "As qualidades mais altas na lista são mais preferidas, mesmo que não sejam verificadas. As qualidades dentro do mesmo grupo são iguais. Somente qualidades verificadas são desejadas",
|
||||
"Qualities": "Qualidades",
|
||||
"PublishedDate": "Data de publicação",
|
||||
"PtpOldSettingsCheckMessage": "As configurações dos seguintes indexadores do PassThePopcorn são obsoletas e devem ser atualizadas: {0}",
|
||||
"ProxyUsernameHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.",
|
||||
"ProxyType": "Tipo de proxy",
|
||||
"ProxyPasswordHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.",
|
||||
"ProxyUsernameHelpText": "Você só precisa digitar um nome de usuário e senha se for necessário. Caso contrário, deixe-os em branco.",
|
||||
"ProxyType": "Tipo de Proxy",
|
||||
"ProxyPasswordHelpText": "Você só precisa digitar um nome de usuário e senha se for necessário. Caso contrário, deixe-os em branco.",
|
||||
"ProxyCheckResolveIpMessage": "Falha ao resolver o endereço IP do host de proxy configurado {0}",
|
||||
"ProxyCheckFailedToTestMessage": "Falha ao testar o proxy: {0}",
|
||||
"ProxyCheckBadRequestMessage": "Falha ao testar o proxy. Código de status: {0}",
|
||||
"ProxyBypassFilterHelpText": "Usar \",\" como separador e \"*.\" como curinga para subdomínios",
|
||||
"ProxyBypassFilterHelpText": "Use ',' como separador e '*.' como curinga para subdomínios",
|
||||
"Proxy": "Proxy",
|
||||
"ProtocolHelpText": "Escolha que protocolo(s) utilizar e qual o preferido ao escolher entre versões iguais",
|
||||
"ProtocolHelpText": "Escolha qual(is) protocolo(s) usar e qual é o preferido ao escolher entre laçamentos iguais",
|
||||
"Protocol": "Protocolo",
|
||||
"Proper": "Proper",
|
||||
"Progress": "Progresso",
|
||||
"ProfilesSettingsSummary": "Perfis de qualidade, idioma e atraso",
|
||||
"Profiles": "Perfis",
|
||||
"ProcessingFolders": "Processando pastas",
|
||||
"ProcessingFolders": "Processando Pastas",
|
||||
"PrioritySettings": "Prioridade: {0}",
|
||||
"PriorityHelpText": "Priorizar vários clientes de download. Usamos um rodízio para clientes com a mesma prioridade.",
|
||||
"PriorityHelpText": "Priorize vários clientes de download. Round-Robin é usado para clientes com a mesma prioridade.",
|
||||
"Priority": "Prioridade",
|
||||
"PreviewRenameHelpText": "Dica: ao visualizar uma renomeação, selecione \"Cancelar\", clique em qualquer título de filme e use o(a)",
|
||||
"PreviewRename": "Visualizar renomeação",
|
||||
"Presets": "Predefinições",
|
||||
"Presets": "Definições",
|
||||
"PreferUsenet": "Preferir Usenet",
|
||||
"PreferTorrent": "Preferir torrent",
|
||||
"PreferredSize": "Tamanho preferido",
|
||||
"PreferTorrent": "Preferir Torrent",
|
||||
"PreferredSize": "Tamanho Preferido",
|
||||
"Preferred": "Preferido",
|
||||
"PreferIndexerFlagsHelpText": "Priorizar versões com sinalizadores especiais",
|
||||
"PreferIndexerFlags": "Preferir sinalizadores de indexador",
|
||||
"PreferAndUpgrade": "Preferir e atualizar",
|
||||
"PreferAndUpgrade": "Preferir e Atualizar",
|
||||
"PosterSize": "Tamanho do pôster",
|
||||
"Posters": "Pôsteres",
|
||||
"PosterOptions": "Opções do pôster",
|
||||
"PortNumber": "Número da porta",
|
||||
"PortNumber": "Número da Porta",
|
||||
"Port": "Porta",
|
||||
"PhysicalReleaseDate": "Data da versão física",
|
||||
"PhysicalRelease": "Versão física",
|
||||
"Permissions": "Permissões",
|
||||
"PendingChangesStayReview": "Ficar e revisar alterações",
|
||||
"PendingChangesMessage": "Há alterações não salvas. Tem certeza que deseja sair desta página?",
|
||||
"PendingChangesDiscardChanges": "Descartar alterações e sair",
|
||||
"PendingChangesStayReview": "Ficar e revisar mudanças",
|
||||
"PendingChangesMessage": "Você tem alterações não salvas. Tem certeza de que deseja sair desta página?",
|
||||
"PendingChangesDiscardChanges": "Descartar mudanças e sair",
|
||||
"Pending": "Pendente",
|
||||
"Peers": "Pares",
|
||||
"Paused": "Pausado",
|
||||
@@ -910,31 +910,31 @@
|
||||
"OnUpgradeHelpText": "Ao atualizar",
|
||||
"OnRenameHelpText": "Ao renomear",
|
||||
"OnRename": "Ao Renomear",
|
||||
"OnlyUsenet": "Apenas Usenet",
|
||||
"OnlyTorrent": "Apenas Torrents",
|
||||
"OnlyUsenet": "Só Usenet",
|
||||
"OnlyTorrent": "Só Torrent",
|
||||
"OnLatestVersion": "A versão mais recente do Sonarr já está instalada",
|
||||
"OnImport": "Ao importar",
|
||||
"OnImport": "Ao Importar",
|
||||
"OnHealthIssueHelpText": "Ao ter problema de integridade",
|
||||
"OnHealthIssue": "Em Problema de Saúde",
|
||||
"OnHealthIssue": "Ao Problema de Saúde",
|
||||
"OnGrabHelpText": "Ao obter",
|
||||
"OnGrab": "Ao obter",
|
||||
"OnGrab": "Ao Baixar",
|
||||
"OnDownloadHelpText": "Ao importar",
|
||||
"Ok": "Ok",
|
||||
"OAuthPopupMessage": "Os pop-ups estão bloqueados em seu navegador",
|
||||
"NoVideoFilesFoundSelectedFolder": "Não há arquivos de vídeo na pasta selecionada",
|
||||
"NoUpdatesAreAvailable": "Nenhuma atualização está disponível",
|
||||
"NotMonitored": "Não monitorado",
|
||||
"NotificationTriggers": "Acionadores da notificação",
|
||||
"NotificationTriggers": "Gatilhos de Notificação",
|
||||
"NotAvailable": "Indisponível",
|
||||
"NoTagsHaveBeenAddedYet": "Você ainda não adicionou tags",
|
||||
"NoTagsHaveBeenAddedYet": "Nenhuma tag foi adicionada ainda",
|
||||
"NoResultsFound": "Nenhum resultado encontrado",
|
||||
"None": "Nenhum",
|
||||
"None": "Vazio",
|
||||
"NoMoviesExist": "Nenhum filme encontrado. Para começar, adicione um novo filme ou importe alguns existentes.",
|
||||
"NoMoveFilesSelf": " Não, eu mesmo moverei os arquivos",
|
||||
"NoMinimumForAnyRuntime": "Sem mínimo para qualquer tempo de execução",
|
||||
"ReplaceWithSpaceDashSpace": "Substituir com Espaço e Traço e Espaço",
|
||||
"ReplaceWithSpaceDash": "Substituir com Espaço e Traço",
|
||||
"ReplaceWithDash": "Substituir por traço",
|
||||
"ReplaceWithSpaceDashSpace": "Substituir com Espaço, Traço e Espaço",
|
||||
"ReplaceWithSpaceDash": "Substituir por Espaço e Traço",
|
||||
"ReplaceWithDash": "Substituir por Traço",
|
||||
"ReleaseBranchCheckOfficialBranchMessage": "A ramificação {0} não é de uma versão válida para o Radarr, você não receberá atualizações",
|
||||
"RequiredHelpText": "Esta condição {0} deve ser correspondida para aplicar o formato personalizado. Caso contrário, uma única correspondência de {1} é suficiente.",
|
||||
"WouldYouLikeToRestoreBackup": "Gostaria de restaurar o backup {0}?",
|
||||
@@ -943,7 +943,7 @@
|
||||
"Warn": "Alerta",
|
||||
"VersionUpdateText": "A versão {0} do Radarr foi instalada. Para obter as alterações mais recentes, recarregue o Radarr.",
|
||||
"UsenetDelayTime": "Atraso da Usenet: {0}",
|
||||
"UsenetDelayHelpText": "Tempo, em minutos, para aguardar antes de capturar uma versão de Usenet",
|
||||
"UsenetDelayHelpText": "Atraso em minutos para esperar antes de pegar um lançamento da Usenet",
|
||||
"UsenetDelay": "Atraso da Usenet",
|
||||
"Uptime": "Tempo de atividade",
|
||||
"UpdateSelected": "Atualizar Selecionada",
|
||||
@@ -953,10 +953,10 @@
|
||||
"UpdateCheckUINotWritableMessage": "Não é possível instalar a atualização porque a pasta de IU '{0}' não pode ser gravada pelo usuário '{1}'.",
|
||||
"UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' está em uma pasta de translocação de aplicativo.",
|
||||
"UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' não pode ser gravada pelo usuário '{1}'.",
|
||||
"UpdateAutomaticallyHelpText": "Baixar e instalar atualizações automaticamente. Você ainda poderá instalar a partir de Sistema: Atualizações",
|
||||
"UpdateAutomaticallyHelpText": "Baixe e instale atualizações automaticamente. Você ainda poderá instalar a partir do Sistema: Atualizações",
|
||||
"UpdateAll": "Atualizar tudo",
|
||||
"UnselectAll": "Deselecionar Todos",
|
||||
"UnsavedChanges": "Alterações não salvas",
|
||||
"UnsavedChanges": "Alterações Não Salvas",
|
||||
"Unreleased": "Inédito",
|
||||
"UnmonitoredHelpText": "Incluir filmes não monitorados no feed do iCal",
|
||||
"Unmonitored": "Não monitorado",
|
||||
@@ -1008,10 +1008,10 @@
|
||||
"SettingsEnableColorImpairedModeHelpText": "Estilo alterado para permitir que usuários com daltonismo distingam melhor as informações codificadas por cores",
|
||||
"SettingsEnableColorImpairedMode": "Habilitar modo para daltonismo",
|
||||
"LastDuration": "Última Duração",
|
||||
"Trace": "Rastreamento",
|
||||
"Trace": "Traço",
|
||||
"ImportNotForDownloads": "Não use para importar downloads de seu cliente. Isso se aplica apenas a bibliotecas organizadas existentes, e não para arquivos não classificados.",
|
||||
"ImportLibrary": "Importar biblioteca",
|
||||
"DefaultCase": "Capitalização padrão",
|
||||
"DefaultCase": "Minúscula ou maiúscula",
|
||||
"ChooseAnotherFolder": "Escolher outra pasta",
|
||||
"MIA": "Desaparecidos",
|
||||
"SqliteVersionCheckUpgradeRequiredMessage": "A versão {0} do SQLite instalada atualmente não é mais compatível. Atualize o SQLite para pelo menos a versão {1}.",
|
||||
@@ -1023,7 +1023,7 @@
|
||||
"OnMovieFileDeleteHelpText": "Ao excluir arquivo de filme",
|
||||
"OnMovieFileDeleteForUpgrade": "Ao excluir arquivo de filme para atualizar",
|
||||
"OnMovieFileDeleteForUpgradeHelpText": "Ao excluir arquivo de filme para atualizar",
|
||||
"OnUpgrade": "Ao Melhorar Versão",
|
||||
"OnUpgrade": "Ao Atualizar",
|
||||
"OnMovieDelete": "Ao excluir filme",
|
||||
"Reddit": "Reddit",
|
||||
"More": "Mais",
|
||||
@@ -1048,12 +1048,12 @@
|
||||
"RemotePathMappingCheckBadDockerPath": "Você está usando o docker; cliente de download {0} coloca downloads em {1}, mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e baixe as configurações do cliente.",
|
||||
"ImportListMultipleMissingRoots": "Várias pastas raiz estão ausentes para listas de importação: {0}",
|
||||
"ImportListMissingRoot": "Pasta raiz ausente para lista(s) de importação: {0}",
|
||||
"BypassDelayIfHighestQualityHelpText": "Ignorar o atraso quando a versão tiver a qualidade mais alta habilitada no perfil de qualidade com o protocolo preferido",
|
||||
"BypassDelayIfHighestQuality": "Ignorar se for a qualidade mais alta",
|
||||
"BypassDelayIfHighestQualityHelpText": "Ignorar o atraso quando o lançamento tiver a qualidade mais alta habilitada no perfil de qualidade com o protocolo preferencial",
|
||||
"BypassDelayIfHighestQuality": "Ignorar se a qualidade é mais alta",
|
||||
"From": "de",
|
||||
"Letterboxd": "Letterboxd",
|
||||
"TaskUserAgentTooltip": "User-Agent fornecido pelo aplicativo que chamou a API",
|
||||
"NotificationTriggersHelpText": "Selecionar quais eventos devem acionar esta notificação",
|
||||
"NotificationTriggersHelpText": "Selecione quais eventos devem acionar esta notificação",
|
||||
"UnableToAddRootFolder": "Incapaz de adicionar pasta raiz",
|
||||
"Blocklisted": "Bloqueado",
|
||||
"Blocklist": "Lista de Bloqueio",
|
||||
@@ -1068,11 +1068,11 @@
|
||||
"RemoveFailed": "Falha na remoção",
|
||||
"RemoveCompleted": "Remoção Concluída",
|
||||
"RemoveDownloadsAlert": "As configurações de remoção foram movidas para as configurações individuais do cliente de download na tabela acima.",
|
||||
"OnApplicationUpdate": "Ao atualizar o aplicativo",
|
||||
"OnApplicationUpdate": "Na Atualização do Aplicativo",
|
||||
"OnApplicationUpdateHelpText": "Ao atualizar o aplicativo",
|
||||
"DiscordUrlInSlackNotification": "Você tem uma notificação do Discord configurado como uma notificação do Slack. Definir isso como uma notificação do Discord para melhor funcionalidade. Com efeito, notificações são: {0}",
|
||||
"AnnouncedMsg": "Filme foi anunciado",
|
||||
"IndexerDownloadClientHelpText": "Especifique qual cliente de download é usado para capturas deste indexador",
|
||||
"IndexerDownloadClientHelpText": "Especifique qual cliente de download é usado para baixar deste indexador",
|
||||
"LocalPath": "Caminho Local",
|
||||
"ManualImportSetReleaseGroup": "Importar Manual - Definir Grupo de Lançamento",
|
||||
"SelectLanguages": "Selecionar Idiomas",
|
||||
@@ -1081,7 +1081,7 @@
|
||||
"ClickToChangeReleaseGroup": "Clique para alterar o grupo do lançamento",
|
||||
"Filters": "Filtros",
|
||||
"RemotePath": "Caminho Remoto",
|
||||
"SizeLimit": "Tamanho limite",
|
||||
"SizeLimit": "Limite de Tamanho",
|
||||
"ImdbRating": "Avaliação no IMDb",
|
||||
"TmdbRating": "Avaliação no TMDb",
|
||||
"TmdbVotes": "Votos no TMDb",
|
||||
@@ -1099,8 +1099,8 @@
|
||||
"Database": "Banco de dados",
|
||||
"RefreshMonitoredIntervalHelpText": "Com que frequência atualizar downloads monitorados de clientes de download, no mínimo 1 minuto",
|
||||
"RssSyncHelpText": "Intervalo em minutos. Defina como zero para desabilitar (isso interromperá todas as capturas de liberação automática)",
|
||||
"InstanceName": "Nome da instância",
|
||||
"InstanceNameHelpText": "Nome da instância na guia e para o nome do aplicativo do Syslog",
|
||||
"InstanceName": "Nome da Instância",
|
||||
"InstanceNameHelpText": "Nome da instância na aba e para o nome do aplicativo Syslog",
|
||||
"AllCollectionsHiddenDueToFilter": "Todos os filmes estão ocultos devido ao filtro aplicado.",
|
||||
"Collections": "Coleções",
|
||||
"MonitorMovies": "Monitorar Filmes",
|
||||
@@ -1129,7 +1129,7 @@
|
||||
"CollectionShowPostersHelpText": "Mostrar pôsteres de itens da coleção",
|
||||
"RottenTomatoesRating": "Avaliação Tomato",
|
||||
"TotalMovies": "Total de Filmes",
|
||||
"ApplicationURL": "URL do aplicativo",
|
||||
"ApplicationURL": "URL do Aplicativo",
|
||||
"ApplicationUrlHelpText": "A URL externa deste aplicativo, incluindo http(s)://, porta e base da URL",
|
||||
"PreferredProtocol": "Protocolo Preferido",
|
||||
"SettingsThemeHelpText": "Alterar o tema da interface do usuário do aplicativo, o tema 'Auto' usará o tema do sistema operacional para definir o modo Claro ou Escuro. Inspirado por Theme.Park",
|
||||
@@ -1153,11 +1153,11 @@
|
||||
"ShowCinemaReleaseHelpText": "Mostrar data de lançamento do cinema sob o pôster",
|
||||
"OnHealthRestored": "Com a Saúde Restaurada",
|
||||
"OnHealthRestoredHelpText": "Com a Saúde Restaurada",
|
||||
"OnManualInteractionRequired": "Uma Interação Manual é Necessária",
|
||||
"OnManualInteractionRequired": "Na Interação Manual Necessária",
|
||||
"OnManualInteractionRequiredHelpText": "Uma Interação Manual é Necessária",
|
||||
"ApiKeyValidationHealthCheckMessage": "Atualize sua chave de API para ter pelo menos {0} caracteres. Você pode fazer isso através das configurações ou do arquivo de configuração",
|
||||
"ImportScriptPath": "Caminho do script de importação",
|
||||
"ImportUsingScript": "Importar usando script",
|
||||
"ImportScriptPath": "Importar Caminho do Script",
|
||||
"ImportUsingScript": "Importar Usando o Script",
|
||||
"RemoveCompletedDownloads": "Remover downloads concluídos",
|
||||
"RemoveFailedDownloads": "Remover downloads com falha",
|
||||
"ScriptImportPathHelpText": "O caminho para o script a ser usado para importar",
|
||||
@@ -1237,5 +1237,6 @@
|
||||
"UnableToLoadAutoTagging": "Não foi possível carregar a marcação automática",
|
||||
"DeleteRootFolder": "Excluir Pasta Raiz",
|
||||
"DeleteRootFolderMessageText": "Tem certeza de que deseja excluir a pasta raiz '{0}'?",
|
||||
"RootFolderPath": "Caminho da Pasta Raiz"
|
||||
"RootFolderPath": "Caminho da Pasta Raiz",
|
||||
"IndexerDownloadClientHealthCheckMessage": "Indexadores com clientes de download inválidos: {0}."
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"AddNewMessage": "Este ușor să adaugi un film nou, începe să tastezi numele filmului pe care vrei să-l adaugi",
|
||||
"AddNew": "Adaugă nou",
|
||||
"AddMovies": "Adaugă Filme",
|
||||
"AddExclusion": "Adaugă Excluziune",
|
||||
"AddExclusion": "Adaugă excludere",
|
||||
"Added": "Adăugat",
|
||||
"Activity": "Activitate",
|
||||
"Actions": "Acțiuni",
|
||||
@@ -387,7 +387,7 @@
|
||||
"Pending": "In asteptarea",
|
||||
"AvailabilityDelayHelpText": "Suma de timp înainte sau după data disponibilă pentru căutarea filmului",
|
||||
"Announced": "Anunțat",
|
||||
"AddRemotePathMapping": "Adăugați maparea căilor la distanță",
|
||||
"AddRemotePathMapping": "Adăugați mapare a căilor la distanță",
|
||||
"BackupRetentionHelpText": "Copiile de rezervă automate mai vechi decât perioada de păstrare vor fi curățate automat",
|
||||
"Backups": "Copii de rezervă",
|
||||
"BeforeUpdate": "Înainte de actualizare",
|
||||
@@ -426,9 +426,9 @@
|
||||
"AllFiles": "Toate fișierele",
|
||||
"AllMoviesInPathHaveBeenImported": "Toate filmele din {0} au fost importate",
|
||||
"AllResultsHiddenFilter": "Toate rezultatele sunt ascunse de filtrul aplicat",
|
||||
"Always": "Mereu",
|
||||
"Always": "Întotdeauna",
|
||||
"AptUpdater": "Utilizați apt pentru a instala actualizarea",
|
||||
"AuthBasic": "De bază (fereastră pop-up browser)",
|
||||
"AuthBasic": "Basic (fereastră pop-up browser)",
|
||||
"AuthForm": "Formulare (Pagina de autentificare)",
|
||||
"Automatic": "Automat",
|
||||
"BindAddressHelpText": "Adresă IP validă, localhost sau '*' pentru toate interfețele",
|
||||
@@ -615,7 +615,6 @@
|
||||
"AgeWhenGrabbed": "Vârsta (când a fost apucat)",
|
||||
"AllowHardcodedSubs": "Permiteți subtitrări codificate",
|
||||
"AllowHardcodedSubsHelpText": "Subcodurile codificate hard vor fi descărcate automat",
|
||||
"Authentication": "Autentificare",
|
||||
"Branch": "Ramură",
|
||||
"TotalFileSize": "Dimensiunea totală a fișierului",
|
||||
"UpgradeAllowedHelpText": "Dacă calitățile cu handicap nu vor fi actualizate",
|
||||
|
||||
@@ -1220,5 +1220,9 @@
|
||||
"AllTitles": "全部标题",
|
||||
"MatchedToMovie": "匹配影片",
|
||||
"ReleaseHash": "发布哈希值",
|
||||
"TestParsing": "测试解析"
|
||||
"TestParsing": "测试解析",
|
||||
"AddAutoTag": "添加自动标签",
|
||||
"AddCondition": "添加条件",
|
||||
"AutoTagging": "自动标记",
|
||||
"DeleteRootFolder": "删除根目录"
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ namespace NzbDrone.Core.Movies
|
||||
PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec);
|
||||
List<Movie> GetMoviesByFileId(int fileId);
|
||||
List<Movie> GetMoviesByCollectionTmdbId(int collectionId);
|
||||
void SetFileId(int fileId, int movieId);
|
||||
PagingSpec<Movie> MoviesWhereCutoffUnmet(PagingSpec<Movie> pagingSpec, List<QualitiesBelowCutoff> qualitiesBelowCutoff);
|
||||
Movie FindByPath(string path);
|
||||
Dictionary<int, string> AllMoviePaths();
|
||||
@@ -226,11 +225,6 @@ namespace NzbDrone.Core.Movies
|
||||
return Query(x => x.MovieMetadata.Value.CollectionTmdbId == collectionId);
|
||||
}
|
||||
|
||||
public void SetFileId(int fileId, int movieId)
|
||||
{
|
||||
SetFields(new Movie { Id = movieId, MovieFileId = fileId }, movie => movie.MovieFileId);
|
||||
}
|
||||
|
||||
public List<Movie> MoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored)
|
||||
{
|
||||
var builder = Builder()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user