mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-18 21:35:51 -04:00
Compare commits
131 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 204a8bab79 | |||
| 0158c84a98 | |||
| ac51a943fb | |||
| 78edc9aa43 | |||
| f2bf494cef | |||
| 5727e7c43b | |||
| a7ba1a6454 | |||
| cc285fab45 | |||
| e0ad573e7f | |||
| 9a23b7f0fc | |||
| 85aecbe67e | |||
| bbb20e95af | |||
| 3fb337e20b | |||
| 5e63da418e | |||
| 890f9d6fe4 | |||
| 8a496cbdae | |||
| f54a5388a0 | |||
| 6961633cc9 | |||
| 1be450a9d0 | |||
| 2b4d6464e2 | |||
| ee4c34bd6c | |||
| 07d41f7902 | |||
| bb573594d9 | |||
| 12e360ab4f | |||
| bae555f63e | |||
| 31abb93d8c | |||
| 75035035e1 | |||
| c1e5990a58 | |||
| 4a42ebe44c | |||
| c82aa5c2c7 | |||
| d1bae32e1c | |||
| c514c7cac0 | |||
| 3d244057b5 | |||
| 323510300c | |||
| 669d87b7ef | |||
| ec7f7b085a | |||
| ecc906a754 | |||
| d0fcac389c | |||
| 621acbef9a | |||
| 7fb1163b23 | |||
| b48eda95dd | |||
| 4627093616 | |||
| a006984d5e | |||
| 7d9183ef12 | |||
| d35c6683e9 | |||
| ac26bcddd9 | |||
| 15bafce8cc | |||
| 2167da87ce | |||
| 926d37a572 | |||
| 42c9e4e3e5 | |||
| 89b609a221 | |||
| dfc9f74116 | |||
| 189603c756 | |||
| a78693a2f7 | |||
| cea0c5033a | |||
| 1e3a42bf42 | |||
| 030744ab7b | |||
| 17fda02d8c | |||
| aabf6b9ff8 | |||
| 7b2fd5140b | |||
| b6b10d7c6f | |||
| 16fcf0b56b | |||
| c222a1a434 | |||
| c6e91e028b | |||
| fcf5984944 | |||
| fdfe8ca656 | |||
| 150a5c1fc6 | |||
| 9ea0957351 | |||
| 8befa436cc | |||
| 53fdb6f07f | |||
| 0697dbff96 | |||
| 34924859aa | |||
| 9c86598b54 | |||
| 0fe2262162 | |||
| 47353aea75 | |||
| af43cb2aca | |||
| bc838b74c7 | |||
| cbcf3d1058 | |||
| c72e64f081 | |||
| e09607edb0 | |||
| d91578aee3 | |||
| affedd7f9d | |||
| c3665e9fea | |||
| 364d8bd7c5 | |||
| 7142d1f224 | |||
| 86777e021b | |||
| 9d2dacea97 | |||
| d98c86c3d9 | |||
| df681d82be | |||
| daf81c5b26 | |||
| 78f929c60b | |||
| 87d59d12a4 | |||
| ce031124c7 | |||
| d4ce08a044 | |||
| 871e78b314 | |||
| eeee682f6c | |||
| 9c594c3e53 | |||
| 0b1b19a165 | |||
| f1ff7b3b61 | |||
| 165c588557 | |||
| 327e18bc7a | |||
| f61f2c89dc | |||
| 2327b72558 | |||
| 66ddd08684 | |||
| 4d2143e9b2 | |||
| 7906ea2a0c | |||
| 9d1956794e | |||
| 4956ff7914 | |||
| f22a589cb8 | |||
| 04185d6839 | |||
| fb25e5d577 | |||
| 6845eaa9b2 | |||
| c1e65874bc | |||
| 226a5da0c9 | |||
| 685a24e476 | |||
| cae4faae61 | |||
| 5dac6badf2 | |||
| 5948f56482 | |||
| 98ddd0386b | |||
| 2947b244e4 | |||
| 72552b8084 | |||
| 09642444d7 | |||
| d1080b825c | |||
| 001421de10 | |||
| bab9b8b36a | |||
| 0fb738aa2e | |||
| 4963920a46 | |||
| f0d10fe1cd | |||
| 386b33b624 | |||
| 98201508f2 | |||
| 9723c569a1 |
+15
-11
@@ -19,10 +19,10 @@ indent_size = 4
|
|||||||
dotnet_sort_system_directives_first = true
|
dotnet_sort_system_directives_first = true
|
||||||
|
|
||||||
# Avoid "this." and "Me." if not necessary
|
# Avoid "this." and "Me." if not necessary
|
||||||
dotnet_style_qualification_for_field = false:warning
|
dotnet_style_qualification_for_field = false:refactoring
|
||||||
dotnet_style_qualification_for_property = false:warning
|
dotnet_style_qualification_for_property = false:refactoring
|
||||||
dotnet_style_qualification_for_method = false:warning
|
dotnet_style_qualification_for_method = false:refactoring
|
||||||
dotnet_style_qualification_for_event = false:warning
|
dotnet_style_qualification_for_event = false:refactoring
|
||||||
|
|
||||||
# Indentation preferences
|
# Indentation preferences
|
||||||
csharp_indent_block_contents = true
|
csharp_indent_block_contents = true
|
||||||
@@ -32,6 +32,10 @@ csharp_indent_case_contents_when_block = true
|
|||||||
csharp_indent_switch_labels = true
|
csharp_indent_switch_labels = true
|
||||||
csharp_indent_labels = flush_left
|
csharp_indent_labels = flush_left
|
||||||
|
|
||||||
|
dotnet_style_qualification_for_field = false:suggestion
|
||||||
|
dotnet_style_qualification_for_property = false:suggestion
|
||||||
|
dotnet_style_qualification_for_method = false:suggestion
|
||||||
|
dotnet_style_qualification_for_event = false:suggestion
|
||||||
dotnet_naming_style.instance_field_style.capitalization = camel_case
|
dotnet_naming_style.instance_field_style.capitalization = camel_case
|
||||||
dotnet_naming_style.instance_field_style.required_prefix = _
|
dotnet_naming_style.instance_field_style.required_prefix = _
|
||||||
|
|
||||||
@@ -64,6 +68,7 @@ dotnet_diagnostic.SA1406.severity = suggestion
|
|||||||
dotnet_diagnostic.SA1410.severity = suggestion
|
dotnet_diagnostic.SA1410.severity = suggestion
|
||||||
dotnet_diagnostic.SA1411.severity = suggestion
|
dotnet_diagnostic.SA1411.severity = suggestion
|
||||||
dotnet_diagnostic.SA1413.severity = none
|
dotnet_diagnostic.SA1413.severity = none
|
||||||
|
dotnet_diagnostic.SA1512.severity = none
|
||||||
dotnet_diagnostic.SA1516.severity = none
|
dotnet_diagnostic.SA1516.severity = none
|
||||||
dotnet_diagnostic.SA1600.severity = none
|
dotnet_diagnostic.SA1600.severity = none
|
||||||
dotnet_diagnostic.SA1601.severity = none
|
dotnet_diagnostic.SA1601.severity = none
|
||||||
@@ -162,6 +167,7 @@ dotnet_diagnostic.CA1309.severity = suggestion
|
|||||||
dotnet_diagnostic.CA1310.severity = suggestion
|
dotnet_diagnostic.CA1310.severity = suggestion
|
||||||
dotnet_diagnostic.CA1401.severity = suggestion
|
dotnet_diagnostic.CA1401.severity = suggestion
|
||||||
dotnet_diagnostic.CA1416.severity = suggestion
|
dotnet_diagnostic.CA1416.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1419.severity = suggestion
|
||||||
dotnet_diagnostic.CA1507.severity = suggestion
|
dotnet_diagnostic.CA1507.severity = suggestion
|
||||||
dotnet_diagnostic.CA1508.severity = suggestion
|
dotnet_diagnostic.CA1508.severity = suggestion
|
||||||
dotnet_diagnostic.CA1707.severity = suggestion
|
dotnet_diagnostic.CA1707.severity = suggestion
|
||||||
@@ -177,9 +183,6 @@ dotnet_diagnostic.CA1720.severity = suggestion
|
|||||||
dotnet_diagnostic.CA1721.severity = suggestion
|
dotnet_diagnostic.CA1721.severity = suggestion
|
||||||
dotnet_diagnostic.CA1724.severity = suggestion
|
dotnet_diagnostic.CA1724.severity = suggestion
|
||||||
dotnet_diagnostic.CA1725.severity = suggestion
|
dotnet_diagnostic.CA1725.severity = suggestion
|
||||||
dotnet_diagnostic.CA1801.severity = suggestion
|
|
||||||
dotnet_diagnostic.CA1802.severity = suggestion
|
|
||||||
dotnet_diagnostic.CA1805.severity = suggestion
|
|
||||||
dotnet_diagnostic.CA1806.severity = suggestion
|
dotnet_diagnostic.CA1806.severity = suggestion
|
||||||
dotnet_diagnostic.CA1810.severity = suggestion
|
dotnet_diagnostic.CA1810.severity = suggestion
|
||||||
dotnet_diagnostic.CA1812.severity = suggestion
|
dotnet_diagnostic.CA1812.severity = suggestion
|
||||||
@@ -191,13 +194,11 @@ dotnet_diagnostic.CA1819.severity = suggestion
|
|||||||
dotnet_diagnostic.CA1822.severity = suggestion
|
dotnet_diagnostic.CA1822.severity = suggestion
|
||||||
dotnet_diagnostic.CA1823.severity = suggestion
|
dotnet_diagnostic.CA1823.severity = suggestion
|
||||||
dotnet_diagnostic.CA1824.severity = suggestion
|
dotnet_diagnostic.CA1824.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1848.severity = suggestion
|
||||||
dotnet_diagnostic.CA2000.severity = suggestion
|
dotnet_diagnostic.CA2000.severity = suggestion
|
||||||
dotnet_diagnostic.CA2002.severity = suggestion
|
dotnet_diagnostic.CA2002.severity = suggestion
|
||||||
dotnet_diagnostic.CA2007.severity = suggestion
|
dotnet_diagnostic.CA2007.severity = suggestion
|
||||||
dotnet_diagnostic.CA2008.severity = suggestion
|
dotnet_diagnostic.CA2008.severity = suggestion
|
||||||
dotnet_diagnostic.CA2009.severity = suggestion
|
|
||||||
dotnet_diagnostic.CA2010.severity = suggestion
|
|
||||||
dotnet_diagnostic.CA2011.severity = suggestion
|
|
||||||
dotnet_diagnostic.CA2012.severity = suggestion
|
dotnet_diagnostic.CA2012.severity = suggestion
|
||||||
dotnet_diagnostic.CA2013.severity = suggestion
|
dotnet_diagnostic.CA2013.severity = suggestion
|
||||||
dotnet_diagnostic.CA2100.severity = suggestion
|
dotnet_diagnostic.CA2100.severity = suggestion
|
||||||
@@ -228,6 +229,9 @@ dotnet_diagnostic.CA2243.severity = suggestion
|
|||||||
dotnet_diagnostic.CA2244.severity = suggestion
|
dotnet_diagnostic.CA2244.severity = suggestion
|
||||||
dotnet_diagnostic.CA2245.severity = suggestion
|
dotnet_diagnostic.CA2245.severity = suggestion
|
||||||
dotnet_diagnostic.CA2246.severity = suggestion
|
dotnet_diagnostic.CA2246.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA2249.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA2251.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA2254.severity = suggestion
|
||||||
dotnet_diagnostic.CA3061.severity = suggestion
|
dotnet_diagnostic.CA3061.severity = suggestion
|
||||||
dotnet_diagnostic.CA3075.severity = suggestion
|
dotnet_diagnostic.CA3075.severity = suggestion
|
||||||
dotnet_diagnostic.CA3076.severity = suggestion
|
dotnet_diagnostic.CA3076.severity = suggestion
|
||||||
@@ -255,7 +259,7 @@ dotnet_diagnostic.CA5392.severity = suggestion
|
|||||||
dotnet_diagnostic.CA5394.severity = suggestion
|
dotnet_diagnostic.CA5394.severity = suggestion
|
||||||
dotnet_diagnostic.CA5397.severity = suggestion
|
dotnet_diagnostic.CA5397.severity = suggestion
|
||||||
|
|
||||||
|
dotnet_diagnostic.SYSLIB0006.severity = none
|
||||||
|
|
||||||
[*.{js,html,js,hbs,less,css}]
|
[*.{js,html,js,hbs,less,css}]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"paths": [
|
|
||||||
"frontend/src/**/*.js"
|
|
||||||
],
|
|
||||||
"ignored": [
|
|
||||||
"**/node_modules/**/*"
|
|
||||||
],
|
|
||||||
"port": 5004
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
name: Sync issue to Azure DevOps work item
|
|
||||||
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types:
|
|
||||||
[opened, edited, deleted, closed, reopened, labeled, unlabeled, assigned]
|
|
||||||
|
|
||||||
concurrency: azuresync-${{ github.event.issue.number }}
|
|
||||||
|
|
||||||
permissions: {}
|
|
||||||
jobs:
|
|
||||||
alert:
|
|
||||||
permissions:
|
|
||||||
issues: write # to update issue body
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: danhellem/github-actions-issue-to-work-item@master
|
|
||||||
if: "${{ contains(github.event.issue.labels.*.name, 'Type: Bug') == true }}"
|
|
||||||
env:
|
|
||||||
ado_token: "${{ secrets.ADO_PERSONAL_ACCESS_TOKEN }}"
|
|
||||||
github_token: "${{ github.token }}"
|
|
||||||
ado_organization: "Servarr"
|
|
||||||
ado_project: "Servarr"
|
|
||||||
ado_area_path: "Servarr\\Radarr"
|
|
||||||
ado_wit: "Bug"
|
|
||||||
ado_new_state: "New"
|
|
||||||
ado_active_state: "Active"
|
|
||||||
ado_close_state: "Closed"
|
|
||||||
ado_bypassrules: true
|
|
||||||
log_level: 100
|
|
||||||
- uses: danhellem/github-actions-issue-to-work-item@master
|
|
||||||
if: "${{ contains(github.event.issue.labels.*.name, 'Type: Bug') == false }}"
|
|
||||||
env:
|
|
||||||
ado_token: "${{ secrets.ADO_PERSONAL_ACCESS_TOKEN }}"
|
|
||||||
github_token: "${{ github.token }}"
|
|
||||||
ado_organization: "Servarr"
|
|
||||||
ado_project: "Servarr"
|
|
||||||
ado_area_path: "Servarr\\Radarr"
|
|
||||||
ado_wit: "User Story"
|
|
||||||
ado_new_state: "New"
|
|
||||||
ado_active_state: "Active"
|
|
||||||
ado_close_state: "Closed"
|
|
||||||
ado_bypassrules: true
|
|
||||||
log_level: 100
|
|
||||||
+2
-21
@@ -166,27 +166,8 @@ packages.config.md5sum
|
|||||||
|
|
||||||
# Common IntelliJ Platform excludes
|
# Common IntelliJ Platform excludes
|
||||||
|
|
||||||
# User specific
|
# Ignore Rider projects completely for now
|
||||||
**/.idea/**/workspace.xml
|
.idea/
|
||||||
**/.idea/**/tasks.xml
|
|
||||||
**/.idea/shelf/*
|
|
||||||
**/.idea/dictionaries
|
|
||||||
**/.idea/.idea.Radarr.Posix
|
|
||||||
**/.idea/.idea.Radarr.Windows
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
**/.idea/**/dataSources/
|
|
||||||
**/.idea/**/dataSources.ids
|
|
||||||
**/.idea/**/dataSources.xml
|
|
||||||
**/.idea/**/dataSources.local.xml
|
|
||||||
**/.idea/**/sqlDataSources.xml
|
|
||||||
**/.idea/**/dynamic.xml
|
|
||||||
|
|
||||||
# Rider
|
|
||||||
# Rider auto-generates .iml files, and contentModel.xml
|
|
||||||
**/.idea/**/*.iml
|
|
||||||
**/.idea/**/contentModel.xml
|
|
||||||
**/.idea/**/modules.xml
|
|
||||||
|
|
||||||
# ignore node_modules symlink
|
# ignore node_modules symlink
|
||||||
node_modules
|
node_modules
|
||||||
|
|||||||
+2
-2
@@ -9,13 +9,13 @@ variables:
|
|||||||
testsFolder: './_tests'
|
testsFolder: './_tests'
|
||||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||||
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
||||||
majorVersion: '4.3.2'
|
majorVersion: '4.5.0'
|
||||||
minorVersion: $[counter('minorVersion', 2000)]
|
minorVersion: $[counter('minorVersion', 2000)]
|
||||||
radarrVersion: '$(majorVersion).$(minorVersion)'
|
radarrVersion: '$(majorVersion).$(minorVersion)'
|
||||||
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
|
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
|
||||||
sentryOrg: 'servarr'
|
sentryOrg: 'servarr'
|
||||||
sentryUrl: 'https://sentry.servarr.com'
|
sentryUrl: 'https://sentry.servarr.com'
|
||||||
dotnetVersion: '6.0.400'
|
dotnetVersion: '6.0.408'
|
||||||
nodeVersion: '16.X'
|
nodeVersion: '16.X'
|
||||||
innoVersion: '6.2.0'
|
innoVersion: '6.2.0'
|
||||||
windowsImage: 'windows-2022'
|
windowsImage: 'windows-2022'
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// eslint-disable-next-line filenames/match-exported
|
||||||
const loaderUtils = require('loader-utils');
|
const loaderUtils = require('loader-utils');
|
||||||
|
|
||||||
module.exports = function cssVariablesLoader(source) {
|
module.exports = function cssVariablesLoader(source) {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class HistoryRow extends Component {
|
|||||||
movie,
|
movie,
|
||||||
quality,
|
quality,
|
||||||
customFormats,
|
customFormats,
|
||||||
|
customFormatScore,
|
||||||
languages,
|
languages,
|
||||||
qualityCutoffNotMet,
|
qualityCutoffNotMet,
|
||||||
eventType,
|
eventType,
|
||||||
@@ -175,7 +176,7 @@ class HistoryRow extends Component {
|
|||||||
key={name}
|
key={name}
|
||||||
className={styles.customFormatScore}
|
className={styles.customFormatScore}
|
||||||
>
|
>
|
||||||
{formatCustomFormatScore(data.customFormatScore)}
|
{formatCustomFormatScore(customFormatScore)}
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -241,8 +242,9 @@ HistoryRow.propTypes = {
|
|||||||
movie: PropTypes.object.isRequired,
|
movie: PropTypes.object.isRequired,
|
||||||
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
|
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||||
|
customFormatScore: PropTypes.number.isRequired,
|
||||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
eventType: PropTypes.string.isRequired,
|
eventType: PropTypes.string.isRequired,
|
||||||
sourceTitle: PropTypes.string.isRequired,
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
date: PropTypes.string.isRequired,
|
date: PropTypes.string.isRequired,
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ class QueueRow extends Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
columns.map((column) => {
|
columns.map((column) => {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
isVisible
|
isVisible
|
||||||
@@ -234,6 +235,16 @@ class QueueRow extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name === 'year') {
|
||||||
|
return (
|
||||||
|
<TableRowCell key={name}>
|
||||||
|
{
|
||||||
|
movie ? movie.year : ''
|
||||||
|
}
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (name === 'title') {
|
if (name === 'title') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
@@ -362,6 +373,7 @@ QueueRow.propTypes = {
|
|||||||
estimatedCompletionTime: PropTypes.string,
|
estimatedCompletionTime: PropTypes.string,
|
||||||
timeleft: PropTypes.string,
|
timeleft: PropTypes.string,
|
||||||
size: PropTypes.number,
|
size: PropTypes.number,
|
||||||
|
year: PropTypes.number,
|
||||||
sizeleft: PropTypes.number,
|
sizeleft: PropTypes.number,
|
||||||
showRelativeDates: PropTypes.bool.isRequired,
|
showRelativeDates: PropTypes.bool.isRequired,
|
||||||
shortDateFormat: PropTypes.string.isRequired,
|
shortDateFormat: PropTypes.string.isRequired,
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ class AddNewMovieSearchResult extends Component {
|
|||||||
images={images}
|
images={images}
|
||||||
size={250}
|
size={250}
|
||||||
overflow={true}
|
overflow={true}
|
||||||
|
lazy={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ class CalendarOptionsModalContent extends Component {
|
|||||||
values={weekColumnOptions}
|
values={weekColumnOptions}
|
||||||
value={calendarWeekColumnHeader}
|
value={calendarWeekColumnHeader}
|
||||||
onChange={this.onGlobalInputChange}
|
onChange={this.onGlobalInputChange}
|
||||||
helpText={translate('HelpText')}
|
helpText={translate('SettingsWeekColumnHeaderHelpText')}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -113,10 +113,12 @@ class EnhancedSelectInput extends Component {
|
|||||||
this._scheduleUpdate();
|
this._scheduleUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Array.isArray(this.props.value) && prevProps.value !== this.props.value) {
|
if (!Array.isArray(this.props.value)) {
|
||||||
this.setState({
|
if (prevProps.value !== this.props.value || prevProps.values !== this.props.values) {
|
||||||
selectedIndex: getSelectedIndex(this.props)
|
this.setState({
|
||||||
});
|
selectedIndex: getSelectedIndex(this.props)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,6 +334,11 @@ class EnhancedSelectInput extends Component {
|
|||||||
|
|
||||||
const isMultiSelect = Array.isArray(value);
|
const isMultiSelect = Array.isArray(value);
|
||||||
const selectedOption = getSelectedOption(selectedIndex, values);
|
const selectedOption = getSelectedOption(selectedIndex, values);
|
||||||
|
let selectedValue = value;
|
||||||
|
|
||||||
|
if (!values.length) {
|
||||||
|
selectedValue = isMultiSelect ? [] : '';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -372,15 +379,17 @@ class EnhancedSelectInput extends Component {
|
|||||||
onPress={this.onPress}
|
onPress={this.onPress}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
isFetching &&
|
isFetching ?
|
||||||
<LoadingIndicator
|
<LoadingIndicator
|
||||||
className={styles.loading}
|
className={styles.loading}
|
||||||
size={20}
|
size={20}
|
||||||
/>
|
/> :
|
||||||
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!isFetching &&
|
isFetching ?
|
||||||
|
null :
|
||||||
<Icon
|
<Icon
|
||||||
name={icons.CARET_DOWN}
|
name={icons.CARET_DOWN}
|
||||||
/>
|
/>
|
||||||
@@ -400,7 +409,7 @@ class EnhancedSelectInput extends Component {
|
|||||||
onPress={this.onPress}
|
onPress={this.onPress}
|
||||||
>
|
>
|
||||||
<SelectedValueComponent
|
<SelectedValueComponent
|
||||||
value={value}
|
value={selectedValue}
|
||||||
values={values}
|
values={values}
|
||||||
{...selectedValueOptions}
|
{...selectedValueOptions}
|
||||||
{...selectedOption}
|
{...selectedOption}
|
||||||
@@ -418,15 +427,17 @@ class EnhancedSelectInput extends Component {
|
|||||||
>
|
>
|
||||||
|
|
||||||
{
|
{
|
||||||
isFetching &&
|
isFetching ?
|
||||||
<LoadingIndicator
|
<LoadingIndicator
|
||||||
className={styles.loading}
|
className={styles.loading}
|
||||||
size={20}
|
size={20}
|
||||||
/>
|
/> :
|
||||||
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!isFetching &&
|
isFetching ?
|
||||||
|
null :
|
||||||
<Icon
|
<Icon
|
||||||
name={icons.CARET_DOWN}
|
name={icons.CARET_DOWN}
|
||||||
/>
|
/>
|
||||||
@@ -506,7 +517,7 @@ class EnhancedSelectInput extends Component {
|
|||||||
</Manager>
|
</Manager>
|
||||||
|
|
||||||
{
|
{
|
||||||
isMobile &&
|
isMobile ?
|
||||||
<Modal
|
<Modal
|
||||||
className={styles.optionsModal}
|
className={styles.optionsModal}
|
||||||
size={sizes.EXTRA_SMALL}
|
size={sizes.EXTRA_SMALL}
|
||||||
@@ -557,7 +568,8 @@ class EnhancedSelectInput extends Component {
|
|||||||
}
|
}
|
||||||
</Scroller>
|
</Scroller>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
</Modal>
|
</Modal> :
|
||||||
|
null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function HintedSelectInputSelectedValue(props) {
|
|||||||
>
|
>
|
||||||
<div className={styles.valueText}>
|
<div className={styles.valueText}>
|
||||||
{
|
{
|
||||||
isMultiSelect &&
|
isMultiSelect ?
|
||||||
value.map((key, index) => {
|
value.map((key, index) => {
|
||||||
const v = valuesMap[key];
|
const v = valuesMap[key];
|
||||||
return (
|
return (
|
||||||
@@ -32,26 +32,28 @@ function HintedSelectInputSelectedValue(props) {
|
|||||||
{v ? v.value : key}
|
{v ? v.value : key}
|
||||||
</Label>
|
</Label>
|
||||||
);
|
);
|
||||||
})
|
}) :
|
||||||
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!isMultiSelect && value
|
isMultiSelect ? null : value
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
hint != null && includeHint &&
|
hint != null && includeHint ?
|
||||||
<div className={styles.hintText}>
|
<div className={styles.hintText}>
|
||||||
{hint}
|
{hint}
|
||||||
</div>
|
</div> :
|
||||||
|
null
|
||||||
}
|
}
|
||||||
</EnhancedSelectInputSelectedValue>
|
</EnhancedSelectInputSelectedValue>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HintedSelectInputSelectedValue.propTypes = {
|
HintedSelectInputSelectedValue.propTypes = {
|
||||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number]))]).isRequired,
|
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number]))]).isRequired,
|
||||||
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
hint: PropTypes.string,
|
hint: PropTypes.string,
|
||||||
isMultiSelect: PropTypes.bool.isRequired,
|
isMultiSelect: PropTypes.bool.isRequired,
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ RootFolderSelectInputOption.propTypes = {
|
|||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
freeSpace: PropTypes.number,
|
freeSpace: PropTypes.number,
|
||||||
movieFolder: PropTypes.string,
|
movieFolder: PropTypes.string,
|
||||||
isMissing: PropTypes.boolean,
|
isMissing: PropTypes.bool,
|
||||||
isMobile: PropTypes.bool.isRequired,
|
isMobile: PropTypes.bool.isRequired,
|
||||||
isWindows: PropTypes.bool
|
isWindows: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -112,6 +112,12 @@ class TextInput extends Component {
|
|||||||
this._isMouseTarget = false;
|
this._isMouseTarget = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onWheel = () => {
|
||||||
|
if (this.props.type === 'number') {
|
||||||
|
this._input.blur();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Render
|
// Render
|
||||||
|
|
||||||
@@ -161,6 +167,7 @@ class TextInput extends Component {
|
|||||||
onKeyUp={this.onKeyUp}
|
onKeyUp={this.onKeyUp}
|
||||||
onMouseDown={this.onMouseDown}
|
onMouseDown={this.onMouseDown}
|
||||||
onMouseUp={this.onMouseUp}
|
onMouseUp={this.onMouseUp}
|
||||||
|
onWheel={this.onWheel}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable no-bitwise */
|
/* eslint-disable no-bitwise */
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import EnhancedSelectInput from './EnhancedSelectInput';
|
import EnhancedSelectInput from './EnhancedSelectInput';
|
||||||
import styles from './UMaskInput.css';
|
import styles from './UMaskInput.css';
|
||||||
|
|
||||||
@@ -101,16 +102,16 @@ class UMaskInput extends Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles.details}>
|
<div className={styles.details}>
|
||||||
<div>
|
<div>
|
||||||
<label>UMask</label>
|
<label>{translate('UMask')}</label>
|
||||||
<div className={styles.value}>{umask}</div>
|
<div className={styles.value}>{umask}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Folder</label>
|
<label>{translate('Folder')}</label>
|
||||||
<div className={styles.value}>{folder}</div>
|
<div className={styles.value}>{folder}</div>
|
||||||
<div className={styles.unit}>d{formatPermissions(folderNum)}</div>
|
<div className={styles.unit}>d{formatPermissions(folderNum)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>File</label>
|
<label>{translate('File')}</label>
|
||||||
<div className={styles.value}>{file}</div>
|
<div className={styles.value}>{file}</div>
|
||||||
<div className={styles.unit}>{formatPermissions(fileNum)}</div>
|
<div className={styles.unit}>{formatPermissions(fileNum)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class FilterMenu extends Component {
|
|||||||
iconName={icons.FILTER}
|
iconName={icons.FILTER}
|
||||||
text={translate('Filter')}
|
text={translate('Filter')}
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
indicator={selectedFilterKey !== 'all'}
|
showIndicator={selectedFilterKey !== 'all'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FilterMenuContent
|
<FilterMenuContent
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
.menuButton {
|
.menuButton {
|
||||||
composes: menuButton from '~./MenuButton.css';
|
composes: menuButton from '~./MenuButton.css';
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.indicatorContainer {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
|
import classNames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from 'Components/Icon';
|
import Icon from 'Components/Icon';
|
||||||
import MenuButton from 'Components/Menu/MenuButton';
|
import MenuButton from 'Components/Menu/MenuButton';
|
||||||
|
import { icons } from 'Helpers/Props';
|
||||||
import styles from './PageMenuButton.css';
|
import styles from './PageMenuButton.css';
|
||||||
|
|
||||||
function PageMenuButton(props) {
|
function PageMenuButton(props) {
|
||||||
const {
|
const {
|
||||||
iconName,
|
iconName,
|
||||||
indicator,
|
showIndicator,
|
||||||
text,
|
text,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
@@ -22,6 +24,22 @@ function PageMenuButton(props) {
|
|||||||
size={18}
|
size={18}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{
|
||||||
|
showIndicator ?
|
||||||
|
<span
|
||||||
|
className={classNames(
|
||||||
|
styles.indicatorContainer,
|
||||||
|
'fa-layers fa-fw'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
name={icons.CIRCLE}
|
||||||
|
size={9}
|
||||||
|
/>
|
||||||
|
</span> :
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
<div className={styles.label}>
|
<div className={styles.label}>
|
||||||
{text}
|
{text}
|
||||||
</div>
|
</div>
|
||||||
@@ -32,11 +50,11 @@ function PageMenuButton(props) {
|
|||||||
PageMenuButton.propTypes = {
|
PageMenuButton.propTypes = {
|
||||||
iconName: PropTypes.object.isRequired,
|
iconName: PropTypes.object.isRequired,
|
||||||
text: PropTypes.string,
|
text: PropTypes.string,
|
||||||
indicator: PropTypes.bool.isRequired
|
showIndicator: PropTypes.bool.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
PageMenuButton.defaultProps = {
|
PageMenuButton.defaultProps = {
|
||||||
indicator: false
|
showIndicator: false
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PageMenuButton;
|
export default PageMenuButton;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import styles from './ToolbarMenuButton.css';
|
|||||||
function ToolbarMenuButton(props) {
|
function ToolbarMenuButton(props) {
|
||||||
const {
|
const {
|
||||||
iconName,
|
iconName,
|
||||||
indicator,
|
showIndicator,
|
||||||
text,
|
text,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
@@ -26,7 +26,7 @@ function ToolbarMenuButton(props) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{
|
{
|
||||||
indicator &&
|
showIndicator &&
|
||||||
<span
|
<span
|
||||||
className={classNames(
|
className={classNames(
|
||||||
styles.indicatorContainer,
|
styles.indicatorContainer,
|
||||||
@@ -53,11 +53,11 @@ function ToolbarMenuButton(props) {
|
|||||||
ToolbarMenuButton.propTypes = {
|
ToolbarMenuButton.propTypes = {
|
||||||
iconName: PropTypes.object.isRequired,
|
iconName: PropTypes.object.isRequired,
|
||||||
text: PropTypes.string,
|
text: PropTypes.string,
|
||||||
indicator: PropTypes.bool.isRequired
|
showIndicator: PropTypes.bool.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
ToolbarMenuButton.defaultProps = {
|
ToolbarMenuButton.defaultProps = {
|
||||||
indicator: false
|
showIndicator: false
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ToolbarMenuButton;
|
export default ToolbarMenuButton;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointLarge) {
|
@media only screen and (max-width: $breakpointExtraLarge) {
|
||||||
.contentFooter {
|
.contentFooter {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,11 @@
|
|||||||
|
|
||||||
.frontTextContainer {
|
.frontTextContainer {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
color: var(--white);
|
color: var(--progressBarFrontTextColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.backTextContainer {
|
||||||
|
color: var(--progressBarBackTextColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
.backTextContainer,
|
.backTextContainer,
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ function getInfoRowProps(row, props) {
|
|||||||
return {
|
return {
|
||||||
title: translate('Ratings'),
|
title: translate('Ratings'),
|
||||||
iconName: icons.HEART,
|
iconName: icons.HEART,
|
||||||
label: `${props.ratings.tmdb.value * 10}%`
|
label: `${(props.ratings.tmdb.value * 10).toFixed()}%`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ export const possibleFilterTypes = {
|
|||||||
{ key: filterTypes.CONTAINS, value: 'contains' },
|
{ key: filterTypes.CONTAINS, value: 'contains' },
|
||||||
{ key: filterTypes.NOT_CONTAINS, value: 'does not contain' },
|
{ key: filterTypes.NOT_CONTAINS, value: 'does not contain' },
|
||||||
{ key: filterTypes.EQUAL, value: 'equal' },
|
{ key: filterTypes.EQUAL, value: 'equal' },
|
||||||
{ key: filterTypes.NOT_EQUAL, value: 'not equal' }
|
{ key: filterTypes.NOT_EQUAL, value: 'not equal' },
|
||||||
|
{ key: filterTypes.STARTS_WITH, value: 'starts with' },
|
||||||
|
{ key: filterTypes.NOT_STARTS_WITH, value: 'does not start with' },
|
||||||
|
{ key: filterTypes.ENDS_WITH, value: 'ends with' },
|
||||||
|
{ key: filterTypes.NOT_ENDS_WITH, value: 'does not end with' }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,6 +39,22 @@ const filterTypePredicates = {
|
|||||||
|
|
||||||
[filterTypes.NOT_EQUAL]: function(itemValue, filterValue) {
|
[filterTypes.NOT_EQUAL]: function(itemValue, filterValue) {
|
||||||
return itemValue !== filterValue;
|
return itemValue !== filterValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
[filterTypes.STARTS_WITH]: function(itemValue, filterValue) {
|
||||||
|
return itemValue.toLowerCase().startsWith(filterValue.toLowerCase());
|
||||||
|
},
|
||||||
|
|
||||||
|
[filterTypes.NOT_STARTS_WITH]: function(itemValue, filterValue) {
|
||||||
|
return !itemValue.toLowerCase().startsWith(filterValue.toLowerCase());
|
||||||
|
},
|
||||||
|
|
||||||
|
[filterTypes.ENDS_WITH]: function(itemValue, filterValue) {
|
||||||
|
return itemValue.toLowerCase().endsWith(filterValue.toLowerCase());
|
||||||
|
},
|
||||||
|
|
||||||
|
[filterTypes.NOT_ENDS_WITH]: function(itemValue, filterValue) {
|
||||||
|
return !itemValue.toLowerCase().endsWith(filterValue.toLowerCase());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ export const LESS_THAN = 'lessThan';
|
|||||||
export const LESS_THAN_OR_EQUAL = 'lessThanOrEqual';
|
export const LESS_THAN_OR_EQUAL = 'lessThanOrEqual';
|
||||||
export const NOT_CONTAINS = 'notContains';
|
export const NOT_CONTAINS = 'notContains';
|
||||||
export const NOT_EQUAL = 'notEqual';
|
export const NOT_EQUAL = 'notEqual';
|
||||||
|
export const STARTS_WITH = 'startsWith';
|
||||||
|
export const NOT_STARTS_WITH = 'notStartsWith';
|
||||||
|
export const ENDS_WITH = 'endsWith';
|
||||||
|
export const NOT_ENDS_WITH = 'notEndsWith';
|
||||||
|
|
||||||
export const all = [
|
export const all = [
|
||||||
CONTAINS,
|
CONTAINS,
|
||||||
@@ -23,5 +27,9 @@ export const all = [
|
|||||||
IN_LAST,
|
IN_LAST,
|
||||||
NOT_IN_LAST,
|
NOT_IN_LAST,
|
||||||
IN_NEXT,
|
IN_NEXT,
|
||||||
NOT_IN_NEXT
|
NOT_IN_NEXT,
|
||||||
|
STARTS_WITH,
|
||||||
|
NOT_STARTS_WITH,
|
||||||
|
ENDS_WITH,
|
||||||
|
NOT_ENDS_WITH
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -64,6 +64,15 @@ const columns = [
|
|||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'customFormats',
|
||||||
|
label: React.createElement(Icon, {
|
||||||
|
name: icons.INTERACTIVE,
|
||||||
|
title: translate('CustomFormat')
|
||||||
|
}),
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'rejections',
|
name: 'rejections',
|
||||||
label: React.createElement(Icon, {
|
label: React.createElement(Icon, {
|
||||||
|
|||||||
@@ -5,8 +5,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.quality,
|
.quality,
|
||||||
.language {
|
.languages {
|
||||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
@@ -21,3 +23,7 @@
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.customFormatTooltip {
|
||||||
|
max-width: 250px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import SelectLanguageModal from 'InteractiveImport/Language/SelectLanguageModal'
|
|||||||
import SelectMovieModal from 'InteractiveImport/Movie/SelectMovieModal';
|
import SelectMovieModal from 'InteractiveImport/Movie/SelectMovieModal';
|
||||||
import SelectQualityModal from 'InteractiveImport/Quality/SelectQualityModal';
|
import SelectQualityModal from 'InteractiveImport/Quality/SelectQualityModal';
|
||||||
import SelectReleaseGroupModal from 'InteractiveImport/ReleaseGroup/SelectReleaseGroupModal';
|
import SelectReleaseGroupModal from 'InteractiveImport/ReleaseGroup/SelectReleaseGroupModal';
|
||||||
|
import MovieFormats from 'Movie/MovieFormats';
|
||||||
import MovieLanguage from 'Movie/MovieLanguage';
|
import MovieLanguage from 'Movie/MovieLanguage';
|
||||||
import MovieQuality from 'Movie/MovieQuality';
|
import MovieQuality from 'Movie/MovieQuality';
|
||||||
import formatBytes from 'Utilities/Number/formatBytes';
|
import formatBytes from 'Utilities/Number/formatBytes';
|
||||||
@@ -150,6 +151,7 @@ class InteractiveImportRow extends Component {
|
|||||||
languages,
|
languages,
|
||||||
releaseGroup,
|
releaseGroup,
|
||||||
size,
|
size,
|
||||||
|
customFormats,
|
||||||
rejections,
|
rejections,
|
||||||
isReprocessing,
|
isReprocessing,
|
||||||
isSelected,
|
isSelected,
|
||||||
@@ -226,7 +228,7 @@ class InteractiveImportRow extends Component {
|
|||||||
</TableRowCellButton>
|
</TableRowCellButton>
|
||||||
|
|
||||||
<TableRowCellButton
|
<TableRowCellButton
|
||||||
className={styles.language}
|
className={styles.languages}
|
||||||
title={translate('ClickToChangeLanguage')}
|
title={translate('ClickToChangeLanguage')}
|
||||||
onPress={this.onSelectLanguagePress}
|
onPress={this.onSelectLanguagePress}
|
||||||
>
|
>
|
||||||
@@ -259,7 +261,26 @@ class InteractiveImportRow extends Component {
|
|||||||
|
|
||||||
<TableRowCell>
|
<TableRowCell>
|
||||||
{
|
{
|
||||||
!!rejections.length &&
|
customFormats?.length ?
|
||||||
|
<Popover
|
||||||
|
anchor={
|
||||||
|
<Icon name={icons.INTERACTIVE} />
|
||||||
|
}
|
||||||
|
title={translate('Formats')}
|
||||||
|
body={
|
||||||
|
<div className={styles.customFormatTooltip}>
|
||||||
|
<MovieFormats formats={customFormats} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
position={tooltipPositions.LEFT}
|
||||||
|
/> :
|
||||||
|
null
|
||||||
|
}
|
||||||
|
</TableRowCell>
|
||||||
|
|
||||||
|
<TableRowCell>
|
||||||
|
{
|
||||||
|
rejections.length ?
|
||||||
<Popover
|
<Popover
|
||||||
anchor={
|
anchor={
|
||||||
<Icon
|
<Icon
|
||||||
@@ -282,7 +303,9 @@ class InteractiveImportRow extends Component {
|
|||||||
</ul>
|
</ul>
|
||||||
}
|
}
|
||||||
position={tooltipPositions.LEFT}
|
position={tooltipPositions.LEFT}
|
||||||
/>
|
canFlip={false}
|
||||||
|
/> :
|
||||||
|
null
|
||||||
}
|
}
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
@@ -330,6 +353,7 @@ InteractiveImportRow.propTypes = {
|
|||||||
languages: PropTypes.arrayOf(PropTypes.object),
|
languages: PropTypes.arrayOf(PropTypes.object),
|
||||||
releaseGroup: PropTypes.string,
|
releaseGroup: PropTypes.string,
|
||||||
size: PropTypes.number.isRequired,
|
size: PropTypes.number.isRequired,
|
||||||
|
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||||
rejections: PropTypes.arrayOf(PropTypes.object).isRequired,
|
rejections: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
isReprocessing: PropTypes.bool,
|
isReprocessing: PropTypes.bool,
|
||||||
isSelected: PropTypes.bool,
|
isSelected: PropTypes.bool,
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class MovieHistoryRow extends Component {
|
|||||||
sourceTitle,
|
sourceTitle,
|
||||||
quality,
|
quality,
|
||||||
customFormats,
|
customFormats,
|
||||||
|
customFormatScore,
|
||||||
languages,
|
languages,
|
||||||
qualityCutoffNotMet,
|
qualityCutoffNotMet,
|
||||||
date,
|
date,
|
||||||
@@ -106,7 +107,7 @@ class MovieHistoryRow extends Component {
|
|||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
{formatCustomFormatScore(data.customFormatScore)}
|
{formatCustomFormatScore(customFormatScore)}
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<RelativeDateCellConnector
|
<RelativeDateCellConnector
|
||||||
@@ -161,7 +162,8 @@ MovieHistoryRow.propTypes = {
|
|||||||
sourceTitle: PropTypes.string.isRequired,
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
|
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||||
|
customFormatScore: PropTypes.number.isRequired,
|
||||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
date: PropTypes.string.isRequired,
|
date: PropTypes.string.isRequired,
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
|
|||||||
@@ -17,6 +17,10 @@
|
|||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.cloneButton {
|
.cloneButton {
|
||||||
composes: button from '~Components/Link/IconButton.css';
|
composes: button from '~Components/Link/IconButton.css';
|
||||||
|
|
||||||
@@ -36,3 +40,10 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
@add-mixin truncate;
|
||||||
|
composes: label from '~Components/Label.css';
|
||||||
|
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class CustomFormat extends Component {
|
|||||||
{name}
|
{name}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div className={styles.buttons}>
|
||||||
<IconButton
|
<IconButton
|
||||||
className={styles.cloneButton}
|
className={styles.cloneButton}
|
||||||
title={translate('CloneCustomFormat')}
|
title={translate('CloneCustomFormat')}
|
||||||
@@ -124,6 +124,7 @@ class CustomFormat extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Label
|
<Label
|
||||||
|
className={styles.label}
|
||||||
key={index}
|
key={index}
|
||||||
kind={kind}
|
kind={kind}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -8,11 +8,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.host {
|
.host {
|
||||||
flex: 0 0 300px;
|
@add-mixin truncate;
|
||||||
|
|
||||||
|
flex: 0 1 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.path {
|
.path {
|
||||||
flex: 0 0 400px;
|
@add-mixin truncate;
|
||||||
|
|
||||||
|
flex: 0 1 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
.remotePathMappingsHeader {
|
.remotePathMappingsHeader {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
padding-right: 24px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.host {
|
.host {
|
||||||
flex: 0 0 300px;
|
@add-mixin truncate;
|
||||||
|
|
||||||
|
flex: 0 1 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.path {
|
.path {
|
||||||
flex: 0 0 400px;
|
@add-mixin truncate;
|
||||||
|
|
||||||
|
flex: 0 1 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addRemotePathMapping {
|
.addRemotePathMapping {
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ function EditIndexerModalContent(props) {
|
|||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.CHECK}
|
type={inputTypes.CHECK}
|
||||||
name="enableRss"
|
name="enableRss"
|
||||||
|
helpText={supportsRss.value ? translate('RSSHelpText') : undefined}
|
||||||
helpTextWarning={supportsRss.value ? undefined : translate('RSSIsNotSupportedWithThisIndexer')}
|
helpTextWarning={supportsRss.value ? undefined : translate('RSSIsNotSupportedWithThisIndexer')}
|
||||||
isDisabled={!supportsRss.value}
|
isDisabled={!supportsRss.value}
|
||||||
{...enableRss}
|
{...enableRss}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
code {
|
code {
|
||||||
padding: 0 1px;
|
padding: 0 1px;
|
||||||
border: 1px solid var(--borderColor);
|
border: 1px solid var(--borderColor);
|
||||||
background-color: #f7f7f7;
|
background-color: var(--modalCloseButtonHoverColor);
|
||||||
|
color: var(--movieBackgroundColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.token {
|
.token {
|
||||||
background-color: #ddd;
|
background-color: var(--popoverTitleBackgroundInverseColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
.example {
|
.example {
|
||||||
background-color: #ccc;
|
background-color: var(--popoverTitleBorderInverseColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
.token {
|
.token {
|
||||||
flex: 0 0 50%;
|
flex: 0 0 50%;
|
||||||
padding: 6px 16px;
|
padding: 6px 16px;
|
||||||
background-color: #eee;
|
background-color: var(--popoverTitleBorderColor);
|
||||||
font-family: $monoSpaceFontFamily;
|
font-family: $monoSpaceFontFamily;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex: 0 0 50%;
|
flex: 0 0 50%;
|
||||||
padding: 6px 16px;
|
padding: 6px 16px;
|
||||||
background-color: #ddd;
|
background-color: var(--popoverTitleBackgroundColor);
|
||||||
|
|
||||||
.footNote {
|
.footNote {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export const certificationCountryOptions = [
|
|||||||
{ key: 'fr', value: 'France' },
|
{ key: 'fr', value: 'France' },
|
||||||
{ key: 'de', value: 'Germany' },
|
{ key: 'de', value: 'Germany' },
|
||||||
{ key: 'gb', value: 'Great Britain' },
|
{ key: 'gb', value: 'Great Britain' },
|
||||||
|
{ key: 'ie', value: 'Ireland' },
|
||||||
{ key: 'it', value: 'Italy' },
|
{ key: 'it', value: 'Italy' },
|
||||||
{ key: 'es', value: 'Spain' },
|
{ key: 'es', value: 'Spain' },
|
||||||
{ key: 'us', value: 'United States' },
|
{ key: 'us', value: 'United States' },
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ const delayProfileShape = {
|
|||||||
enableTorrent: PropTypes.shape(boolSettingShape).isRequired,
|
enableTorrent: PropTypes.shape(boolSettingShape).isRequired,
|
||||||
usenetDelay: PropTypes.shape(numberSettingShape).isRequired,
|
usenetDelay: PropTypes.shape(numberSettingShape).isRequired,
|
||||||
torrentDelay: PropTypes.shape(numberSettingShape).isRequired,
|
torrentDelay: PropTypes.shape(numberSettingShape).isRequired,
|
||||||
|
bypassIfHighestQuality: PropTypes.shape(boolSettingShape).isRequired,
|
||||||
order: PropTypes.shape(numberSettingShape),
|
order: PropTypes.shape(numberSettingShape),
|
||||||
tags: PropTypes.shape(tagSettingShape).isRequired
|
tags: PropTypes.shape(tagSettingShape).isRequired
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const newDelayProfile = {
|
|||||||
preferredProtocol: 'usenet',
|
preferredProtocol: 'usenet',
|
||||||
usenetDelay: 0,
|
usenetDelay: 0,
|
||||||
torrentDelay: 0,
|
torrentDelay: 0,
|
||||||
|
bypassIfHighestQuality: false,
|
||||||
tags: []
|
tags: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { DndProvider } from 'react-dnd';
|
import { DndProvider } from 'react-dnd-multi-backend';
|
||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import HTML5toTouch from 'react-dnd-multi-backend/dist/esm/HTML5toTouch';
|
||||||
import Link from 'Components/Link/Link';
|
import Link from 'Components/Link/Link';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
@@ -25,7 +25,7 @@ class Profiles extends Component {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<PageContentBody>
|
<PageContentBody>
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider options={HTML5toTouch}>
|
||||||
<QualityProfilesConnector />
|
<QualityProfilesConnector />
|
||||||
<DelayProfilesConnector />
|
<DelayProfilesConnector />
|
||||||
<div className={styles.addCustomFormatMessage}>
|
<div className={styles.addCustomFormatMessage}>
|
||||||
|
|||||||
@@ -118,6 +118,12 @@ export const defaultState = {
|
|||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'year',
|
||||||
|
label: translate('Year'),
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'outputPath',
|
name: 'outputPath',
|
||||||
label: translate('OutputPath'),
|
label: translate('OutputPath'),
|
||||||
|
|||||||
@@ -201,6 +201,11 @@ export const defaultState = {
|
|||||||
return genreList.sort(sortByName);
|
return genreList.sort(sortByName);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'customFormatScore',
|
||||||
|
label: translate('CustomFormatScore'),
|
||||||
|
type: filterBuilderTypes.NUMBER
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'rejectionCount',
|
name: 'rejectionCount',
|
||||||
label: translate('RejectionCount'),
|
label: translate('RejectionCount'),
|
||||||
|
|||||||
@@ -94,27 +94,27 @@ module.exports = {
|
|||||||
defaultBackgroundColor: '#333',
|
defaultBackgroundColor: '#333',
|
||||||
defaultBorderColor: '#eaeaea',
|
defaultBorderColor: '#eaeaea',
|
||||||
defaultHoverBackgroundColor: '#444',
|
defaultHoverBackgroundColor: '#444',
|
||||||
defaultHoverBorderColor: '#d6d6d6;',
|
defaultHoverBorderColor: '#d6d6d6',
|
||||||
|
|
||||||
primaryBackgroundColor: '#5d9cec',
|
primaryBackgroundColor: '#5d9cec',
|
||||||
primaryBorderColor: '#5899eb',
|
primaryBorderColor: '#5899eb',
|
||||||
primaryHoverBackgroundColor: '#4b91ea',
|
primaryHoverBackgroundColor: '#4b91ea',
|
||||||
primaryHoverBorderColor: '#3483e7;',
|
primaryHoverBorderColor: '#3483e7',
|
||||||
|
|
||||||
successBackgroundColor: '#27c24c',
|
successBackgroundColor: '#27c24c',
|
||||||
successBorderColor: '#26be4a',
|
successBorderColor: '#26be4a',
|
||||||
successHoverBackgroundColor: '#24b145',
|
successHoverBackgroundColor: '#24b145',
|
||||||
successHoverBorderColor: '#1f9c3d;',
|
successHoverBorderColor: '#1f9c3d',
|
||||||
|
|
||||||
warningBackgroundColor: '#ff902b',
|
warningBackgroundColor: '#ff902b',
|
||||||
warningBorderColor: '#ff8d26',
|
warningBorderColor: '#ff8d26',
|
||||||
warningHoverBackgroundColor: '#ff8517',
|
warningHoverBackgroundColor: '#ff8517',
|
||||||
warningHoverBorderColor: '#fc7800;',
|
warningHoverBorderColor: '#fc7800',
|
||||||
|
|
||||||
dangerBackgroundColor: '#f05050',
|
dangerBackgroundColor: '#f05050',
|
||||||
dangerBorderColor: '#f04b4b',
|
dangerBorderColor: '#f04b4b',
|
||||||
dangerHoverBackgroundColor: '#ee3d3d',
|
dangerHoverBackgroundColor: '#ee3d3d',
|
||||||
dangerHoverBorderColor: '#ec2626;',
|
dangerHoverBorderColor: '#ec2626',
|
||||||
|
|
||||||
iconButtonDisabledColor: '#7a7a7a',
|
iconButtonDisabledColor: '#7a7a7a',
|
||||||
iconButtonHoverColor: '#666',
|
iconButtonHoverColor: '#666',
|
||||||
@@ -226,6 +226,8 @@ module.exports = {
|
|||||||
//
|
//
|
||||||
// Misc
|
// Misc
|
||||||
|
|
||||||
|
progressBarFrontTextColor: white,
|
||||||
|
progressBarBackTextColor: white,
|
||||||
progressBarBackgroundColor: '#727070',
|
progressBarBackgroundColor: '#727070',
|
||||||
logEventsBackgroundColor: '#2a2a2a'
|
logEventsBackgroundColor: '#2a2a2a'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -198,8 +198,8 @@ module.exports = {
|
|||||||
popoverShadowColor: 'rgba(0, 0, 0, 0.2)',
|
popoverShadowColor: 'rgba(0, 0, 0, 0.2)',
|
||||||
popoverArrowBorderColor: '#fff',
|
popoverArrowBorderColor: '#fff',
|
||||||
|
|
||||||
popoverTitleBackgroundInverseColor: '#595959',
|
popoverTitleBackgroundInverseColor: '#9b9b9b',
|
||||||
popoverTitleBorderInverseColor: '#707070',
|
popoverTitleBorderInverseColor: '#bfbfbf',
|
||||||
popoverShadowInverseColor: 'rgba(0, 0, 0, 0.2)',
|
popoverShadowInverseColor: 'rgba(0, 0, 0, 0.2)',
|
||||||
popoverArrowBorderInverseColor: 'rgba(58, 63, 81, 0.75)',
|
popoverArrowBorderInverseColor: 'rgba(58, 63, 81, 0.75)',
|
||||||
|
|
||||||
@@ -227,6 +227,8 @@ module.exports = {
|
|||||||
//
|
//
|
||||||
// Misc
|
// Misc
|
||||||
|
|
||||||
progressBarBackgroundColor: '#fff',
|
progressBarFrontTextColor: white,
|
||||||
logEventsBackgroundColor: '#fff'
|
progressBarBackTextColor: darkGray,
|
||||||
|
progressBarBackgroundColor: white,
|
||||||
|
logEventsBackgroundColor: white
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
|
function formatCustomFormatScore(input, customFormatsLength = 0) {
|
||||||
function formatCustomFormatScore(input) {
|
|
||||||
const score = Number(input);
|
const score = Number(input);
|
||||||
|
|
||||||
if (score > 0) {
|
if (score > 0) {
|
||||||
@@ -10,7 +9,7 @@ function formatCustomFormatScore(input) {
|
|||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return customFormatsLength > 0 ? '+0' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default formatCustomFormatScore;
|
export default formatCustomFormatScore;
|
||||||
|
|||||||
+9
-6
@@ -8,8 +8,8 @@
|
|||||||
"clean": "rimraf ./_output/UI && rimraf \"**/*.js.map\"",
|
"clean": "rimraf ./_output/UI && rimraf \"**/*.js.map\"",
|
||||||
"start": "webpack --watch --config ./frontend/build/webpack.config.js",
|
"start": "webpack --watch --config ./frontend/build/webpack.config.js",
|
||||||
"watch": "webpack --watch --config ./frontend/build/webpack.config.js",
|
"watch": "webpack --watch --config ./frontend/build/webpack.config.js",
|
||||||
"lint": "esprint check",
|
"lint": "eslint --config frontend/.eslintrc.js --ignore-path frontend/.eslintignore frontend/",
|
||||||
"lint-fix": "esprint check --fix",
|
"lint-fix": "yarn lint --fix",
|
||||||
"stylelint-linux": "stylelint $(find frontend -name '*.css') --config frontend/.stylelintrc",
|
"stylelint-linux": "stylelint $(find frontend -name '*.css') --config frontend/.stylelintrc",
|
||||||
"stylelint-windows": "stylelint frontend/**/*.css --config frontend/.stylelintrc"
|
"stylelint-windows": "stylelint frontend/**/*.css --config frontend/.stylelintrc"
|
||||||
},
|
},
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"@fortawesome/free-regular-svg-icons": "6.1.0",
|
"@fortawesome/free-regular-svg-icons": "6.1.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "6.1.0",
|
"@fortawesome/free-solid-svg-icons": "6.1.0",
|
||||||
"@fortawesome/react-fontawesome": "0.1.18",
|
"@fortawesome/react-fontawesome": "0.1.18",
|
||||||
"@microsoft/signalr": "6.0.8",
|
"@microsoft/signalr": "6.0.16",
|
||||||
"@sentry/browser": "6.18.2",
|
"@sentry/browser": "6.18.2",
|
||||||
"@sentry/integrations": "6.18.2",
|
"@sentry/integrations": "6.18.2",
|
||||||
"classnames": "2.3.1",
|
"classnames": "2.3.1",
|
||||||
@@ -108,12 +108,11 @@
|
|||||||
"eslint-plugin-json": "3.1.0",
|
"eslint-plugin-json": "3.1.0",
|
||||||
"eslint-plugin-react": "7.29.4",
|
"eslint-plugin-react": "7.29.4",
|
||||||
"eslint-plugin-react-hooks": "4.6.0",
|
"eslint-plugin-react-hooks": "4.6.0",
|
||||||
"eslint-plugin-simple-import-sort": "7.0.0",
|
"eslint-plugin-simple-import-sort": "8.0.0",
|
||||||
"esprint": "3.3.0",
|
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
"filemanager-webpack-plugin": "5.0.0",
|
"filemanager-webpack-plugin": "5.0.0",
|
||||||
"html-webpack-plugin": "5.3.1",
|
"html-webpack-plugin": "5.3.1",
|
||||||
"loader-utils": "^2.0.0",
|
"loader-utils": "^3.2.1",
|
||||||
"mini-css-extract-plugin": "1.5.0",
|
"mini-css-extract-plugin": "1.5.0",
|
||||||
"postcss": "8.2.12",
|
"postcss": "8.2.12",
|
||||||
"postcss-color-function": "4.1.0",
|
"postcss-color-function": "4.1.0",
|
||||||
@@ -134,5 +133,9 @@
|
|||||||
"webpack-cli": "4.9.1",
|
"webpack-cli": "4.9.1",
|
||||||
"webpack-livereload-plugin": "3.0.2",
|
"webpack-livereload-plugin": "3.0.2",
|
||||||
"worker-loader": "3.0.8"
|
"worker-loader": "3.0.8"
|
||||||
|
},
|
||||||
|
"volta": {
|
||||||
|
"node": "16.17.0",
|
||||||
|
"yarn": "1.22.19"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
is_global = true
|
||||||
|
|
||||||
|
dotnet_diagnostic.CA1014.severity = none
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<!-- Common to all Radarr Projects -->
|
<!-- Common to all Radarr Projects -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<AnalysisLevel>6.0-all</AnalysisLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||||
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
@@ -90,7 +92,7 @@
|
|||||||
|
|
||||||
<!-- Standard testing packages -->
|
<!-- Standard testing packages -->
|
||||||
<ItemGroup Condition="'$(TestProject)'=='true'">
|
<ItemGroup Condition="'$(TestProject)'=='true'">
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||||
<PackageReference Include="NunitXml.TestLogger" Version="3.0.117" />
|
<PackageReference Include="NunitXml.TestLogger" Version="3.0.117" />
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ namespace NzbDrone.Common.Disk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetPathRoot(string path)
|
public virtual string GetPathRoot(string path)
|
||||||
{
|
{
|
||||||
Ensure.That(path, () => path).IsValidPath();
|
Ensure.That(path, () => path).IsValidPath();
|
||||||
|
|
||||||
@@ -483,12 +483,11 @@ namespace NzbDrone.Common.Disk
|
|||||||
|
|
||||||
return mounts.Where(drive => drive.RootDirectory.PathEquals(path) ||
|
return mounts.Where(drive => drive.RootDirectory.PathEquals(path) ||
|
||||||
drive.RootDirectory.IsParentPath(path))
|
drive.RootDirectory.IsParentPath(path))
|
||||||
.OrderByDescending(drive => drive.RootDirectory.Length)
|
.MaxBy(drive => drive.RootDirectory.Length);
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Debug(ex, string.Format("Failed to get mount for path {0}", path));
|
Logger.Debug(ex, $"Failed to get mount for path {path}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
public interface IAppFolderFactory
|
public interface IAppFolderFactory
|
||||||
{
|
{
|
||||||
void Register();
|
void Register();
|
||||||
|
void SetPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppFolderFactory : IAppFolderFactory
|
public class AppFolderFactory : IAppFolderFactory
|
||||||
@@ -58,7 +59,7 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
InitializeMonoApplicationData();
|
InitializeMonoApplicationData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPermissions()
|
public void SetPermissions()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
bool IsAdmin { get; }
|
bool IsAdmin { get; }
|
||||||
bool IsWindowsService { get; }
|
bool IsWindowsService { get; }
|
||||||
bool IsWindowsTray { get; }
|
bool IsWindowsTray { get; }
|
||||||
|
bool IsStarting { get; set; }
|
||||||
bool IsExiting { get; set; }
|
bool IsExiting { get; set; }
|
||||||
bool IsTray { get; }
|
bool IsTray { get; }
|
||||||
RuntimeMode Mode { get; }
|
RuntimeMode Mode { get; }
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
IsWindowsService = hostLifetime is WindowsServiceLifetime;
|
IsWindowsService = hostLifetime is WindowsServiceLifetime;
|
||||||
|
IsStarting = true;
|
||||||
|
|
||||||
// net6.0 will return Radarr.dll for entry assembly, we need the actual
|
// net6.0 will return Radarr.dll for entry assembly, we need the actual
|
||||||
// executable name (Radarr on linux). On mono this will return the location of
|
// executable name (Radarr on linux). On mono this will return the location of
|
||||||
@@ -82,6 +83,7 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
|
|
||||||
public bool IsWindowsService { get; private set; }
|
public bool IsWindowsService { get; private set; }
|
||||||
|
|
||||||
|
public bool IsStarting { get; set; }
|
||||||
public bool IsExiting { get; set; }
|
public bool IsExiting { get; set; }
|
||||||
public bool IsTray
|
public bool IsTray
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ namespace NzbDrone.Common.Extensions
|
|||||||
|
|
||||||
public static string WrapInQuotes(this string text)
|
public static string WrapInQuotes(this string text)
|
||||||
{
|
{
|
||||||
if (!text.Contains(" "))
|
if (!text.Contains(' '))
|
||||||
{
|
{
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ namespace NzbDrone.Common.Extensions
|
|||||||
|
|
||||||
public static string ToUrlHost(this string input)
|
public static string ToUrlHost(this string input)
|
||||||
{
|
{
|
||||||
return input.Contains(":") ? $"[{input}]" : input;
|
return input.Contains(':') ? $"[{input}]" : input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ namespace NzbDrone.Common.Http.Dispatchers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddContentHeader(HttpRequestMessage request, string header, string value)
|
private static void AddContentHeader(HttpRequestMessage request, string header, string value)
|
||||||
{
|
{
|
||||||
var headers = request.Content?.Headers;
|
var headers = request.Content?.Headers;
|
||||||
if (headers == null)
|
if (headers == null)
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ namespace NzbDrone.Common.Http
|
|||||||
|
|
||||||
if (baseSlashIndex >= 0)
|
if (baseSlashIndex >= 0)
|
||||||
{
|
{
|
||||||
return basePath.Substring(0, baseSlashIndex) + "/" + relativePath;
|
return $"{basePath.AsSpan(0, baseSlashIndex)}/{relativePath}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return relativePath;
|
return relativePath;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using System.Threading;
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Common;
|
using NLog.Common;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
|
using Npgsql;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using Sentry;
|
using Sentry;
|
||||||
@@ -34,6 +35,14 @@ namespace NzbDrone.Common.Instrumentation.Sentry
|
|||||||
SQLiteErrorCode.Auth
|
SQLiteErrorCode.Auth
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static readonly HashSet<string> FilteredPostgresErrorCodes = new HashSet<string>
|
||||||
|
{
|
||||||
|
PostgresErrorCodes.OutOfMemory,
|
||||||
|
PostgresErrorCodes.TooManyConnections,
|
||||||
|
PostgresErrorCodes.DiskFull,
|
||||||
|
PostgresErrorCodes.ProgramLimitExceeded
|
||||||
|
};
|
||||||
|
|
||||||
// use string and not Type so we don't need a reference to the project
|
// use string and not Type so we don't need a reference to the project
|
||||||
// where these are defined
|
// where these are defined
|
||||||
private static readonly HashSet<string> FilteredExceptionTypeNames = new HashSet<string>
|
private static readonly HashSet<string> FilteredExceptionTypeNames = new HashSet<string>
|
||||||
@@ -250,6 +259,19 @@ namespace NzbDrone.Common.Instrumentation.Sentry
|
|||||||
isSentry = false;
|
isSentry = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pgEx = logEvent.Exception as PostgresException;
|
||||||
|
if (pgEx != null && FilteredPostgresErrorCodes.Contains(pgEx.SqlState))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't care about transient network and timeout errors
|
||||||
|
var npgEx = logEvent.Exception as NpgsqlException;
|
||||||
|
if (npgEx != null && npgEx.IsTransient)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (FilteredExceptionTypeNames.Contains(ex.GetType().Name))
|
if (FilteredExceptionTypeNames.Contains(ex.GetType().Name))
|
||||||
{
|
{
|
||||||
isSentry = false;
|
isSentry = false;
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ namespace NzbDrone.Common.Processes
|
|||||||
processInfo = new ProcessInfo();
|
processInfo = new ProcessInfo();
|
||||||
processInfo.Id = process.Id;
|
processInfo.Id = process.Id;
|
||||||
processInfo.Name = process.ProcessName;
|
processInfo.Name = process.ProcessName;
|
||||||
processInfo.StartPath = GetExeFileName(process);
|
processInfo.StartPath = process.MainModule.FileName;
|
||||||
|
|
||||||
if (process.Id != GetCurrentProcessId() && process.HasExited)
|
if (process.Id != GetCurrentProcessId() && process.HasExited)
|
||||||
{
|
{
|
||||||
@@ -335,16 +335,6 @@ namespace NzbDrone.Common.Processes
|
|||||||
return processInfo;
|
return processInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetExeFileName(Process process)
|
|
||||||
{
|
|
||||||
if (process.MainModule.FileName != "mono.exe")
|
|
||||||
{
|
|
||||||
return process.MainModule.FileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.Modules.Cast<ProcessModule>().FirstOrDefault(module => module.ModuleName.ToLower().EndsWith(".exe")).FileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Process> GetProcessesByName(string name)
|
private List<Process> GetProcessesByName(string name)
|
||||||
{
|
{
|
||||||
var processes = Process.GetProcessesByName(name).ToList();
|
var processes = Process.GetProcessesByName(name).ToList();
|
||||||
|
|||||||
@@ -4,19 +4,20 @@
|
|||||||
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64'">ISMUSL</DefineConstants>
|
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64'">ISMUSL</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DryIoc.dll" Version="5.3.0" />
|
<PackageReference Include="DryIoc.dll" Version="5.3.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||||
<PackageReference Include="NLog" Version="5.0.1" />
|
<PackageReference Include="NLog" Version="5.0.1" />
|
||||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.0.0" />
|
<PackageReference Include="NLog.Extensions.Logging" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Npgsql" Version="5.0.11" />
|
||||||
<PackageReference Include="Sentry" Version="3.23.1" />
|
<PackageReference Include="Sentry" Version="3.23.1" />
|
||||||
<PackageReference Include="NLog.Targets.Syslog" Version="7.0.0" />
|
<PackageReference Include="NLog.Targets.Syslog" Version="7.0.0" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||||
<PackageReference Include="System.Text.Json" Version="6.0.5" />
|
<PackageReference Include="System.Text.Json" Version="6.0.7" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||||
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
|
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
|
||||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
||||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
|
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace NzbDrone.Common
|
|||||||
|
|
||||||
var args = $"create {serviceName} " +
|
var args = $"create {serviceName} " +
|
||||||
$"DisplayName= \"{serviceName}\" " +
|
$"DisplayName= \"{serviceName}\" " +
|
||||||
$"binpath= \"{Process.GetCurrentProcess().MainModule.FileName}\" " +
|
$"binpath= \"{Environment.ProcessPath}\" " +
|
||||||
"start= auto " +
|
"start= auto " +
|
||||||
"depend= EventLog/Tcpip/http " +
|
"depend= EventLog/Tcpip/http " +
|
||||||
"obj= \"NT AUTHORITY\\LocalService\"";
|
"obj= \"NT AUTHORITY\\LocalService\"";
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace NzbDrone.Common.TPL
|
|||||||
private readonly int _maxDegreeOfParallelism;
|
private readonly int _maxDegreeOfParallelism;
|
||||||
|
|
||||||
/// <summary>Whether the scheduler is currently processing work items.</summary>
|
/// <summary>Whether the scheduler is currently processing work items.</summary>
|
||||||
private int _delegatesQueuedOrRunning = 0;
|
private int _delegatesQueuedOrRunning;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
|
/// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
|
||||||
|
|||||||
@@ -81,8 +81,9 @@ namespace NzbDrone.Core.Test.Blocklisting
|
|||||||
|
|
||||||
Subject.DeleteForMovies(new List<int> { _movie1.Id });
|
Subject.DeleteForMovies(new List<int> { _movie1.Id });
|
||||||
|
|
||||||
var removedMovieBlocklists = Subject.BlocklistedByMovie(_movie1.Id);
|
var blocklist = Subject.All();
|
||||||
var nonRemovedMovieBlocklists = Subject.BlocklistedByMovie(_movie2.Id);
|
var removedMovieBlocklists = blocklist.Where(b => b.MovieId == _movie1.Id);
|
||||||
|
var nonRemovedMovieBlocklists = blocklist.Where(b => b.MovieId == _movie2.Id);
|
||||||
|
|
||||||
removedMovieBlocklists.Should().HaveCount(0);
|
removedMovieBlocklists.Should().HaveCount(0);
|
||||||
nonRemovedMovieBlocklists.Should().HaveCount(1);
|
nonRemovedMovieBlocklists.Should().HaveCount(1);
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@@ -9,7 +9,7 @@ using NzbDrone.Core.Test.Framework;
|
|||||||
namespace NzbDrone.Core.Test.CustomFormats
|
namespace NzbDrone.Core.Test.CustomFormats
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class CustomFormatsFixture : CoreTest
|
public class CustomFormatsTestHelpers : CoreTest
|
||||||
{
|
{
|
||||||
private static List<CustomFormat> _customFormats { get; set; }
|
private static List<CustomFormat> _customFormats { get; set; }
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class custom_formatsFixture : MigrationTest<add_custom_formats>
|
public class custom_formatsFixture : MigrationTest<add_custom_formats>
|
||||||
{
|
{
|
||||||
public static Dictionary<int, int> QualityToDefinition = null;
|
public static Dictionary<int, int> QualityToDefinition;
|
||||||
|
|
||||||
public void AddDefaultProfile(add_custom_formats m, string name, Quality cutoff, params Quality[] allowed)
|
public void AddDefaultProfile(add_custom_formats m, string name, Quality cutoff, params Quality[] allowed)
|
||||||
{
|
{
|
||||||
|
|||||||
+7
-7
@@ -46,14 +46,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
ParsedMovieInfo = new ParsedMovieInfo { Quality = new QualityModel(Quality.DVD, new Revision(version: 2)) },
|
ParsedMovieInfo = new ParsedMovieInfo { Quality = new QualityModel(Quality.DVD, new Revision(version: 2)) },
|
||||||
};
|
};
|
||||||
|
|
||||||
CustomFormatsFixture.GivenCustomFormats(_format1, _format2);
|
CustomFormatsTestHelpers.GivenCustomFormats(_format1, _format2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_allow_if_format_score_greater_than_min()
|
public void should_allow_if_format_score_greater_than_min()
|
||||||
{
|
{
|
||||||
_remoteMovie.CustomFormats = new List<CustomFormat> { _format1 };
|
_remoteMovie.CustomFormats = new List<CustomFormat> { _format1 };
|
||||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
|
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
|
||||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue();
|
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue();
|
||||||
@@ -63,7 +63,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
public void should_deny_if_format_score_not_greater_than_min()
|
public void should_deny_if_format_score_not_greater_than_min()
|
||||||
{
|
{
|
||||||
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2 };
|
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2 };
|
||||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
|
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
|
||||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||||
|
|
||||||
Console.WriteLine(_remoteMovie.CustomFormatScore);
|
Console.WriteLine(_remoteMovie.CustomFormatScore);
|
||||||
@@ -76,7 +76,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
public void should_deny_if_format_score_not_greater_than_min_2()
|
public void should_deny_if_format_score_not_greater_than_min_2()
|
||||||
{
|
{
|
||||||
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2, _format1 };
|
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2, _format1 };
|
||||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
|
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
|
||||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse();
|
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse();
|
||||||
@@ -86,7 +86,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
public void should_allow_if_all_format_is_defined_in_profile()
|
public void should_allow_if_all_format_is_defined_in_profile()
|
||||||
{
|
{
|
||||||
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2, _format1 };
|
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2, _format1 };
|
||||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
|
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue();
|
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue();
|
||||||
@@ -96,7 +96,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
public void should_deny_if_no_format_was_parsed_and_min_score_positive()
|
public void should_deny_if_no_format_was_parsed_and_min_score_positive()
|
||||||
{
|
{
|
||||||
_remoteMovie.CustomFormats = new List<CustomFormat> { };
|
_remoteMovie.CustomFormats = new List<CustomFormat> { };
|
||||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
|
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse();
|
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse();
|
||||||
@@ -106,7 +106,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
public void should_allow_if_no_format_was_parsed_min_score_is_zero()
|
public void should_allow_if_no_format_was_parsed_min_score_is_zero()
|
||||||
{
|
{
|
||||||
_remoteMovie.CustomFormats = new List<CustomFormat> { };
|
_remoteMovie.CustomFormats = new List<CustomFormat> { };
|
||||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
|
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||||
_remoteMovie.Movie.Profile.MinFormatScore = 0;
|
_remoteMovie.Movie.Profile.MinFormatScore = 0;
|
||||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
|
|
||||||
private void GivenProfile(Profile profile)
|
private void GivenProfile(Profile profile)
|
||||||
{
|
{
|
||||||
CustomFormatsFixture.GivenCustomFormats();
|
CustomFormatsTestHelpers.GivenCustomFormats();
|
||||||
profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems();
|
profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems();
|
||||||
profile.MinFormatScore = 0;
|
profile.MinFormatScore = 0;
|
||||||
_remoteMovie.Movie.Profile = profile;
|
_remoteMovie.Movie.Profile = profile;
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
{
|
{
|
||||||
_customFormat = new CustomFormat("My Format", new ResolutionSpecification { Value = (int)Resolution.R1080p }) { Id = 1 };
|
_customFormat = new CustomFormat("My Format", new ResolutionSpecification { Value = (int)Resolution.R1080p }) { Id = 1 };
|
||||||
|
|
||||||
CustomFormatsFixture.GivenCustomFormats(_customFormat);
|
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -157,7 +157,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
Cutoff = Quality.HDTV720p.Id,
|
Cutoff = Quality.HDTV720p.Id,
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
MinFormatScore = 0,
|
MinFormatScore = 0,
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems("My Format"),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems("My Format"),
|
||||||
UpgradeAllowed = true
|
UpgradeAllowed = true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
Mocker.Resolve<UpgradableSpecification>();
|
Mocker.Resolve<UpgradableSpecification>();
|
||||||
_upgradeHistory = Mocker.Resolve<HistorySpecification>();
|
_upgradeHistory = Mocker.Resolve<HistorySpecification>();
|
||||||
|
|
||||||
CustomFormatsFixture.GivenCustomFormats();
|
CustomFormatsTestHelpers.GivenCustomFormats();
|
||||||
|
|
||||||
_fakeMovie = Builder<Movie>.CreateNew()
|
_fakeMovie = Builder<Movie>.CreateNew()
|
||||||
.With(c => c.Profile = new Profile
|
.With(c => c.Profile = new Profile
|
||||||
{
|
{
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
Cutoff = Quality.Bluray1080p.Id,
|
Cutoff = Quality.Bluray1080p.Id,
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems("None"),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems("None"),
|
||||||
MinFormatScore = 0,
|
MinFormatScore = 0,
|
||||||
UpgradeAllowed = true
|
UpgradeAllowed = true
|
||||||
})
|
})
|
||||||
@@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||||
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>()))
|
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>(), It.IsAny<Movie>()))
|
||||||
.Returns(new List<CustomFormat>());
|
.Returns(new List<CustomFormat>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
{
|
{
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
Cutoff = Quality.Bluray1080p.Id,
|
Cutoff = Quality.Bluray1080p.Id,
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||||
MinFormatScore = 0
|
MinFormatScore = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
_upgradableQuality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1));
|
_upgradableQuality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1));
|
||||||
|
|
||||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||||
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>()))
|
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>(), It.IsAny<Movie>()))
|
||||||
.Returns(new List<CustomFormat>());
|
.Returns(new List<CustomFormat>());
|
||||||
|
|
||||||
GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, MovieHistoryEventType.Grabbed);
|
GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, MovieHistoryEventType.Grabbed);
|
||||||
@@ -186,7 +186,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
{
|
{
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
Cutoff = Quality.WEBDL1080p.Id,
|
Cutoff = Quality.WEBDL1080p.Id,
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||||
MinFormatScore = 0
|
MinFormatScore = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,7 +221,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
{
|
{
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
Cutoff = Quality.WEBDL1080p.Id,
|
Cutoff = Quality.WEBDL1080p.Id,
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||||
MinFormatScore = 0
|
MinFormatScore = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,17 +41,17 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
|
|
||||||
private void WithEnglishRelease()
|
private void WithEnglishRelease()
|
||||||
{
|
{
|
||||||
_remoteMovie.ParsedMovieInfo.Languages = new List<Language> { Language.English };
|
_remoteMovie.Languages = new List<Language> { Language.English };
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithGermanRelease()
|
private void WithGermanRelease()
|
||||||
{
|
{
|
||||||
_remoteMovie.ParsedMovieInfo.Languages = new List<Language> { Language.German };
|
_remoteMovie.Languages = new List<Language> { Language.German };
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithFrenchRelease()
|
private void WithFrenchRelease()
|
||||||
{
|
{
|
||||||
_remoteMovie.ParsedMovieInfo.Languages = new List<Language> { Language.French };
|
_remoteMovie.Languages = new List<Language> { Language.French };
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
_customFormat1 = new CustomFormat("My Format 1", new LanguageSpecification { Value = (int)Language.English }) { Id = 1 };
|
_customFormat1 = new CustomFormat("My Format 1", new LanguageSpecification { Value = (int)Language.English }) { Id = 1 };
|
||||||
_customFormat2 = new CustomFormat("My Format 2", new LanguageSpecification { Value = (int)Language.French }) { Id = 2 };
|
_customFormat2 = new CustomFormat("My Format 2", new LanguageSpecification { Value = (int)Language.French }) { Id = 2 };
|
||||||
|
|
||||||
CustomFormatsFixture.GivenCustomFormats(_customFormat1, _customFormat2);
|
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat1, _customFormat2);
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>()
|
Mocker.GetMock<IQualityDefinitionService>()
|
||||||
.Setup(s => s.Get(It.IsAny<Quality>()))
|
.Setup(s => s.Get(It.IsAny<Quality>()))
|
||||||
@@ -62,7 +62,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
remoteMovie.Movie = Builder<Movie>.CreateNew().With(m => m.Profile = new Profile
|
remoteMovie.Movie = Builder<Movie>.CreateNew().With(m => m.Profile = new Profile
|
||||||
{
|
{
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
|
||||||
MinFormatScore = 0
|
MinFormatScore = 0
|
||||||
})
|
})
|
||||||
.With(m => m.Title = "A Movie")
|
.With(m => m.Title = "A Movie")
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
CustomFormatsFixture.GivenCustomFormats(_customFormat1, _customFormat2);
|
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat1, _customFormat2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenAutoDownloadPropers(ProperDownloadTypes type)
|
private void GivenAutoDownloadPropers(ProperDownloadTypes type)
|
||||||
@@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
var profile = new Profile
|
var profile = new Profile
|
||||||
{
|
{
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
|
||||||
MinFormatScore = 0
|
MinFormatScore = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ using FizzWare.NBuilder;
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.CustomFormats;
|
using NzbDrone.Core.CustomFormats;
|
||||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||||
using NzbDrone.Core.Download.TrackedDownloads;
|
using NzbDrone.Core.Download.TrackedDownloads;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.Movies;
|
using NzbDrone.Core.Movies;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Profiles;
|
using NzbDrone.Core.Profiles;
|
||||||
@@ -32,13 +34,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
{
|
{
|
||||||
Mocker.Resolve<UpgradableSpecification>();
|
Mocker.Resolve<UpgradableSpecification>();
|
||||||
|
|
||||||
CustomFormatsFixture.GivenCustomFormats();
|
CustomFormatsTestHelpers.GivenCustomFormats();
|
||||||
|
|
||||||
_movie = Builder<Movie>.CreateNew()
|
_movie = Builder<Movie>.CreateNew()
|
||||||
.With(e => e.Profile = new Profile
|
.With(e => e.Profile = new Profile
|
||||||
{
|
{
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||||
MinFormatScore = 0,
|
MinFormatScore = 0,
|
||||||
UpgradeAllowed = true
|
UpgradeAllowed = true
|
||||||
})
|
})
|
||||||
@@ -58,7 +60,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||||
.Setup(x => x.ParseCustomFormat(It.IsAny<ParsedMovieInfo>(), _movie))
|
.Setup(x => x.ParseCustomFormat(It.IsAny<RemoteMovie>(), It.IsAny<long>()))
|
||||||
.Returns(new List<CustomFormat>());
|
.Returns(new List<CustomFormat>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,5 +206,31 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
|
|
||||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue();
|
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_same_quality_non_proper_in_queue_and_download_propers_is_do_not_upgrade()
|
||||||
|
{
|
||||||
|
_remoteMovie.ParsedMovieInfo.Quality = new QualityModel(Quality.HDTV720p, new Revision(2));
|
||||||
|
_movie.Profile.Cutoff = _remoteMovie.ParsedMovieInfo.Quality.Quality.Id;
|
||||||
|
|
||||||
|
Mocker.GetMock<IConfigService>()
|
||||||
|
.Setup(s => s.DownloadPropersAndRepacks)
|
||||||
|
.Returns(ProperDownloadTypes.DoNotUpgrade);
|
||||||
|
|
||||||
|
var remoteMovie = Builder<RemoteMovie>.CreateNew()
|
||||||
|
.With(r => r.Movie = _movie)
|
||||||
|
.With(r => r.ParsedMovieInfo = new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
Quality = new QualityModel(Quality.HDTV720p),
|
||||||
|
Languages = new List<Language> { Language.English }
|
||||||
|
})
|
||||||
|
.With(r => r.Release = _releaseInfo)
|
||||||
|
.With(r => r.CustomFormats = new List<CustomFormat>())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteMovie> { remoteMovie });
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,209 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||||
|
using NzbDrone.Core.Profiles;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class UpgradeAllowedSpecificationFixture : CoreTest<UpgradableSpecification>
|
||||||
|
{
|
||||||
|
private CustomFormat _customFormatOne;
|
||||||
|
private CustomFormat _customFormatTwo;
|
||||||
|
private Profile _qualityProfile;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_customFormatOne = new CustomFormat
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Name = "One"
|
||||||
|
};
|
||||||
|
_customFormatTwo = new CustomFormat
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Name = "Two"
|
||||||
|
};
|
||||||
|
|
||||||
|
_qualityProfile = new Profile
|
||||||
|
{
|
||||||
|
Cutoff = Quality.Bluray1080p.Id,
|
||||||
|
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
|
UpgradeAllowed = false,
|
||||||
|
CutoffFormatScore = 100,
|
||||||
|
FormatItems = new List<ProfileFormatItem>
|
||||||
|
{
|
||||||
|
new ProfileFormatItem
|
||||||
|
{
|
||||||
|
Format = _customFormatOne,
|
||||||
|
Score = 50
|
||||||
|
},
|
||||||
|
new ProfileFormatItem
|
||||||
|
{
|
||||||
|
Format = _customFormatTwo,
|
||||||
|
Score = 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_when_quality_is_better_custom_formats_are_the_same_and_upgrading_is_not_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = false;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat>(),
|
||||||
|
new QualityModel(Quality.Bluray1080p),
|
||||||
|
new List<CustomFormat>())
|
||||||
|
.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_when_quality_is_same_and_custom_format_is_upgrade_and_upgrading_is_not_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = false;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatOne },
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatTwo })
|
||||||
|
.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_custom_format_upgrade_when_upgrading_is_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = true;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatOne },
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatTwo })
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_same_custom_format_score_when_upgrading_is_not_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = false;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatOne },
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatOne })
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_lower_custom_format_score_when_upgrading_is_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = true;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatTwo },
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatOne })
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_lower_language_when_upgrading_is_not_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = false;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatTwo },
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat> { _customFormatOne })
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_quality_upgrade_when_upgrading_is_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = true;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat>(),
|
||||||
|
new QualityModel(Quality.Bluray1080p),
|
||||||
|
new List<CustomFormat>())
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_same_quality_when_upgrading_is_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = true;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat>(),
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat>())
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_same_quality_when_upgrading_is_not_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = false;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat>(),
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat>())
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_lower_quality_when_upgrading_is_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = true;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat>(),
|
||||||
|
new QualityModel(Quality.SDTV),
|
||||||
|
new List<CustomFormat>())
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_for_lower_quality_when_upgrading_is_not_allowed()
|
||||||
|
{
|
||||||
|
_qualityProfile.UpgradeAllowed = false;
|
||||||
|
|
||||||
|
Subject.IsUpgradeAllowed(
|
||||||
|
_qualityProfile,
|
||||||
|
new QualityModel(Quality.DVD),
|
||||||
|
new List<CustomFormat>(),
|
||||||
|
new QualityModel(Quality.SDTV),
|
||||||
|
new List<CustomFormat>())
|
||||||
|
.Should().BeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
Mocker.Resolve<UpgradableSpecification>();
|
Mocker.Resolve<UpgradableSpecification>();
|
||||||
_upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>();
|
_upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>();
|
||||||
|
|
||||||
CustomFormatsFixture.GivenCustomFormats();
|
CustomFormatsTestHelpers.GivenCustomFormats();
|
||||||
|
|
||||||
_firstFile = new MovieFile { Quality = new QualityModel(Quality.Bluray1080p, new Revision(version: 2)), DateAdded = DateTime.Now };
|
_firstFile = new MovieFile { Quality = new QualityModel(Quality.Bluray1080p, new Revision(version: 2)), DateAdded = DateTime.Now };
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
.With(c => c.Profile = new Profile
|
.With(c => c.Profile = new Profile
|
||||||
{
|
{
|
||||||
Cutoff = Quality.Bluray1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(),
|
Cutoff = Quality.Bluray1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||||
MinFormatScore = 0
|
MinFormatScore = 0
|
||||||
})
|
})
|
||||||
.With(e => e.MovieFile = _firstFile)
|
.With(e => e.MovieFile = _firstFile)
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Download.Aggregation.Aggregators;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.Movies;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class AggregateLanguagesFixture : CoreTest<AggregateLanguages>
|
||||||
|
{
|
||||||
|
private RemoteMovie _remoteMovie;
|
||||||
|
private Movie _movie;
|
||||||
|
private string _simpleReleaseTitle = "Series.Title.S01E01.xyz-RlsGroup";
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_movie = Builder<Movie>.CreateNew()
|
||||||
|
.With(m => m.MovieMetadata = new MovieMetadata
|
||||||
|
{
|
||||||
|
Title = "Some Movie",
|
||||||
|
OriginalLanguage = Language.English
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_remoteMovie = Builder<RemoteMovie>.CreateNew()
|
||||||
|
.With(l => l.ParsedMovieInfo = null)
|
||||||
|
.With(l => l.Movie = _movie)
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParsedMovieInfo GetParsedMovieInfo(List<Language> languages, string releaseTitle, string releaseTokens = "")
|
||||||
|
{
|
||||||
|
return new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
Languages = languages,
|
||||||
|
ReleaseTitle = releaseTitle,
|
||||||
|
SimpleReleaseTitle = releaseTokens
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_existing_language_if_episode_title_does_not_have_language()
|
||||||
|
{
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Original }, _simpleReleaseTitle);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Contain(_movie.MovieMetadata.Value.OriginalLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_parsed_language()
|
||||||
|
{
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.French }, _simpleReleaseTitle);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(_remoteMovie.ParsedMovieInfo.Languages);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_exclude_language_that_is_part_of_episode_title_when_release_tokens_contains_episode_title()
|
||||||
|
{
|
||||||
|
var releaseTitle = "Series.Title.S01E01.Jimmy.The.Greek.xyz-RlsGroup";
|
||||||
|
var releaseTokens = ".Jimmy.The.Greek.xyz-RlsGroup";
|
||||||
|
|
||||||
|
_remoteMovie.Movie.Title = "Jimmy The Greek";
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(_movie.MovieMetadata.Value.OriginalLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_remove_parsed_language_that_is_part_of_episode_title_when_release_tokens_contains_episode_title()
|
||||||
|
{
|
||||||
|
var releaseTitle = "Series.Title.S01E01.Jimmy.The.Greek.French.xyz-RlsGroup";
|
||||||
|
var releaseTokens = ".Jimmy.The.Greek.French.xyz-RlsGroup";
|
||||||
|
|
||||||
|
_remoteMovie.Movie.Title = "Jimmy The Greek";
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Greek, Language.French }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(Language.French);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_exclude_language_that_is_part_of_episode_title_when_release_tokens_does_not_contain_episode_title()
|
||||||
|
{
|
||||||
|
var releaseTitle = "Series.Title.S01E01.xyz-RlsGroup";
|
||||||
|
var releaseTokens = ".xyz-RlsGroup";
|
||||||
|
|
||||||
|
_remoteMovie.Movie.Title = "Jimmy The Greek";
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(Language.Greek);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_reparse_language_after_determining_languages_that_are_in_episode_titles()
|
||||||
|
{
|
||||||
|
var releaseTitle = "Series.Title.S01E01.Jimmy.The.Greek.Greek.xyz-RlsGroup";
|
||||||
|
var releaseTokens = ".Jimmy.The.Greek.Greek.xyz-RlsGroup";
|
||||||
|
|
||||||
|
_remoteMovie.Movie.Title = "Jimmy The Greek";
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(Language.Greek);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests
|
|||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
Mocker.GetMock<IHttpClient>()
|
||||||
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[0]));
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), Array.Empty<byte>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void GivenCategory()
|
protected void GivenCategory()
|
||||||
|
|||||||
+22
-1
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
@@ -275,7 +276,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
|||||||
|
|
||||||
[TestCase(-1)] // Infinite/Unknown
|
[TestCase(-1)] // Infinite/Unknown
|
||||||
[TestCase(-2)] // Magnet Downloading
|
[TestCase(-2)] // Magnet Downloading
|
||||||
public void should_ignore_negative_eta(int eta)
|
public void should_ignore_negative_eta(long eta)
|
||||||
{
|
{
|
||||||
_completed.Eta = eta;
|
_completed.Eta = eta;
|
||||||
|
|
||||||
@@ -284,6 +285,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
|||||||
item.RemainingTime.Should().NotHaveValue();
|
item.RemainingTime.Should().NotHaveValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase(2147483648)] // 2038-01-19T03:14:08Z > int.MaxValue as unix timestamp can be either an int or a long
|
||||||
|
public void should_support_long_values_for_eta_in_seconds(long eta)
|
||||||
|
{
|
||||||
|
_downloading.Eta = eta;
|
||||||
|
|
||||||
|
PrepareClientToReturnDownloadingItem();
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.RemainingTime.Should().Be(TimeSpan.FromSeconds(eta));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(2147483648000)] // works with milliseconds format too
|
||||||
|
public void should_support_long_values_for_eta_in_milliseconds(long eta)
|
||||||
|
{
|
||||||
|
_downloading.Eta = eta;
|
||||||
|
|
||||||
|
PrepareClientToReturnDownloadingItem();
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.RemainingTime.Should().Be(TimeSpan.FromMilliseconds(eta));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_reached_and_not_stopped()
|
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_reached_and_not_stopped()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
|||||||
|
|
||||||
[TestCase(-1)] // Infinite/Unknown
|
[TestCase(-1)] // Infinite/Unknown
|
||||||
[TestCase(-2)] // Magnet Downloading
|
[TestCase(-2)] // Magnet Downloading
|
||||||
public void should_ignore_negative_eta(int eta)
|
public void should_ignore_negative_eta(long eta)
|
||||||
{
|
{
|
||||||
_completed.Eta = eta;
|
_completed.Eta = eta;
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.Download
|
|||||||
_downloadClients = new List<IDownloadClient>();
|
_downloadClients = new List<IDownloadClient>();
|
||||||
|
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(v => v.GetDownloadClients())
|
.Setup(v => v.GetDownloadClients(It.IsAny<bool>()))
|
||||||
.Returns(_downloadClients);
|
.Returns(_downloadClients);
|
||||||
|
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
|
|||||||
+1
@@ -54,6 +54,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||||||
Id = id,
|
Id = id,
|
||||||
Title = "Movie.Title.2020.720p-Radarr",
|
Title = "Movie.Title.2020.720p-Radarr",
|
||||||
ParsedMovieInfo = new ParsedMovieInfo { MovieTitles = new List<string> { title }, Year = year },
|
ParsedMovieInfo = new ParsedMovieInfo { MovieTitles = new List<string> { title }, Year = year },
|
||||||
|
Release = Builder<ReleaseInfo>.CreateNew().Build(),
|
||||||
MovieId = _movie.Id
|
MovieId = _movie.Id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace NzbDrone.Core.Test.Extras.Others
|
|||||||
|
|
||||||
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
||||||
|
|
||||||
results.Count().Should().Be(1);
|
results.Count.Should().Be(1);
|
||||||
|
|
||||||
results[0].RelativePath.AsOsAgnostic().PathEquals(expectedOutputPath.AsOsAgnostic()).Should().Be(true);
|
results[0].RelativePath.AsOsAgnostic().PathEquals(expectedOutputPath.AsOsAgnostic()).Should().Be(true);
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ namespace NzbDrone.Core.Test.Extras.Others
|
|||||||
|
|
||||||
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
||||||
|
|
||||||
results.Count().Should().Be(1);
|
results.Count.Should().Be(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.Extras.Subtitles
|
|||||||
|
|
||||||
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
||||||
|
|
||||||
results.Count().Should().Be(0);
|
results.Count.Should().Be(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -84,7 +84,7 @@ namespace NzbDrone.Core.Test.Extras.Subtitles
|
|||||||
|
|
||||||
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
||||||
|
|
||||||
results.Count().Should().Be(1);
|
results.Count.Should().Be(1);
|
||||||
|
|
||||||
results[0].RelativePath.AsOsAgnostic().PathEquals(expectedOutputPath.AsOsAgnostic()).Should().Be(true);
|
results[0].RelativePath.AsOsAgnostic().PathEquals(expectedOutputPath.AsOsAgnostic()).Should().Be(true);
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ namespace NzbDrone.Core.Test.Extras.Subtitles
|
|||||||
|
|
||||||
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
||||||
|
|
||||||
results.Count().Should().Be(expectedOutputs.Length);
|
results.Count.Should().Be(expectedOutputs.Length);
|
||||||
|
|
||||||
for (int i = 0; i < expectedOutputs.Length; i++)
|
for (int i = 0; i < expectedOutputs.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -139,7 +139,7 @@ namespace NzbDrone.Core.Test.Extras.Subtitles
|
|||||||
|
|
||||||
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
var results = Subject.ImportFiles(_localMovie, _movieFile, files, true).ToList();
|
||||||
|
|
||||||
results.Count().Should().Be(expectedOutputs.Length);
|
results.Count.Should().Be(expectedOutputs.Length);
|
||||||
|
|
||||||
for (int i = 0; i < expectedOutputs.Length; i++)
|
for (int i = 0; i < expectedOutputs.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -169,7 +169,7 @@ namespace NzbDrone.Core.Test.Extras.Subtitles
|
|||||||
|
|
||||||
var results = Subject.ImportFiles(_localMovie, _movieFile, new List<string> { subtitleFile }, true).ToList();
|
var results = Subject.ImportFiles(_localMovie, _movieFile, new List<string> { subtitleFile }, true).ToList();
|
||||||
|
|
||||||
results.Count().Should().Be(1);
|
results.Count.Should().Be(1);
|
||||||
|
|
||||||
results[0].RelativePath.AsOsAgnostic().PathEquals(expectedOutputPath.AsOsAgnostic()).Should().Be(true);
|
results[0].RelativePath.AsOsAgnostic().PathEquals(expectedOutputPath.AsOsAgnostic()).Should().Be(true);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
public void should_return_warning_when_download_client_has_not_been_configured()
|
public void should_return_warning_when_download_client_has_not_been_configured()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(s => s.GetDownloadClients())
|
.Setup(s => s.GetDownloadClients(It.IsAny<bool>()))
|
||||||
.Returns(Array.Empty<IDownloadClient>());
|
.Returns(Array.Empty<IDownloadClient>());
|
||||||
|
|
||||||
Subject.Check().ShouldBeWarning();
|
Subject.Check().ShouldBeWarning();
|
||||||
@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
.Throws<Exception>();
|
.Throws<Exception>();
|
||||||
|
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(s => s.GetDownloadClients())
|
.Setup(s => s.GetDownloadClients(It.IsAny<bool>()))
|
||||||
.Returns(new IDownloadClient[] { downloadClient.Object });
|
.Returns(new IDownloadClient[] { downloadClient.Object });
|
||||||
|
|
||||||
Subject.Check().ShouldBeError();
|
Subject.Check().ShouldBeError();
|
||||||
@@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
.Returns(new List<DownloadClientItem>());
|
.Returns(new List<DownloadClientItem>());
|
||||||
|
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(s => s.GetDownloadClients())
|
.Setup(s => s.GetDownloadClients(It.IsAny<bool>()))
|
||||||
.Returns(new IDownloadClient[] { downloadClient.Object });
|
.Returns(new IDownloadClient[] { downloadClient.Object });
|
||||||
|
|
||||||
Subject.Check().ShouldBeOk();
|
Subject.Check().ShouldBeOk();
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
.Returns(_clientStatus);
|
.Returns(_clientStatus);
|
||||||
|
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(s => s.GetDownloadClients())
|
.Setup(s => s.GetDownloadClients(It.IsAny<bool>()))
|
||||||
.Returns(new IDownloadClient[] { _downloadClient.Object });
|
.Returns(new IDownloadClient[] { _downloadClient.Object });
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Download.Clients;
|
||||||
|
using NzbDrone.Core.HealthCheck.Checks;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
|
using NzbDrone.Core.RootFolders;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class DownloadClientFolderCheckFixture : CoreTest<DownloadClientSortingCheck>
|
||||||
|
{
|
||||||
|
private DownloadClientInfo _clientStatus;
|
||||||
|
private Mock<IDownloadClient> _downloadClient;
|
||||||
|
|
||||||
|
private static Exception[] DownloadClientExceptions =
|
||||||
|
{
|
||||||
|
new DownloadClientUnavailableException("error"),
|
||||||
|
new DownloadClientAuthenticationException("error"),
|
||||||
|
new DownloadClientException("error")
|
||||||
|
};
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ILocalizationService>()
|
||||||
|
.Setup(s => s.GetLocalizedString(It.IsAny<string>()))
|
||||||
|
.Returns("Some Warning Message");
|
||||||
|
|
||||||
|
_clientStatus = new DownloadClientInfo
|
||||||
|
{
|
||||||
|
IsLocalhost = true,
|
||||||
|
SortingMode = null
|
||||||
|
};
|
||||||
|
|
||||||
|
_downloadClient = Mocker.GetMock<IDownloadClient>();
|
||||||
|
_downloadClient.Setup(s => s.Definition)
|
||||||
|
.Returns(new DownloadClientDefinition { Name = "Test" });
|
||||||
|
|
||||||
|
_downloadClient.Setup(s => s.GetStatus())
|
||||||
|
.Returns(_clientStatus);
|
||||||
|
|
||||||
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
|
.Setup(s => s.GetDownloadClients(It.IsAny<bool>()))
|
||||||
|
.Returns(new IDownloadClient[] { _downloadClient.Object });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_ok_if_sorting_is_not_enabled()
|
||||||
|
{
|
||||||
|
Subject.Check().ShouldBeOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_warning_if_sorting_is_enabled()
|
||||||
|
{
|
||||||
|
_clientStatus.SortingMode = "TV";
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeWarning();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[TestCaseSource("DownloadClientExceptions")]
|
||||||
|
public void should_return_ok_if_client_throws_downloadclientexception(Exception ex)
|
||||||
|
{
|
||||||
|
_downloadClient.Setup(s => s.GetStatus())
|
||||||
|
.Throws(ex);
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeOk();
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedErrors(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,7 +63,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
.Returns(_clientStatus);
|
.Returns(_clientStatus);
|
||||||
|
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(s => s.GetDownloadClients())
|
.Setup(s => s.GetDownloadClients(It.IsAny<bool>()))
|
||||||
.Returns(new IDownloadClient[] { _downloadClient.Object });
|
.Returns(new IDownloadClient[] { _downloadClient.Object });
|
||||||
|
|
||||||
Mocker.GetMock<IConfigService>()
|
Mocker.GetMock<IConfigService>()
|
||||||
|
|||||||
+133
@@ -0,0 +1,133 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Housekeeping.Housekeepers;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Profiles;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CleanupQualityProfileFormatItemsFixture : DbTest<CleanupQualityProfileFormatItems, Profile>
|
||||||
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
Mocker.SetConstant<IQualityProfileFormatItemsCleanupRepository>(
|
||||||
|
new QualityProfileFormatItemsCleanupRepository(Mocker.Resolve<IMainDatabase>(), Mocker.Resolve<IEventAggregator>()));
|
||||||
|
|
||||||
|
Mocker.SetConstant<ICustomFormatRepository>(
|
||||||
|
new CustomFormatRepository(Mocker.Resolve<IMainDatabase>(), Mocker.Resolve<IEventAggregator>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_remove_orphaned_custom_formats()
|
||||||
|
{
|
||||||
|
var qualityProfile = Builder<Profile>.CreateNew()
|
||||||
|
.With(h => h.Items = Qualities.QualityFixture.GetDefaultQualities())
|
||||||
|
.With(h => h.MinFormatScore = 50)
|
||||||
|
.With(h => h.CutoffFormatScore = 100)
|
||||||
|
.With(h => h.FormatItems = new List<ProfileFormatItem>
|
||||||
|
{
|
||||||
|
Builder<ProfileFormatItem>.CreateNew()
|
||||||
|
.With(c => c.Format = new CustomFormat("My Custom Format") { Id = 0 })
|
||||||
|
.Build()
|
||||||
|
})
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(qualityProfile);
|
||||||
|
Subject.Clean();
|
||||||
|
|
||||||
|
var result = AllStoredModels;
|
||||||
|
|
||||||
|
result.Should().HaveCount(1);
|
||||||
|
result.First().FormatItems.Should().BeEmpty();
|
||||||
|
result.First().MinFormatScore.Should().Be(0);
|
||||||
|
result.First().CutoffFormatScore.Should().Be(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_remove_unorphaned_custom_formats()
|
||||||
|
{
|
||||||
|
var minFormatScore = 50;
|
||||||
|
var cutoffFormatScore = 100;
|
||||||
|
|
||||||
|
var customFormat = Builder<CustomFormat>.CreateNew()
|
||||||
|
.With(h => h.Specifications = new List<ICustomFormatSpecification>())
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(customFormat);
|
||||||
|
|
||||||
|
var qualityProfile = Builder<Profile>.CreateNew()
|
||||||
|
.With(h => h.Items = Qualities.QualityFixture.GetDefaultQualities())
|
||||||
|
.With(h => h.MinFormatScore = minFormatScore)
|
||||||
|
.With(h => h.CutoffFormatScore = cutoffFormatScore)
|
||||||
|
.With(h => h.FormatItems = new List<ProfileFormatItem>
|
||||||
|
{
|
||||||
|
Builder<ProfileFormatItem>.CreateNew()
|
||||||
|
.With(c => c.Format = customFormat)
|
||||||
|
.Build()
|
||||||
|
})
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(qualityProfile);
|
||||||
|
|
||||||
|
Subject.Clean();
|
||||||
|
var result = AllStoredModels;
|
||||||
|
|
||||||
|
result.Should().HaveCount(1);
|
||||||
|
result.First().FormatItems.Should().HaveCount(1);
|
||||||
|
result.First().MinFormatScore.Should().Be(minFormatScore);
|
||||||
|
result.First().CutoffFormatScore.Should().Be(cutoffFormatScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_add_missing_custom_formats()
|
||||||
|
{
|
||||||
|
var minFormatScore = 50;
|
||||||
|
var cutoffFormatScore = 100;
|
||||||
|
|
||||||
|
var customFormat1 = Builder<CustomFormat>.CreateNew()
|
||||||
|
.With(h => h.Id = 1)
|
||||||
|
.With(h => h.Name = "Custom Format 1")
|
||||||
|
.With(h => h.Specifications = new List<ICustomFormatSpecification>())
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
var customFormat2 = Builder<CustomFormat>.CreateNew()
|
||||||
|
.With(h => h.Id = 2)
|
||||||
|
.With(h => h.Name = "Custom Format 2")
|
||||||
|
.With(h => h.Specifications = new List<ICustomFormatSpecification>())
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(customFormat1);
|
||||||
|
Db.Insert(customFormat2);
|
||||||
|
|
||||||
|
var qualityProfile = Builder<Profile>.CreateNew()
|
||||||
|
.With(h => h.Items = Qualities.QualityFixture.GetDefaultQualities())
|
||||||
|
.With(h => h.MinFormatScore = minFormatScore)
|
||||||
|
.With(h => h.CutoffFormatScore = cutoffFormatScore)
|
||||||
|
.With(h => h.FormatItems = new List<ProfileFormatItem>
|
||||||
|
{
|
||||||
|
Builder<ProfileFormatItem>.CreateNew()
|
||||||
|
.With(c => c.Format = customFormat1)
|
||||||
|
.Build()
|
||||||
|
})
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(qualityProfile);
|
||||||
|
|
||||||
|
Subject.Clean();
|
||||||
|
var result = AllStoredModels;
|
||||||
|
|
||||||
|
result.Should().HaveCount(1);
|
||||||
|
result.First().FormatItems.Should().HaveCount(2);
|
||||||
|
result.First().MinFormatScore.Should().Be(minFormatScore);
|
||||||
|
result.First().CutoffFormatScore.Should().Be(cutoffFormatScore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Indexers.FileList;
|
||||||
using NzbDrone.Core.Indexers.Newznab;
|
using NzbDrone.Core.Indexers.Newznab;
|
||||||
using NzbDrone.Core.Indexers.Omgwtfnzbs;
|
|
||||||
using NzbDrone.Core.Lifecycle;
|
using NzbDrone.Core.Lifecycle;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Test.IndexerTests
|
|||||||
_indexers = new List<IIndexer>();
|
_indexers = new List<IIndexer>();
|
||||||
|
|
||||||
_indexers.Add(Mocker.Resolve<Newznab>());
|
_indexers.Add(Mocker.Resolve<Newznab>());
|
||||||
_indexers.Add(Mocker.Resolve<Omgwtfnzbs>());
|
_indexers.Add(Mocker.Resolve<FileList>());
|
||||||
|
|
||||||
Mocker.SetConstant<IEnumerable<IIndexer>>(_indexers);
|
Mocker.SetConstant<IEnumerable<IIndexer>>(_indexers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,13 +62,21 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
|||||||
releaseInfo.Size.Should().Be(1183105773);
|
releaseInfo.Size.Should().Be(1183105773);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
public void should_use_best_pagesize_reported_by_caps()
|
||||||
public void should_use_pagesize_reported_by_caps()
|
|
||||||
{
|
{
|
||||||
_caps.MaxPageSize = 30;
|
_caps.MaxPageSize = 30;
|
||||||
_caps.DefaultPageSize = 25;
|
_caps.DefaultPageSize = 25;
|
||||||
|
|
||||||
Subject.PageSize.Should().Be(25);
|
Subject.PageSize.Should().Be(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_use_pagesize_over_100_even_if_reported_in_caps()
|
||||||
|
{
|
||||||
|
_caps.MaxPageSize = 250;
|
||||||
|
_caps.DefaultPageSize = 25;
|
||||||
|
|
||||||
|
Subject.PageSize.Should().Be(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
using NzbDrone.Core.Indexers.Omgwtfnzbs;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.IndexerTests.OmgwtfnzbsTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class OmgwtfnzbsFixture : CoreTest<Omgwtfnzbs>
|
|
||||||
{
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
Subject.Definition = new IndexerDefinition()
|
|
||||||
{
|
|
||||||
Name = "Omgwtfnzbs",
|
|
||||||
Settings = new OmgwtfnzbsSettings()
|
|
||||||
{
|
|
||||||
ApiKey = "xxx",
|
|
||||||
Username = "me@my.domain"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_parse_recent_feed_from_omgwtfnzbs()
|
|
||||||
{
|
|
||||||
var recentFeed = ReadAllText(@"Files/Indexers/Omgwtfnzbs/Omgwtfnzbs.xml");
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get)))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(100);
|
|
||||||
|
|
||||||
var releaseInfo = releases.First();
|
|
||||||
|
|
||||||
releaseInfo.Title.Should().Be("Un.Petit.Boulot.2016.FRENCH.720p.BluRay.DTS.x264-LOST");
|
|
||||||
releaseInfo.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
|
|
||||||
releaseInfo.DownloadUrl.Should().Be("https://api.omgwtfnzbs.me/nzb/?id=8a2Bw&user=nzbdrone&api=nzbdrone");
|
|
||||||
releaseInfo.InfoUrl.Should().Be("https://omgwtfnzbs.me/details.php?id=8a2Bw");
|
|
||||||
releaseInfo.CommentUrl.Should().BeNullOrEmpty();
|
|
||||||
releaseInfo.Indexer.Should().Be(Subject.Definition.Name);
|
|
||||||
releaseInfo.PublishDate.Should().Be(DateTime.Parse("2017/01/09 00:16:54"));
|
|
||||||
releaseInfo.Size.Should().Be(5354909355);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
@@ -55,7 +56,7 @@ namespace NzbDrone.Core.Test.IndexerTests.PTPTests
|
|||||||
first.DownloadUrl.Should().Be("https://passthepopcorn.me/torrents.php?action=download&id=452135&authkey=00000000000000000000000000000000&torrent_pass=00000000000000000000000000000000");
|
first.DownloadUrl.Should().Be("https://passthepopcorn.me/torrents.php?action=download&id=452135&authkey=00000000000000000000000000000000&torrent_pass=00000000000000000000000000000000");
|
||||||
first.InfoUrl.Should().Be("https://passthepopcorn.me/torrents.php?id=148131&torrentid=452135");
|
first.InfoUrl.Should().Be("https://passthepopcorn.me/torrents.php?id=148131&torrentid=452135");
|
||||||
|
|
||||||
// first.PublishDate.Should().Be(DateTime.Parse("2017-04-17T12:13:42+0000").ToUniversalTime()); stupid timezones
|
first.PublishDate.Should().Be(DateTime.Parse("2016-10-18T23:40:59+0000").ToUniversalTime());
|
||||||
first.Size.Should().Be(2466170624L);
|
first.Size.Should().Be(2466170624L);
|
||||||
first.InfoHash.Should().BeNullOrEmpty();
|
first.InfoHash.Should().BeNullOrEmpty();
|
||||||
first.MagnetUrl.Should().BeNullOrEmpty();
|
first.MagnetUrl.Should().BeNullOrEmpty();
|
||||||
|
|||||||
@@ -135,12 +135,21 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_use_pagesize_reported_by_caps()
|
public void should_use_best_pagesize_reported_by_caps()
|
||||||
{
|
{
|
||||||
_caps.MaxPageSize = 30;
|
_caps.MaxPageSize = 30;
|
||||||
_caps.DefaultPageSize = 25;
|
_caps.DefaultPageSize = 25;
|
||||||
|
|
||||||
Subject.PageSize.Should().Be(25);
|
Subject.PageSize.Should().Be(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_use_pagesize_over_100_even_if_reported_in_caps()
|
||||||
|
{
|
||||||
|
_caps.MaxPageSize = 250;
|
||||||
|
_caps.DefaultPageSize = 25;
|
||||||
|
|
||||||
|
Subject.PageSize.Should().Be(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("http://localhost:9117/", "/api")]
|
[TestCase("http://localhost:9117/", "/api")]
|
||||||
|
|||||||
@@ -49,6 +49,14 @@ namespace NzbDrone.Core.Test.Languages
|
|||||||
new object[] { 34, Language.Bengali },
|
new object[] { 34, Language.Bengali },
|
||||||
new object[] { 35, Language.Slovak },
|
new object[] { 35, Language.Slovak },
|
||||||
new object[] { 36, Language.Latvian },
|
new object[] { 36, Language.Latvian },
|
||||||
|
new object[] { 37, Language.SpanishLatino },
|
||||||
|
new object[] { 38, Language.Catalan },
|
||||||
|
new object[] { 39, Language.Croatian },
|
||||||
|
new object[] { 40, Language.Serbian },
|
||||||
|
new object[] { 41, Language.Bosnian },
|
||||||
|
new object[] { 42, Language.Estonian },
|
||||||
|
new object[] { 43, Language.Tamil },
|
||||||
|
new object[] { 44, Language.Indonesian }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static object[] ToIntCases =
|
public static object[] ToIntCases =
|
||||||
@@ -92,6 +100,14 @@ namespace NzbDrone.Core.Test.Languages
|
|||||||
new object[] { Language.Bengali, 34 },
|
new object[] { Language.Bengali, 34 },
|
||||||
new object[] { Language.Slovak, 35 },
|
new object[] { Language.Slovak, 35 },
|
||||||
new object[] { Language.Latvian, 36 },
|
new object[] { Language.Latvian, 36 },
|
||||||
|
new object[] { Language.SpanishLatino, 37 },
|
||||||
|
new object[] { Language.Catalan, 38 },
|
||||||
|
new object[] { Language.Croatian, 39 },
|
||||||
|
new object[] { Language.Serbian, 40 },
|
||||||
|
new object[] { Language.Bosnian, 41 },
|
||||||
|
new object[] { Language.Estonian, 42 },
|
||||||
|
new object[] { Language.Tamil, 43 },
|
||||||
|
new object[] { Language.Indonesian, 44 }
|
||||||
};
|
};
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -445,6 +445,58 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
.Verify(v => v.DeleteFolder(It.IsAny<string>(), true), Times.Never());
|
.Verify(v => v.DeleteFolder(It.IsAny<string>(), true), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_rejection_if_nothing_imported_and_contains_rar_file()
|
||||||
|
{
|
||||||
|
GivenValidMovie();
|
||||||
|
|
||||||
|
var path = @"C:\media\ba09030e-1234-1234-1234-123456789abc\[HorribleSubs] American Psycho (2000) [720p]\[HorribleSubs] American Psycho (2000) [720p].mkv".AsOsAgnostic();
|
||||||
|
var imported = new List<ImportDecision>();
|
||||||
|
|
||||||
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
|
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true, true))
|
||||||
|
.Returns(imported);
|
||||||
|
|
||||||
|
Mocker.GetMock<IImportApprovedMovie>()
|
||||||
|
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto))
|
||||||
|
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(s => s.GetFiles(It.IsAny<string>(), SearchOption.AllDirectories))
|
||||||
|
.Returns(new[] { _videoFiles.First().Replace(".ext", ".rar") });
|
||||||
|
|
||||||
|
var result = Subject.ProcessPath(path);
|
||||||
|
|
||||||
|
result.Count.Should().Be(1);
|
||||||
|
result.First().Result.Should().Be(ImportResultType.Rejected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_rejection_if_nothing_imported_and_contains_executable_file()
|
||||||
|
{
|
||||||
|
GivenValidMovie();
|
||||||
|
|
||||||
|
var path = @"C:\media\ba09030e-1234-1234-1234-123456789abc\[HorribleSubs] American Psycho (2000) [720p]\[HorribleSubs] American Psycho (2000) [720p].mkv".AsOsAgnostic();
|
||||||
|
var imported = new List<ImportDecision>();
|
||||||
|
|
||||||
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
|
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true, true))
|
||||||
|
.Returns(imported);
|
||||||
|
|
||||||
|
Mocker.GetMock<IImportApprovedMovie>()
|
||||||
|
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto))
|
||||||
|
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(s => s.GetFiles(It.IsAny<string>(), SearchOption.AllDirectories))
|
||||||
|
.Returns(new[] { _videoFiles.First().Replace(".ext", ".exe") });
|
||||||
|
|
||||||
|
var result = Subject.ProcessPath(path);
|
||||||
|
|
||||||
|
result.Count.Should().Be(1);
|
||||||
|
result.First().Result.Should().Be(ImportResultType.Rejected);
|
||||||
|
}
|
||||||
|
|
||||||
private void VerifyNoImport()
|
private void VerifyNoImport()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IImportApprovedMovie>().Verify(c => c.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto),
|
Mocker.GetMock<IImportApprovedMovie>().Verify(c => c.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto),
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaFileDeletionService
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class DeleteMovieFileFixture : CoreTest<Core.MediaFiles.MediaFileDeletionService>
|
public class DeleteMovieFileFixture : CoreTest<Core.MediaFiles.MediaFileDeletionService>
|
||||||
{
|
{
|
||||||
private static readonly string RootFolder = @"C:\Test\Movies";
|
private const string RootFolder = @"C:\Test\Movies";
|
||||||
private Movie _movie;
|
private Movie _movie;
|
||||||
private MovieFile _movieFile;
|
private MovieFile _movieFile;
|
||||||
|
|
||||||
|
|||||||
+1
@@ -25,6 +25,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests
|
|||||||
[TestCase("msmpeg4, DIV3", "Movie the Title (1976) 360p MPEG Audio.avi", "DivX")]
|
[TestCase("msmpeg4, DIV3", "Movie the Title (1976) 360p MPEG Audio.avi", "DivX")]
|
||||||
[TestCase("msmpeg4v2, DIV3", "Movie the Title (1976) 360p MPEG Audio.avi", "DivX")]
|
[TestCase("msmpeg4v2, DIV3", "Movie the Title (1976) 360p MPEG Audio.avi", "DivX")]
|
||||||
[TestCase("msmpeg4v3, DIV3", "Movie the Title (1976) 360p MPEG Audio.avi", "DivX")]
|
[TestCase("msmpeg4v3, DIV3", "Movie the Title (1976) 360p MPEG Audio.avi", "DivX")]
|
||||||
|
[TestCase("vp6f, 4", "Movie the Title (1976) 360p MPEG Audio.flv", "VP6")]
|
||||||
[TestCase("vp6, 4", "Top Gear - S12E01 - Lorries - SD TV.flv", "VP6")]
|
[TestCase("vp6, 4", "Top Gear - S12E01 - Lorries - SD TV.flv", "VP6")]
|
||||||
[TestCase("vp7, VP70", "Movie the Title.avi", "VP7")]
|
[TestCase("vp7, VP70", "Movie the Title.avi", "VP7")]
|
||||||
[TestCase("vp8, V_VP8", "Movie the Title.mkv", "VP8")]
|
[TestCase("vp8, V_VP8", "Movie the Title.mkv", "VP8")]
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace NzbDrone.Core.Test.MovieTests.MovieRepositoryTests
|
|||||||
var profile = new Profile
|
var profile = new Profile
|
||||||
{
|
{
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
|
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
|
||||||
FormatItems = CustomFormatsFixture.GetDefaultFormatItems(),
|
FormatItems = CustomFormatsTestHelpers.GetDefaultFormatItems(),
|
||||||
MinFormatScore = 0,
|
MinFormatScore = 0,
|
||||||
Cutoff = Quality.Bluray1080p.Id,
|
Cutoff = Quality.Bluray1080p.Id,
|
||||||
Name = "TestProfile"
|
Name = "TestProfile"
|
||||||
|
|||||||
+2
-2
@@ -75,7 +75,7 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests
|
|||||||
[TestCase("radarr.video")]
|
[TestCase("radarr.video")]
|
||||||
public void should_not_be_valid_if_cc_is_invalid(string email)
|
public void should_not_be_valid_if_cc_is_invalid(string email)
|
||||||
{
|
{
|
||||||
_emailSettings.CC = new string[] { email };
|
_emailSettings.Cc = new string[] { email };
|
||||||
|
|
||||||
_validator.Validate(_emailSettings).IsValid.Should().BeFalse();
|
_validator.Validate(_emailSettings).IsValid.Should().BeFalse();
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests
|
|||||||
public void should_not_be_valid_if_to_bcc_cc_are_all_empty()
|
public void should_not_be_valid_if_to_bcc_cc_are_all_empty()
|
||||||
{
|
{
|
||||||
_emailSettings.To = Array.Empty<string>();
|
_emailSettings.To = Array.Empty<string>();
|
||||||
_emailSettings.CC = Array.Empty<string>();
|
_emailSettings.Cc = Array.Empty<string>();
|
||||||
_emailSettings.Bcc = Array.Empty<string>();
|
_emailSettings.Bcc = Array.Empty<string>();
|
||||||
|
|
||||||
_validator.Validate(_emailSettings).IsValid.Should().BeFalse();
|
_validator.Validate(_emailSettings).IsValid.Should().BeFalse();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@@ -13,10 +14,10 @@ using NzbDrone.Core.Test.Framework;
|
|||||||
namespace NzbDrone.Core.Test.NotificationTests
|
namespace NzbDrone.Core.Test.NotificationTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TraktServiceFixture : CoreTest<TraktService>
|
public class TraktServiceFixture : CoreTest<Trakt>
|
||||||
{
|
{
|
||||||
private DownloadMessage _downloadMessage;
|
private DownloadMessage _downloadMessage;
|
||||||
private TraktSettings _traktSettings;
|
private NotificationDefinition _traktDefinition;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
@@ -34,11 +35,17 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_traktSettings = new TraktSettings
|
_traktDefinition = new NotificationDefinition
|
||||||
{
|
{
|
||||||
AccessToken = "",
|
Settings = new TraktSettings
|
||||||
RefreshToken = ""
|
{
|
||||||
|
AccessToken = "",
|
||||||
|
RefreshToken = "",
|
||||||
|
Expires = DateTime.Now.AddDays(1)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Subject.Definition = _traktDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GiventValidMediaInfo(Quality quality, string audioChannels, string audioFormat, string scanType)
|
private void GiventValidMediaInfo(Quality quality, string audioChannels, string audioFormat, string scanType)
|
||||||
@@ -56,7 +63,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_add_collection_movie_if_null_mediainfo()
|
public void should_add_collection_movie_if_null_mediainfo()
|
||||||
{
|
{
|
||||||
Subject.AddMovieToCollection(_traktSettings, _downloadMessage.Movie, _downloadMessage.MovieFile);
|
Subject.OnDownload(_downloadMessage);
|
||||||
|
|
||||||
Mocker.GetMock<ITraktProxy>()
|
Mocker.GetMock<ITraktProxy>()
|
||||||
.Verify(v => v.AddToCollection(It.IsAny<TraktCollectMoviesResource>(), It.IsAny<string>()), Times.Once());
|
.Verify(v => v.AddToCollection(It.IsAny<TraktCollectMoviesResource>(), It.IsAny<string>()), Times.Once());
|
||||||
@@ -67,7 +74,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||||||
{
|
{
|
||||||
GiventValidMediaInfo(Quality.Bluray1080p, "5.1", "DTS", "Progressive");
|
GiventValidMediaInfo(Quality.Bluray1080p, "5.1", "DTS", "Progressive");
|
||||||
|
|
||||||
Subject.AddMovieToCollection(_traktSettings, _downloadMessage.Movie, _downloadMessage.MovieFile);
|
Subject.OnDownload(_downloadMessage);
|
||||||
|
|
||||||
Mocker.GetMock<ITraktProxy>()
|
Mocker.GetMock<ITraktProxy>()
|
||||||
.Verify(v => v.AddToCollection(It.Is<TraktCollectMoviesResource>(t =>
|
.Verify(v => v.AddToCollection(It.Is<TraktCollectMoviesResource>(t =>
|
||||||
@@ -83,7 +90,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||||||
{
|
{
|
||||||
GiventValidMediaInfo(Quality.Bluray1080p, "2.0", "DTS", "Progressive");
|
GiventValidMediaInfo(Quality.Bluray1080p, "2.0", "DTS", "Progressive");
|
||||||
|
|
||||||
Subject.AddMovieToCollection(_traktSettings, _downloadMessage.Movie, _downloadMessage.MovieFile);
|
Subject.OnDownload(_downloadMessage);
|
||||||
|
|
||||||
Mocker.GetMock<ITraktProxy>()
|
Mocker.GetMock<ITraktProxy>()
|
||||||
.Verify(v => v.AddToCollection(It.Is<TraktCollectMoviesResource>(t =>
|
.Verify(v => v.AddToCollection(It.Is<TraktCollectMoviesResource>(t =>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
|||||||
{
|
{
|
||||||
[TestCase("Mission: Impossible - no [HDTV-720p]",
|
[TestCase("Mission: Impossible - no [HDTV-720p]",
|
||||||
"Mission Impossible - no [HDTV-720p]")]
|
"Mission Impossible - no [HDTV-720p]")]
|
||||||
|
[TestCase(".45 (2006)", "45 (2006)")]
|
||||||
|
[TestCase(" The Movie Title ", "The Movie Title")]
|
||||||
public void CleanFileName(string name, string expectedName)
|
public void CleanFileName(string name, string expectedName)
|
||||||
{
|
{
|
||||||
FileNameBuilder.CleanFileName(name).Should().Be(expectedName);
|
FileNameBuilder.CleanFileName(name).Should().Be(expectedName);
|
||||||
|
|||||||
@@ -562,19 +562,6 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
|||||||
.Should().Be(string.Format("HDTV-720p{0}South{0}Park", separator));
|
.Should().Be(string.Format("HDTV-720p{0}South{0}Park", separator));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_able_to_use_original_filename()
|
|
||||||
{
|
|
||||||
_movie.Title = "30 Rock";
|
|
||||||
_namingConfig.StandardMovieFormat = "{Movie Title} - {Original Filename}";
|
|
||||||
|
|
||||||
_movieFile.SceneName = "30.Rock.S01E01.xvid-LOL";
|
|
||||||
_movieFile.RelativePath = "30 Rock - S01E01 - Test";
|
|
||||||
|
|
||||||
Subject.BuildFileName(_movie, _movieFile)
|
|
||||||
.Should().Be("30 Rock - 30 Rock - S01E01 - Test");
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("en-US")]
|
[TestCase("en-US")]
|
||||||
[TestCase("fr-FR")]
|
[TestCase("fr-FR")]
|
||||||
[TestCase("az")]
|
[TestCase("az")]
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user