1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-24 17:25:22 -04:00

Compare commits

..

1 Commits

Author SHA1 Message Date
PearsonFlyer
eb764832ed Fix notifiation in Ntfy on test from Radarr to Sonarr
(cherry picked from commit 1b599c7e765b10ce043cbf6b127143cc737b378a)
2023-01-20 00:24:26 +00:00
172 changed files with 2727 additions and 1861 deletions

23
.gitignore vendored
View File

@@ -166,8 +166,27 @@ packages.config.md5sum
# Common IntelliJ Platform excludes
# Ignore Rider projects completely for now
.idea/
# User specific
**/.idea/**/workspace.xml
**/.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
node_modules

View File

@@ -9,7 +9,7 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '4.4.2'
majorVersion: '4.4.0'
minorVersion: $[counter('minorVersion', 2000)]
radarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(radarrVersion)'

View File

@@ -56,7 +56,6 @@ class HistoryRow extends Component {
movie,
quality,
customFormats,
customFormatScore,
languages,
qualityCutoffNotMet,
eventType,
@@ -176,7 +175,7 @@ class HistoryRow extends Component {
key={name}
className={styles.customFormatScore}
>
{formatCustomFormatScore(customFormatScore)}
{formatCustomFormatScore(data.customFormatScore)}
</TableRowCell>
);
}
@@ -242,9 +241,8 @@ HistoryRow.propTypes = {
movie: PropTypes.object.isRequired,
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
quality: PropTypes.object.isRequired,
customFormats: PropTypes.arrayOf(PropTypes.object),
customFormatScore: PropTypes.number.isRequired,
qualityCutoffNotMet: PropTypes.bool.isRequired,
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
eventType: PropTypes.string.isRequired,
sourceTitle: PropTypes.string.isRequired,
date: PropTypes.string.isRequired,

View File

@@ -128,7 +128,6 @@ class QueueRow extends Component {
{
columns.map((column) => {
const {
name,
isVisible
@@ -235,16 +234,6 @@ class QueueRow extends Component {
);
}
if (name === 'year') {
return (
<TableRowCell key={name}>
{
movie ? movie.year : ''
}
</TableRowCell>
);
}
if (name === 'title') {
return (
<TableRowCell key={name}>
@@ -373,7 +362,6 @@ QueueRow.propTypes = {
estimatedCompletionTime: PropTypes.string,
timeleft: PropTypes.string,
size: PropTypes.number,
year: PropTypes.number,
sizeleft: PropTypes.number,
showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired,

View File

@@ -60,7 +60,7 @@ class FilterMenu extends Component {
iconName={icons.FILTER}
text={translate('Filter')}
isDisabled={isDisabled}
showIndicator={selectedFilterKey !== 'all'}
indicator={selectedFilterKey !== 'all'}
/>
<FilterMenuContent

View File

@@ -1,19 +1,11 @@
.menuButton {
composes: menuButton from '~./MenuButton.css';
position: relative;
&:hover {
color: #666;
}
}
.indicatorContainer {
position: absolute;
top: 10px;
left: 10px;
}
.label {
margin-left: 5px;
}

View File

@@ -1,15 +1,13 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import Icon from 'Components/Icon';
import MenuButton from 'Components/Menu/MenuButton';
import { icons } from 'Helpers/Props';
import styles from './PageMenuButton.css';
function PageMenuButton(props) {
const {
iconName,
showIndicator,
indicator,
text,
...otherProps
} = props;
@@ -24,22 +22,6 @@ function PageMenuButton(props) {
size={18}
/>
{
showIndicator ?
<span
className={classNames(
styles.indicatorContainer,
'fa-layers fa-fw'
)}
>
<Icon
name={icons.CIRCLE}
size={9}
/>
</span> :
null
}
<div className={styles.label}>
{text}
</div>
@@ -50,11 +32,11 @@ function PageMenuButton(props) {
PageMenuButton.propTypes = {
iconName: PropTypes.object.isRequired,
text: PropTypes.string,
showIndicator: PropTypes.bool.isRequired
indicator: PropTypes.bool.isRequired
};
PageMenuButton.defaultProps = {
showIndicator: false
indicator: false
};
export default PageMenuButton;

View File

@@ -9,7 +9,7 @@ import styles from './ToolbarMenuButton.css';
function ToolbarMenuButton(props) {
const {
iconName,
showIndicator,
indicator,
text,
...otherProps
} = props;
@@ -26,7 +26,7 @@ function ToolbarMenuButton(props) {
/>
{
showIndicator &&
indicator &&
<span
className={classNames(
styles.indicatorContainer,
@@ -53,11 +53,11 @@ function ToolbarMenuButton(props) {
ToolbarMenuButton.propTypes = {
iconName: PropTypes.object.isRequired,
text: PropTypes.string,
showIndicator: PropTypes.bool.isRequired
indicator: PropTypes.bool.isRequired
};
ToolbarMenuButton.defaultProps = {
showIndicator: false
indicator: false
};
export default ToolbarMenuButton;

View File

@@ -19,7 +19,7 @@
}
}
@media only screen and (max-width: $breakpointExtraLarge) {
@media only screen and (max-width: $breakpointLarge) {
.contentFooter {
flex-wrap: wrap;
}

View File

@@ -20,11 +20,7 @@
.frontTextContainer {
z-index: 1;
color: var(--progressBarFrontTextColor);
}
.backTextContainer {
color: var(--progressBarBackTextColor);
color: var(--white);
}
.backTextContainer,

View File

@@ -64,15 +64,6 @@ const columns = [
isSortable: true,
isVisible: true
},
{
name: 'customFormats',
label: React.createElement(Icon, {
name: icons.INTERACTIVE,
title: translate('CustomFormat')
}),
isSortable: true,
isVisible: true
},
{
name: 'rejections',
label: React.createElement(Icon, {

View File

@@ -5,10 +5,8 @@
}
.quality,
.languages {
.language {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
text-align: center;
}
.label {
@@ -23,7 +21,3 @@
margin-top: 0;
text-align: start;
}
.customFormatTooltip {
max-width: 250px;
}

View File

@@ -12,7 +12,6 @@ import SelectLanguageModal from 'InteractiveImport/Language/SelectLanguageModal'
import SelectMovieModal from 'InteractiveImport/Movie/SelectMovieModal';
import SelectQualityModal from 'InteractiveImport/Quality/SelectQualityModal';
import SelectReleaseGroupModal from 'InteractiveImport/ReleaseGroup/SelectReleaseGroupModal';
import MovieFormats from 'Movie/MovieFormats';
import MovieLanguage from 'Movie/MovieLanguage';
import MovieQuality from 'Movie/MovieQuality';
import formatBytes from 'Utilities/Number/formatBytes';
@@ -151,7 +150,6 @@ class InteractiveImportRow extends Component {
languages,
releaseGroup,
size,
customFormats,
rejections,
isReprocessing,
isSelected,
@@ -228,7 +226,7 @@ class InteractiveImportRow extends Component {
</TableRowCellButton>
<TableRowCellButton
className={styles.languages}
className={styles.language}
title={translate('ClickToChangeLanguage')}
onPress={this.onSelectLanguagePress}
>
@@ -261,26 +259,7 @@ class InteractiveImportRow extends Component {
<TableRowCell>
{
customFormats?.length ?
<Popover
anchor={
<Icon name={icons.INTERACTIVE} />
}
title="Formats"
body={
<div className={styles.customFormatTooltip}>
<MovieFormats formats={customFormats} />
</div>
}
position={tooltipPositions.LEFT}
/> :
null
}
</TableRowCell>
<TableRowCell>
{
rejections.length ?
!!rejections.length &&
<Popover
anchor={
<Icon
@@ -303,9 +282,7 @@ class InteractiveImportRow extends Component {
</ul>
}
position={tooltipPositions.LEFT}
canFlip={false}
/> :
null
/>
}
</TableRowCell>
@@ -353,7 +330,6 @@ InteractiveImportRow.propTypes = {
languages: PropTypes.arrayOf(PropTypes.object),
releaseGroup: PropTypes.string,
size: PropTypes.number.isRequired,
customFormats: PropTypes.arrayOf(PropTypes.object),
rejections: PropTypes.arrayOf(PropTypes.object).isRequired,
isReprocessing: PropTypes.bool,
isSelected: PropTypes.bool,

View File

@@ -62,7 +62,6 @@ class MovieHistoryRow extends Component {
sourceTitle,
quality,
customFormats,
customFormatScore,
languages,
qualityCutoffNotMet,
date,
@@ -107,7 +106,7 @@ class MovieHistoryRow extends Component {
</TableRowCell>
<TableRowCell key={name}>
{formatCustomFormatScore(customFormatScore)}
{formatCustomFormatScore(data.customFormatScore)}
</TableRowCell>
<RelativeDateCellConnector
@@ -162,8 +161,7 @@ MovieHistoryRow.propTypes = {
sourceTitle: PropTypes.string.isRequired,
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
quality: PropTypes.object.isRequired,
customFormats: PropTypes.arrayOf(PropTypes.object),
customFormatScore: PropTypes.number.isRequired,
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
qualityCutoffNotMet: PropTypes.bool.isRequired,
date: PropTypes.string.isRequired,
data: PropTypes.object.isRequired,

View File

@@ -30,7 +30,6 @@
code {
padding: 0 1px;
border: 1px solid var(--borderColor);
background-color: var(--modalCloseButtonHoverColor);
color: var(--movieBackgroundColor);
background-color: #f7f7f7;
}
}

View File

@@ -7,11 +7,11 @@
&:hover {
.token {
background-color: var(--popoverTitleBackgroundInverseColor);
background-color: #ddd;
}
.example {
background-color: var(--popoverTitleBorderInverseColor);
background-color: #ccc;
}
}
}
@@ -27,7 +27,7 @@
.token {
flex: 0 0 50%;
padding: 6px 16px;
background-color: var(--popoverTitleBorderColor);
background-color: #eee;
font-family: $monoSpaceFontFamily;
}
@@ -38,7 +38,7 @@
justify-content: space-between;
flex: 0 0 50%;
padding: 6px 16px;
background-color: var(--popoverTitleBackgroundColor);
background-color: #ddd;
.footNote {
padding: 2px;

View File

@@ -118,12 +118,6 @@ export const defaultState = {
isSortable: true,
isVisible: false
},
{
name: 'year',
label: translate('Year'),
isSortable: true,
isVisible: true
},
{
name: 'outputPath',
label: translate('OutputPath'),

View File

@@ -201,11 +201,6 @@ export const defaultState = {
return genreList.sort(sortByName);
}
},
{
name: 'customFormatScore',
label: translate('CustomFormatScore'),
type: filterBuilderTypes.NUMBER
},
{
name: 'rejectionCount',
label: translate('RejectionCount'),

View File

@@ -226,8 +226,6 @@ module.exports = {
//
// Misc
progressBarFrontTextColor: white,
progressBarBackTextColor: white,
progressBarBackgroundColor: '#727070',
logEventsBackgroundColor: '#2a2a2a'
};

View File

@@ -198,8 +198,8 @@ module.exports = {
popoverShadowColor: 'rgba(0, 0, 0, 0.2)',
popoverArrowBorderColor: '#fff',
popoverTitleBackgroundInverseColor: '#9b9b9b',
popoverTitleBorderInverseColor: '#bfbfbf',
popoverTitleBackgroundInverseColor: '#595959',
popoverTitleBorderInverseColor: '#707070',
popoverShadowInverseColor: 'rgba(0, 0, 0, 0.2)',
popoverArrowBorderInverseColor: 'rgba(58, 63, 81, 0.75)',
@@ -227,8 +227,6 @@ module.exports = {
//
// Misc
progressBarFrontTextColor: white,
progressBarBackTextColor: darkGray,
progressBarBackgroundColor: white,
logEventsBackgroundColor: white
progressBarBackgroundColor: '#fff',
logEventsBackgroundColor: '#fff'
};

View File

@@ -1,4 +1,5 @@
function formatCustomFormatScore(input, customFormatsLength = 0) {
function formatCustomFormatScore(input) {
const score = Number(input);
if (score > 0) {
@@ -9,7 +10,7 @@ function formatCustomFormatScore(input, customFormatsLength = 0) {
return score;
}
return customFormatsLength > 0 ? '+0' : '';
return '';
}
export default formatCustomFormatScore;

View File

@@ -113,7 +113,7 @@
"file-loader": "6.2.0",
"filemanager-webpack-plugin": "5.0.0",
"html-webpack-plugin": "5.3.1",
"loader-utils": "^3.2.1",
"loader-utils": "^2.0.0",
"mini-css-extract-plugin": "1.5.0",
"postcss": "8.2.12",
"postcss-color-function": "4.1.0",

View File

@@ -9,7 +9,6 @@ namespace NzbDrone.Common.EnvironmentInfo
bool IsAdmin { get; }
bool IsWindowsService { get; }
bool IsWindowsTray { get; }
bool IsStarting { get; set; }
bool IsExiting { get; set; }
bool IsTray { get; }
RuntimeMode Mode { get; }

View File

@@ -19,7 +19,6 @@ namespace NzbDrone.Common.EnvironmentInfo
_logger = logger;
IsWindowsService = hostLifetime is WindowsServiceLifetime;
IsStarting = true;
// 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
@@ -83,7 +82,6 @@ namespace NzbDrone.Common.EnvironmentInfo
public bool IsWindowsService { get; private set; }
public bool IsStarting { get; set; }
public bool IsExiting { get; set; }
public bool IsTray
{

View File

@@ -8,7 +8,6 @@ using System.Threading;
using NLog;
using NLog.Common;
using NLog.Targets;
using Npgsql;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using Sentry;
@@ -35,14 +34,6 @@ namespace NzbDrone.Common.Instrumentation.Sentry
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
// where these are defined
private static readonly HashSet<string> FilteredExceptionTypeNames = new HashSet<string>
@@ -259,19 +250,6 @@ namespace NzbDrone.Common.Instrumentation.Sentry
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))
{
isSentry = false;

View File

@@ -10,7 +10,6 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="NLog" Version="5.0.1" />
<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="NLog.Targets.Syslog" Version="7.0.0" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -9,7 +9,7 @@ using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.CustomFormats
{
[TestFixture]
public class CustomFormatsTestHelpers : CoreTest
public class CustomFormatsFixture : CoreTest
{
private static List<CustomFormat> _customFormats { get; set; }

View File

@@ -46,14 +46,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
ParsedMovieInfo = new ParsedMovieInfo { Quality = new QualityModel(Quality.DVD, new Revision(version: 2)) },
};
CustomFormatsTestHelpers.GivenCustomFormats(_format1, _format2);
CustomFormatsFixture.GivenCustomFormats(_format1, _format2);
}
[Test]
public void should_allow_if_format_score_greater_than_min()
{
_remoteMovie.CustomFormats = new List<CustomFormat> { _format1 };
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
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()
{
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2 };
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
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()
{
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2, _format1 };
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
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()
{
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2, _format1 };
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
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()
{
_remoteMovie.CustomFormats = new List<CustomFormat> { };
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
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()
{
_remoteMovie.CustomFormats = new List<CustomFormat> { };
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
_remoteMovie.Movie.Profile.MinFormatScore = 0;
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);

View File

@@ -40,8 +40,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
private void GivenProfile(Profile profile)
{
CustomFormatsTestHelpers.GivenCustomFormats();
profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems();
CustomFormatsFixture.GivenCustomFormats();
profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems();
profile.MinFormatScore = 0;
_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 };
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat);
CustomFormatsFixture.GivenCustomFormats(_customFormat);
}
[Test]
@@ -157,7 +157,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities(),
MinFormatScore = 0,
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems("My Format"),
FormatItems = CustomFormatsFixture.GetSampleFormatItems("My Format"),
UpgradeAllowed = true
});

View File

@@ -38,14 +38,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Mocker.Resolve<UpgradableSpecification>();
_upgradeHistory = Mocker.Resolve<HistorySpecification>();
CustomFormatsTestHelpers.GivenCustomFormats();
CustomFormatsFixture.GivenCustomFormats();
_fakeMovie = Builder<Movie>.CreateNew()
.With(c => c.Profile = new Profile
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
Cutoff = Quality.Bluray1080p.Id,
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems("None"),
FormatItems = CustomFormatsFixture.GetSampleFormatItems("None"),
MinFormatScore = 0,
UpgradeAllowed = true
})
@@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
.Returns(true);
Mocker.GetMock<ICustomFormatCalculationService>()
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>(), It.IsAny<Movie>()))
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>()))
.Returns(new List<CustomFormat>());
}
@@ -163,7 +163,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
Cutoff = Quality.Bluray1080p.Id,
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
MinFormatScore = 0
};
@@ -171,7 +171,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_upgradableQuality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1));
Mocker.GetMock<ICustomFormatCalculationService>()
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>(), It.IsAny<Movie>()))
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>()))
.Returns(new List<CustomFormat>());
GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, MovieHistoryEventType.Grabbed);
@@ -186,7 +186,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
Cutoff = Quality.WEBDL1080p.Id,
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
MinFormatScore = 0
};
@@ -221,7 +221,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
Cutoff = Quality.WEBDL1080p.Id,
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
MinFormatScore = 0
};

View File

@@ -41,17 +41,17 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
private void WithEnglishRelease()
{
_remoteMovie.Languages = new List<Language> { Language.English };
_remoteMovie.ParsedMovieInfo.Languages = new List<Language> { Language.English };
}
private void WithGermanRelease()
{
_remoteMovie.Languages = new List<Language> { Language.German };
_remoteMovie.ParsedMovieInfo.Languages = new List<Language> { Language.German };
}
private void WithFrenchRelease()
{
_remoteMovie.Languages = new List<Language> { Language.French };
_remoteMovie.ParsedMovieInfo.Languages = new List<Language> { Language.French };
}
[Test]

View File

@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_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 };
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat1, _customFormat2);
CustomFormatsFixture.GivenCustomFormats(_customFormat1, _customFormat2);
Mocker.GetMock<IQualityDefinitionService>()
.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
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
FormatItems = CustomFormatsFixture.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
MinFormatScore = 0
})
.With(m => m.Title = "A Movie")

View File

@@ -48,7 +48,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[SetUp]
public void Setup()
{
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat1, _customFormat2);
CustomFormatsFixture.GivenCustomFormats(_customFormat1, _customFormat2);
}
private void GivenAutoDownloadPropers(ProperDownloadTypes type)
@@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
var profile = new Profile
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
FormatItems = CustomFormatsFixture.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
MinFormatScore = 0
};

View File

@@ -32,13 +32,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
Mocker.Resolve<UpgradableSpecification>();
CustomFormatsTestHelpers.GivenCustomFormats();
CustomFormatsFixture.GivenCustomFormats();
_movie = Builder<Movie>.CreateNew()
.With(e => e.Profile = new Profile
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
MinFormatScore = 0,
UpgradeAllowed = true
})
@@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
.Build();
Mocker.GetMock<ICustomFormatCalculationService>()
.Setup(x => x.ParseCustomFormat(It.IsAny<RemoteMovie>(), It.IsAny<long>()))
.Setup(x => x.ParseCustomFormat(It.IsAny<ParsedMovieInfo>(), _movie))
.Returns(new List<CustomFormat>());
}

View File

@@ -40,11 +40,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
new ProfileFormatItem
{
Id = 1,
Format = _customFormatOne,
Score = 50
},
new ProfileFormatItem
{
Id = 1,
Format = _customFormatTwo,
Score = 100
}

View File

@@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Mocker.Resolve<UpgradableSpecification>();
_upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>();
CustomFormatsTestHelpers.GivenCustomFormats();
CustomFormatsFixture.GivenCustomFormats();
_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
{
Cutoff = Quality.Bluray1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(),
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
MinFormatScore = 0
})
.With(e => e.MovieFile = _firstFile)

View File

@@ -1,112 +0,0 @@
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);
}
}
}

View File

@@ -54,7 +54,6 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
Id = id,
Title = "Movie.Title.2020.720p-Radarr",
ParsedMovieInfo = new ParsedMovieInfo { MovieTitles = new List<string> { title }, Year = year },
Release = Builder<ReleaseInfo>.CreateNew().Build(),
MovieId = _movie.Id
});
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,133 +0,0 @@
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);
}
}
}

View File

@@ -1,10 +1,10 @@
using System.Collections.Generic;
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Indexers.FileList;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Indexers.Omgwtfnzbs;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Test.Framework;
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Test.IndexerTests
_indexers = new List<IIndexer>();
_indexers.Add(Mocker.Resolve<Newznab>());
_indexers.Add(Mocker.Resolve<FileList>());
_indexers.Add(Mocker.Resolve<Omgwtfnzbs>());
Mocker.SetConstant<IEnumerable<IIndexer>>(_indexers);
}

View File

@@ -0,0 +1,56 @@
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);
}
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Linq;
using System.Net.Http;
using FluentAssertions;
@@ -56,7 +55,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.InfoUrl.Should().Be("https://passthepopcorn.me/torrents.php?id=148131&torrentid=452135");
first.PublishDate.Should().Be(DateTime.Parse("2016-10-18T23:40:59+0000").ToUniversalTime());
// first.PublishDate.Should().Be(DateTime.Parse("2017-04-17T12:13:42+0000").ToUniversalTime()); stupid timezones
first.Size.Should().Be(2466170624L);
first.InfoHash.Should().BeNullOrEmpty();
first.MagnetUrl.Should().BeNullOrEmpty();

View File

@@ -49,7 +49,6 @@ namespace NzbDrone.Core.Test.Languages
new object[] { 34, Language.Bengali },
new object[] { 35, Language.Slovak },
new object[] { 36, Language.Latvian },
new object[] { 37, Language.SpanishLatino }
};
public static object[] ToIntCases =
@@ -93,7 +92,6 @@ namespace NzbDrone.Core.Test.Languages
new object[] { Language.Bengali, 34 },
new object[] { Language.Slovak, 35 },
new object[] { Language.Latvian, 36 },
new object[] { Language.SpanishLatino, 37 }
};
[Test]

View File

@@ -445,58 +445,6 @@ namespace NzbDrone.Core.Test.MediaFiles
.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()
{
Mocker.GetMock<IImportApprovedMovie>().Verify(c => c.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto),

View File

@@ -35,7 +35,7 @@ namespace NzbDrone.Core.Test.MovieTests.MovieRepositoryTests
var profile = new Profile
{
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
FormatItems = CustomFormatsTestHelpers.GetDefaultFormatItems(),
FormatItems = CustomFormatsFixture.GetDefaultFormatItems(),
MinFormatScore = 0,
Cutoff = Quality.Bluray1080p.Id,
Name = "TestProfile"

View File

@@ -10,8 +10,6 @@ namespace NzbDrone.Core.Test.OrganizerTests
{
[TestCase("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)
{
FileNameBuilder.CleanFileName(name).Should().Be(expectedName);

View File

@@ -562,6 +562,19 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
.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("fr-FR")]
[TestCase("az")]

View File

@@ -1,88 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
{
[TestFixture]
public class OriginalTitleFixture : CoreTest<FileNameBuilder>
{
private Movie _movie;
private MovieFile _movieFile;
private NamingConfig _namingConfig;
[SetUp]
public void Setup()
{
_movie = Builder<Movie>
.CreateNew()
.With(s => s.Title = "My Movie")
.Build();
_movieFile = new MovieFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "RadarrTest" };
_namingConfig = NamingConfig.Default;
_namingConfig.RenameMovies = true;
Mocker.GetMock<INamingConfigService>()
.Setup(c => c.GetConfig()).Returns(_namingConfig);
Mocker.GetMock<IQualityDefinitionService>()
.Setup(v => v.Get(Moq.It.IsAny<Quality>()))
.Returns<Quality>(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v));
Mocker.GetMock<ICustomFormatService>()
.Setup(v => v.All())
.Returns(new List<CustomFormat>());
}
[Test]
public void should_not_recursively_include_current_filename()
{
_movieFile.RelativePath = "My Movie";
_namingConfig.StandardMovieFormat = "{Movie Title} {[Original Title]}";
Subject.BuildFileName(_movie, _movieFile)
.Should().Be("My Movie");
}
[Test]
public void should_include_original_title_if_not_current_file_name()
{
_movieFile.SceneName = "my.movie.2008";
_movieFile.RelativePath = "My Movie";
_namingConfig.StandardMovieFormat = "{Movie Title} {[Original Title]}";
Subject.BuildFileName(_movie, _movieFile)
.Should().Be("My Movie [my.movie.2008]");
}
[Test]
public void should_include_current_filename_if_not_renaming_files()
{
_movieFile.SceneName = "my.movie.2008";
_namingConfig.RenameMovies = false;
Subject.BuildFileName(_movie, _movieFile)
.Should().Be("my.movie.2008");
}
[Test]
public void should_include_current_filename_if_not_including_multiple_naming_tokens()
{
_movieFile.RelativePath = "My Movie";
_namingConfig.StandardMovieFormat = "{Original Title}";
Subject.BuildFileName(_movie, _movieFile)
.Should().Be("My Movie");
}
}
}

View File

@@ -1,4 +1,3 @@
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Languages;
@@ -381,18 +380,6 @@ namespace NzbDrone.Core.Test.ParserTests
result.Languages.Should().BeEquivalentTo(Language.Latvian);
}
[TestCase("Movie.Title.2019.720p_Eng-Spa(Latino)_MovieClubMx")]
[TestCase("Movie.Title.1.WEB-DL.720p.Complete.Latino.YG")]
[TestCase("Movie.Title.1080p.WEB.H264.Latino.YG")]
[TestCase("Movie Title latino")]
[TestCase("Movie Title (Temporada 11 Completa) Audio Dual Ingles/Latino 1920x1080")]
[TestCase("Movie title 7x4 audio latino")]
public void should_parse_language_spanish_latino(string postTitle)
{
var result = LanguageParser.ParseLanguages(postTitle);
result.First().Id.Should().Be(Language.SpanishLatino.Id);
}
[TestCase("Movie.Title.en.sub")]
[TestCase("Movie Title.eng.sub")]
[TestCase("Movie.Title.eng.forced.sub")]

View File

@@ -215,7 +215,6 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Movie Name FRENCH BluRay 720p 2016 kjhlj", 2016)]
[TestCase("Der.Movie.German.Bluray.FuckYou.Pso.Why.cant.you.follow.scene.rules.1998", 1998)]
[TestCase("Movie Name (1897) [DVD].mp4", 1897)]
[TestCase("World Movie Z Movie [2023]", 2023)]
public void should_parse_movie_year(string postTitle, int year)
{
Parser.Parser.ParseMovieTitle(postTitle).Year.Should().Be(year);
@@ -255,18 +254,6 @@ namespace NzbDrone.Core.Test.ParserTests
parsed.Languages.Should().Contain(Language.German);
}
[TestCase("Movie.Title.2016.1080p.KORSUB.WEBRip.x264.AAC2.0-RADARR", "KORSUB")]
[TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "KORSUBS")]
[TestCase("Movie Title 2017 HC 720p HDRiP DD5 1 x264-LEGi0N", "Generic Hardcoded Subs")]
[TestCase("Movie.Title.2017.720p.SUBBED.HDRip.V2.XViD-26k.avi", "Generic Hardcoded Subs")]
[TestCase("Movie.Title.2000.1080p.BlueRay.x264.DTS.RoSubbed-playHD", null)]
[TestCase("Movie Title! 2018 [Web][MKV][h264][480p][AAC 2.0][Softsubs]", null)]
[TestCase("Movie Title! 2019 [HorribleSubs][Web][MKV][h264][848x480][AAC 2.0][Softsubs(HorribleSubs)]", null)]
public void should_parse_hardcoded_subs(string postTitle, string sub)
{
Parser.Parser.ParseMovieTitle(postTitle).HardcodedSubs.Should().Be(sub);
}
[TestCase("That Italian Movie 2008 [tt1234567] 720p BluRay X264", "tt1234567")]
[TestCase("That Italian Movie 2008 [tt12345678] 720p BluRay X264", "tt12345678")]
public void should_parse_imdb_in_title(string postTitle, string imdb)

View File

@@ -0,0 +1,28 @@
using System.Collections.Generic;
using NUnit.Framework;
using NzbDrone.Core.Parser.Augmenters;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
{
[TestFixture]
public abstract class AugmentMovieInfoFixture<TAugmenter> : CoreTest<TAugmenter>
where TAugmenter : class, IAugmentParsedMovieInfo
{
protected ParsedMovieInfo MovieInfo;
[SetUp]
public virtual void Setup()
{
MovieInfo = new ParsedMovieInfo
{
MovieTitles = new List<string> { "A Movie" },
Year = 1998,
SimpleReleaseTitle = "A Movie Title 1998 Bluray 1080p",
Quality = new QualityModel(Quality.Bluray1080p)
};
}
}
}

View File

@@ -0,0 +1,23 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Parser.Augmenters;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
{
[TestFixture]
public class AugmentWithFileSizeFixture : AugmentMovieInfoFixture<AugmentWithFileSize>
{
[Test]
public void should_add_file_size()
{
var localMovie = new LocalMovie
{
Size = 1500
};
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, localMovie);
movieInfo.ExtraInfo["Size"].Should().BeEquivalentTo(1500);
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.History;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Indexers.Rarbg;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Parser.Augmenters;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
{
[TestFixture]
public class AugmentWithHistoryFixture : AugmentMovieInfoFixture<AugmentWithHistory>
{
private AugmentWithHistory _customSubject { get; set; }
[SetUp]
public override void Setup()
{
base.Setup();
// Add multi indexer
GivenIndexerSettings(new RarbgSettings
{
MultiLanguages = new List<int>
{
(int)Language.English,
(int)Language.French,
}
});
}
protected new AugmentWithHistory Subject
{
get
{
if (_customSubject == null)
{
_customSubject = new AugmentWithHistory(new List<Lazy<IAugmentParsedMovieInfo>> { new (Mocker.Resolve<AugmentWithReleaseInfo>()) });
}
return _customSubject;
}
}
private void GivenIndexerSettings(IIndexerSettings indexerSettings)
{
Mocker.GetMock<IIndexerFactory>().Setup(f => f.Get(It.IsAny<int>())).Returns(new IndexerDefinition
{
Settings = indexerSettings
});
}
private MovieHistory HistoryWithData(params string[] data)
{
var dict = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
for (var i = 0; i < data.Length; i += 2)
{
dict.Add(data[i], data[i + 1]);
}
return new MovieHistory
{
Data = dict,
EventType = MovieHistoryEventType.Grabbed
};
}
[Test]
public void should_add_indexer_flags()
{
var history = HistoryWithData("IndexerFlags", (IndexerFlags.PTP_Approved | IndexerFlags.PTP_Golden).ToString());
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, history);
movieInfo.ExtraInfo["IndexerFlags"].Should().BeEquivalentTo(IndexerFlags.PTP_Golden | IndexerFlags.PTP_Approved);
}
[Test]
public void should_add_size()
{
var history = HistoryWithData("Size", 9663676416.ToString());
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, history);
movieInfo.ExtraInfo["Size"].Should().BeEquivalentTo(9663676416);
}
[Test]
public void should_use_settings_languages_when_necessary()
{
var history = HistoryWithData("IndexerId", 1.ToString());
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, history);
movieInfo.Languages.Should().BeEquivalentTo();
MovieInfo.SimpleReleaseTitle = "A Movie 1998 Bluray 1080p MULTI";
var multiInfo = Subject.AugmentMovieInfo(MovieInfo, history);
multiInfo.Languages.Should().BeEquivalentTo(Language.English, Language.French);
}
[Test]
public void should_not_use_settings_languages()
{
var unknownIndexer = HistoryWithData();
var unknownIndexerInfo = Subject.AugmentMovieInfo(MovieInfo, unknownIndexer);
unknownIndexerInfo.Languages.Should().BeEquivalentTo();
}
}
}

View File

@@ -0,0 +1,90 @@
// using FluentAssertions;
// using NUnit.Framework;
// using NzbDrone.Core.CustomFormats;
// using NzbDrone.Core.MediaFiles.MediaInfo;
// using NzbDrone.Core.Parser;
// using NzbDrone.Core.Parser.Augmenters;
// using NzbDrone.Core.Qualities;
// namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
// {
// [TestFixture]
// public class AugmentWithMediaInfoFixture : AugmentMovieInfoFixture<AugmentWithMediaInfo>
// {
// [TestCase(Resolution.R720p, Source.BLURAY, Resolution.R1080p)]
// [TestCase(Resolution.R1080p, Source.TV, Resolution.R720p)]
// public void should_correct_resolution(Resolution resolution, Source source, Resolution realResolution)
// {
// var quality = new QualityModel
// {
// Source = source,
// Resolution = resolution,
// };
// MovieInfo.Quality = quality;
// var realWidth = 480;
// switch (realResolution)
// {
// case Resolution.R720p:
// realWidth = 1280;
// break;
// case Resolution.R1080p:
// realWidth = 1920;
// break;
// case Resolution.R2160p:
// realWidth = 2160;
// break;
// }
// var mediaInfo = new MediaInfoModel
// {
// Width = realWidth
// };
// var movieInfo = Subject.AugmentMovieInfo(MovieInfo, mediaInfo);
// movieInfo.Quality.Resolution.Should().BeEquivalentTo(realResolution);
// movieInfo.Quality.QualityDetectionSource.Should().BeEquivalentTo(QualityDetectionSource.MediaInfo);
// }
// [TestCase(Resolution.R720P, Source.BLURAY, Resolution.R1080P, Modifier.BRDISK)]
// [TestCase(Resolution.R1080P, Source.BLURAY, Resolution.R720P, Modifier.REMUX)]
// [TestCase(Resolution.R480P, Source.BLURAY, Resolution.R720P)]
// [TestCase(Resolution.R720P, Source.DVD, Resolution.R480P)]
// public void should_not_correct_resolution(Resolution resolution, Source source, Resolution realResolution, Modifier modifier = Modifier.NONE)
// {
// var quality = new QualityModel
// {
// Source = source,
// Resolution = resolution,
// Modifier = modifier,
// };
// MovieInfo.Quality = quality;
// var realWidth = 480;
// switch (realResolution)
// {
// case Resolution.R720P:
// realWidth = 1280;
// break;
// case Resolution.R1080P:
// realWidth = 1920;
// break;
// case Resolution.R2160P:
// realWidth = 2160;
// break;
// }
// var mediaInfo = new MediaInfoModel
// {
// Width = realWidth
// };
// var movieInfo = Subject.AugmentMovieInfo(MovieInfo, mediaInfo);
// movieInfo.Quality.Resolution.Should().BeEquivalentTo(resolution);
// movieInfo.Quality.QualityDetectionSource.Should().BeEquivalentTo(QualityDetectionSource.Name);
// }
// }
// }

View File

@@ -0,0 +1,29 @@
using System;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Parser.Augmenters;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
{
[TestFixture]
public class AugmentWithOriginalLanguageFixture : AugmentMovieInfoFixture<AugmentWithOriginalLanguage>
{
[Test]
public void should_add_movie_original_language()
{
var releaseInfo = new ParsedMovieInfo();
var movie = new Movies.Movie
{
MovieMetadata = new Movies.MovieMetadata
{
OriginalLanguage = Language.English
}
};
var result = Subject.AugmentMovieInfo(releaseInfo, movie);
result.ExtraInfo.Should().ContainKey("OriginalLanguage");
result.ExtraInfo["OriginalLanguage"].Should().Be(Language.English);
}
}
}

View File

@@ -0,0 +1,77 @@
using System.Collections.Generic;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Parser.Augmenters;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
{
[TestFixture]
public class AugmentWithParsedMovieInfoFixture : AugmentMovieInfoFixture<AugmentWithParsedMovieInfo>
{
[Test]
public void should_add_edition_if_null()
{
var folderInfo = new ParsedMovieInfo
{
Edition = "Directors Cut"
};
var result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
result.Edition.Should().Be(folderInfo.Edition);
}
[Test]
public void should_preferr_longer_edition()
{
var folderInfo = new ParsedMovieInfo
{
Edition = "Super duper cut"
};
MovieInfo.Edition = "Rogue";
var result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
result.Edition.Should().Be(folderInfo.Edition);
MovieInfo.Edition = "Super duper awesome cut";
result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
result.Edition.Should().Be(MovieInfo.Edition);
}
[Test]
public void should_combine_languages()
{
var folderInfo = new ParsedMovieInfo
{
Languages = new List<Language> { Language.French }
};
MovieInfo.Languages = new List<Language> { Language.English };
var result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
result.Languages.Should().BeEquivalentTo(Language.English, Language.French);
}
[Test]
public void should_use_folder_release_group()
{
var folderInfo = new ParsedMovieInfo
{
ReleaseGroup = "AwesomeGroup"
};
MovieInfo.ReleaseGroup = "";
var result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
result.ReleaseGroup.Should().BeEquivalentTo(folderInfo.ReleaseGroup);
}
}
}

View File

@@ -0,0 +1,82 @@
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Indexers.Rarbg;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Parser.Augmenters;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
{
[TestFixture]
public class AugmentWithReleaseInfoFixture : AugmentMovieInfoFixture<AugmentWithReleaseInfo>
{
private IndexerDefinition _indexerDefinition;
private ReleaseInfo ReleaseInfoWithLanguages(params Language[] languages)
{
_indexerDefinition = new IndexerDefinition
{
Settings = new RarbgSettings { MultiLanguages = languages.ToList().Select(l => (int)l) }
};
Mocker.GetMock<IIndexerFactory>()
.Setup(v => v.Get(1))
.Returns(_indexerDefinition);
return new ReleaseInfo
{
IndexerId = 1
};
}
[Test]
public void should_add_language_from_indexer()
{
var releaseInfo = ReleaseInfoWithLanguages(Language.English, Language.French);
MovieInfo.SimpleReleaseTitle = "A Movie Title 1998 Bluray 1080p MULTI";
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, releaseInfo);
movieInfo.Languages.Count.Should().Be(2);
movieInfo.Languages.Should().BeEquivalentTo(Language.English, Language.French);
}
[Test]
public void should_add_size_info()
{
var releaseInfo = new ReleaseInfo
{
Size = 1500
};
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, releaseInfo);
movieInfo.ExtraInfo["Size"].Should().BeEquivalentTo(1500);
}
[Test]
public void should_not_add_size_when_already_present()
{
var releaseInfo = new ReleaseInfo
{
Size = 1500
};
MovieInfo.ExtraInfo["Size"] = 1600;
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, releaseInfo);
movieInfo.ExtraInfo["Size"].Should().BeEquivalentTo(1600);
}
[Test]
public void should_add_indexer_flags()
{
var releaseInfo = new ReleaseInfo
{
IndexerFlags = IndexerFlags.PTP_Approved | IndexerFlags.PTP_Golden
};
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, releaseInfo);
movieInfo.ExtraInfo["IndexerFlags"].Should().BeEquivalentTo(IndexerFlags.PTP_Approved | IndexerFlags.PTP_Golden);
}
}
}

View File

@@ -194,5 +194,20 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
Subject.Map(_umlautInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
Subject.Map(_umlautAltInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
}
[Test]
public void should_convert_original()
{
Subject.Map(_multiLanguageInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().Contain(Language.English);
Subject.Map(_multiLanguageInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().Contain(Language.French);
}
[Test]
public void should_remove_original_as_already_exists()
{
Subject.Map(_multiLanguageWithOriginalInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().Contain(Language.English);
Subject.Map(_multiLanguageWithOriginalInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().Contain(Language.French);
Subject.Map(_multiLanguageWithOriginalInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().NotContain(Language.Original);
}
}
}

View File

@@ -44,7 +44,6 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Movie Name 2018 NEW PROPER 720p HD-CAM X264 HQ-CPG", true)]
[TestCase("Movie Name (2022) 1080p HQCAM ENG x264 AAC - QRips", false)]
[TestCase("Movie Name (2018) 720p Hindi HQ CAMrip x264 AAC 1.4GB", false)]
[TestCase("Movie Name (2022) New HDCAMRip 1080p [Love Rulz]", false)]
public void should_parse_cam(string title, bool proper)
{
ParseAndVerifyQuality(title, Source.CAM, proper, Resolution.Unknown);
@@ -452,6 +451,18 @@ namespace NzbDrone.Core.Test.ParserTests
result.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Name);
}
[TestCase("Movie.Title.2016.1080p.KORSUB.WEBRip.x264.AAC2.0-RADARR", "KORSUB")]
[TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "KORSUBS")]
[TestCase("Movie Title 2017 HC 720p HDRiP DD5 1 x264-LEGi0N", "Generic Hardcoded Subs")]
[TestCase("Movie.Title.2017.720p.SUBBED.HDRip.V2.XViD-26k.avi", "Generic Hardcoded Subs")]
[TestCase("Movie.Title.2000.1080p.BlueRay.x264.DTS.RoSubbed-playHD", null)]
[TestCase("Movie Title! 2018 [Web][MKV][h264][480p][AAC 2.0][Softsubs]", null)]
[TestCase("Movie Title! 2019 [HorribleSubs][Web][MKV][h264][848x480][AAC 2.0][Softsubs(HorribleSubs)]", null)]
public void should_parse_hardcoded_subs(string postTitle, string sub)
{
QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub);
}
[TestCase("Movie Title 2018 REPACK 720p x264 aAF", true)]
[TestCase("Movie.Title.2018.REPACK.720p.x264-aAF", true)]
[TestCase("Movie.Title.2018.PROPER.720p.x264-aAF", false)]

View File

@@ -51,7 +51,6 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Some.Really.Bad.Movie.Title.[2021].1080p.WEB-HDRip.Dual.Audio.[Hindi.[Clean]. .English].x264.AAC.DD.2.0.By.Full4Movies.mkv-xpost", null)]
[TestCase("The.Movie.Title.2013.1080p.10bit.AMZN.WEB-DL.DDP5.1.HEVC-Vyndros", "Vyndros")]
[TestCase("Movie.Name.2022.1080p.BluRay.x264-[YTS.AG]", "YTS.AG")]
[TestCase("Movie.Name.2022.1080p.BluRay.x264-VARYG", "VARYG")]
[TestCase("Movie.Title.2019.1080p.AMZN.WEB-Rip.DDP.5.1.HEVC", null)]
public void should_parse_expected_release_group(string title, string expected)
{
@@ -108,7 +107,6 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Why.Cant.You.Use.Normal.Characters.2021.2160p.UHD.HDR10+.BluRay.TrueHD.Atmos.7.1.x265-ZØNEHD", "ZØNEHD")]
[TestCase("Movie.Should.Not.Use.Dots.2022.1080p.BluRay.x265.10bit.Tigole", "Tigole")]
[TestCase("Movie.Title.2005.2160p.UHD.BluRay.TrueHD 7.1.Atmos.x265 - HQMUX", "HQMUX")]
[TestCase("Movie.Name.2022.1080p.BluRay.x264-VARYG (Blue Lock, Multi-Subs)", "VARYG")]
public void should_parse_exception_release_group(string title, string expected)
{
Parser.Parser.ParseReleaseGroup(title).Should().Be(expected);

View File

@@ -22,7 +22,7 @@ namespace NzbDrone.Core.Test.Profiles
{
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
MinFormatScore = 0,
FormatItems = CustomFormatsTestHelpers.GetDefaultFormatItems(),
FormatItems = CustomFormatsFixture.GetDefaultFormatItems(),
Cutoff = Quality.Bluray1080p.Id,
Name = "TestProfile"
};

View File

@@ -170,9 +170,9 @@ namespace NzbDrone.Core.Test.Profiles
var customFormat1 = new CustomFormat("My Format 1", new LanguageSpecification { Value = (int)Language.English }) { Id = 1 };
var customFormat2 = new CustomFormat("My Format 2", new LanguageSpecification { Value = (int)Language.French }) { Id = 2 };
CustomFormatsTestHelpers.GivenCustomFormats(customFormat1, customFormat2);
CustomFormatsFixture.GivenCustomFormats(customFormat1, customFormat2);
profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(customFormat2.Name);
profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(customFormat2.Name);
Mocker.GetMock<IProfileRepository>()
.Setup(s => s.Get(It.IsAny<int>()))

View File

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

View File

@@ -14,133 +14,28 @@ namespace NzbDrone.Core.CustomFormats
{
public interface ICustomFormatCalculationService
{
List<CustomFormat> ParseCustomFormat(RemoteMovie remoteMovie, long size);
List<CustomFormat> ParseCustomFormat(MovieFile movieFile, Movie movie);
List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo, Movie movie);
List<CustomFormat> ParseCustomFormat(MovieFile movieFile);
List<CustomFormat> ParseCustomFormat(Blocklist blocklist, Movie movie);
List<CustomFormat> ParseCustomFormat(MovieHistory history, Movie movie);
List<CustomFormat> ParseCustomFormat(LocalMovie localMovie);
List<CustomFormat> ParseCustomFormat(Blocklist blocklist);
List<CustomFormat> ParseCustomFormat(MovieHistory history);
}
public class CustomFormatCalculationService : ICustomFormatCalculationService
{
private readonly ICustomFormatService _formatService;
private readonly IParsingService _parsingService;
private readonly IMovieService _movieService;
public CustomFormatCalculationService(ICustomFormatService formatService)
public CustomFormatCalculationService(ICustomFormatService formatService,
IParsingService parsingService,
IMovieService movieService)
{
_formatService = formatService;
_parsingService = parsingService;
_movieService = movieService;
}
public List<CustomFormat> ParseCustomFormat(RemoteMovie remoteMovie, long size)
{
var input = new CustomFormatInput
{
MovieInfo = remoteMovie.ParsedMovieInfo,
Movie = remoteMovie.Movie,
Size = size,
Languages = remoteMovie.Languages
};
return ParseCustomFormat(input);
}
public List<CustomFormat> ParseCustomFormat(MovieFile movieFile, Movie movie)
{
return ParseCustomFormat(movieFile, movie, _formatService.All());
}
public List<CustomFormat> ParseCustomFormat(MovieFile movieFile)
{
return ParseCustomFormat(movieFile, movieFile.Movie, _formatService.All());
}
public List<CustomFormat> ParseCustomFormat(Blocklist blocklist, Movie movie)
{
var parsed = Parser.Parser.ParseMovieTitle(blocklist.SourceTitle);
var movieInfo = new ParsedMovieInfo
{
MovieTitles = new List<string>() { movie.Title },
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? blocklist.SourceTitle.SimplifyReleaseTitle(),
ReleaseTitle = parsed?.ReleaseTitle ?? blocklist.SourceTitle,
Edition = parsed?.Edition,
Quality = blocklist.Quality,
Languages = blocklist.Languages,
ReleaseGroup = parsed?.ReleaseGroup
};
var input = new CustomFormatInput
{
MovieInfo = movieInfo,
Movie = movie,
Size = blocklist.Size ?? 0,
IndexerFlags = blocklist.IndexerFlags,
Languages = blocklist.Languages
};
return ParseCustomFormat(input);
}
public List<CustomFormat> ParseCustomFormat(MovieHistory history, Movie movie)
{
var parsed = Parser.Parser.ParseMovieTitle(history.SourceTitle);
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags flags);
var movieInfo = new ParsedMovieInfo
{
MovieTitles = new List<string>() { movie.Title },
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? history.SourceTitle.SimplifyReleaseTitle(),
ReleaseTitle = parsed?.ReleaseTitle ?? history.SourceTitle,
Edition = parsed?.Edition,
Quality = history.Quality,
Languages = history.Languages,
ReleaseGroup = parsed?.ReleaseGroup,
};
var input = new CustomFormatInput
{
MovieInfo = movieInfo,
Movie = movie,
Size = size,
IndexerFlags = flags,
Languages = history.Languages
};
return ParseCustomFormat(input);
}
public List<CustomFormat> ParseCustomFormat(LocalMovie localMovie)
{
var episodeInfo = new ParsedMovieInfo
{
MovieTitles = new List<string>() { localMovie.Movie.Title },
SimpleReleaseTitle = localMovie.SceneName?.SimplifyReleaseTitle(),
ReleaseTitle = localMovie.SceneName,
Quality = localMovie.Quality,
Edition = localMovie.Edition,
Languages = localMovie.Languages,
ReleaseGroup = localMovie.ReleaseGroup
};
var input = new CustomFormatInput
{
MovieInfo = episodeInfo,
Movie = localMovie.Movie,
Size = localMovie.Size,
Languages = localMovie.Languages
};
return ParseCustomFormat(input);
}
private List<CustomFormat> ParseCustomFormat(CustomFormatInput input)
{
return ParseCustomFormat(input, _formatService.All());
}
private static List<CustomFormat> ParseCustomFormat(CustomFormatInput input, List<CustomFormat> allCustomFormats)
public static List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo, List<CustomFormat> allCustomFormats)
{
var matches = new List<CustomFormat>();
@@ -150,7 +45,7 @@ namespace NzbDrone.Core.CustomFormats
.GroupBy(t => t.GetType())
.Select(g => new SpecificationMatchesGroup
{
Matches = g.ToDictionary(t => t, t => t.IsSatisfiedBy(input))
Matches = g.ToDictionary(t => t, t => t.IsSatisfiedBy(movieInfo))
})
.ToList();
@@ -163,7 +58,7 @@ namespace NzbDrone.Core.CustomFormats
return matches;
}
private static List<CustomFormat> ParseCustomFormat(MovieFile movieFile, Movie movie, List<CustomFormat> allCustomFormats)
public static List<CustomFormat> ParseCustomFormat(MovieFile movieFile, List<CustomFormat> allCustomFormats)
{
var sceneName = string.Empty;
if (movieFile.SceneName.IsNotNullOrWhiteSpace())
@@ -179,29 +74,90 @@ namespace NzbDrone.Core.CustomFormats
sceneName = Path.GetFileName(movieFile.RelativePath);
}
var movieInfo = new ParsedMovieInfo
var info = new ParsedMovieInfo
{
MovieTitles = new List<string>() { movie.Title },
MovieTitles = new List<string>() { movieFile.Movie.MovieMetadata.Value.Title },
SimpleReleaseTitle = sceneName.SimplifyReleaseTitle(),
Quality = movieFile.Quality,
Languages = movieFile.Languages,
ReleaseGroup = movieFile.ReleaseGroup,
Edition = movieFile.Edition,
Year = movieFile.Movie.MovieMetadata.Value.Year,
ImdbId = movieFile.Movie.MovieMetadata.Value.ImdbId
ImdbId = movieFile.Movie.MovieMetadata.Value.ImdbId,
ExtraInfo = new Dictionary<string, object>
{
{ "IndexerFlags", movieFile.IndexerFlags },
{ "Size", movieFile.Size },
{ "Filename", Path.GetFileName(movieFile.RelativePath) },
{ "OriginalLanguage", movieFile.Movie.MovieMetadata.Value.OriginalLanguage }
}
};
var input = new CustomFormatInput
return ParseCustomFormat(info, allCustomFormats);
}
public List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo, Movie movie)
{
movieInfo = _parsingService.EnhanceMovieInfo(movieInfo, new List<object> { movie }) ?? movieInfo;
return ParseCustomFormat(movieInfo, _formatService.All());
}
public List<CustomFormat> ParseCustomFormat(MovieFile movieFile)
{
return ParseCustomFormat(movieFile, _formatService.All());
}
public List<CustomFormat> ParseCustomFormat(Blocklist blocklist)
{
var movie = _movieService.GetMovie(blocklist.MovieId);
var parsed = _parsingService.ParseMovieInfo(blocklist.SourceTitle, null);
var info = new ParsedMovieInfo
{
MovieInfo = movieInfo,
Movie = movie,
Size = movieFile.Size,
IndexerFlags = movieFile.IndexerFlags,
Languages = movieFile.Languages,
Filename = Path.GetFileName(movieFile.RelativePath)
MovieTitles = new List<string>() { movie.MovieMetadata.Value.Title },
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? blocklist.SourceTitle.SimplifyReleaseTitle(),
Quality = blocklist.Quality,
Languages = blocklist.Languages,
ReleaseGroup = parsed?.ReleaseGroup,
Edition = parsed?.Edition,
Year = movie.MovieMetadata.Value.Year,
ImdbId = movie.MovieMetadata.Value.ImdbId,
ExtraInfo = new Dictionary<string, object>
{
{ "IndexerFlags", blocklist.IndexerFlags },
{ "Size", blocklist.Size }
}
};
return ParseCustomFormat(input, allCustomFormats);
return ParseCustomFormat(info, movie);
}
public List<CustomFormat> ParseCustomFormat(MovieHistory history)
{
var movie = _movieService.GetMovie(history.MovieId);
var parsed = _parsingService.ParseMovieInfo(history.SourceTitle, null);
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags flags);
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
var info = new ParsedMovieInfo
{
MovieTitles = new List<string>() { movie.MovieMetadata.Value.Title },
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? history.SourceTitle.SimplifyReleaseTitle(),
Quality = history.Quality,
Languages = history.Languages,
ReleaseGroup = parsed?.ReleaseGroup,
Edition = parsed?.Edition,
Year = movie.MovieMetadata.Value.Year,
ImdbId = movie.MovieMetadata.Value.ImdbId,
ExtraInfo = new Dictionary<string, object>
{
{ "IndexerFlags", flags },
{ "Size", size }
}
};
return ParseCustomFormat(info, movie);
}
}
}

View File

@@ -1,22 +0,0 @@
using System.Collections.Generic;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class CustomFormatInput
{
public ParsedMovieInfo MovieInfo { get; set; }
public Movie Movie { get; set; }
public long Size { get; set; }
public IndexerFlags IndexerFlags { get; set; }
public List<Language> Languages { get; set; }
public string Filename { get; set; }
public CustomFormatInput()
{
Languages = new List<Language>();
}
}
}

View File

@@ -21,9 +21,9 @@ namespace NzbDrone.Core.CustomFormats
public abstract NzbDroneValidationResult Validate();
public bool IsSatisfiedBy(CustomFormatInput input)
public bool IsSatisfiedBy(ParsedMovieInfo movieInfo)
{
var match = IsSatisfiedByWithoutNegate(input);
var match = IsSatisfiedByWithoutNegate(movieInfo);
if (Negate)
{
match = !match;
@@ -32,6 +32,6 @@ namespace NzbDrone.Core.CustomFormats
return match;
}
protected abstract bool IsSatisfiedByWithoutNegate(CustomFormatInput input);
protected abstract bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo);
}
}

View File

@@ -1,3 +1,5 @@
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public class EditionSpecification : RegexSpecificationBase
@@ -6,9 +8,9 @@ namespace NzbDrone.Core.CustomFormats
public override string ImplementationName => "Edition";
public override string InfoLink => "https://wiki.servarr.com/radarr/settings#custom-formats-2";
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return MatchString(input.MovieInfo.Edition);
return MatchString(movieInfo.Edition);
}
}
}

View File

@@ -15,6 +15,6 @@ namespace NzbDrone.Core.CustomFormats
NzbDroneValidationResult Validate();
ICustomFormatSpecification Clone();
bool IsSatisfiedBy(CustomFormatInput input);
bool IsSatisfiedBy(ParsedMovieInfo movieInfo);
}
}

View File

@@ -32,9 +32,10 @@ namespace NzbDrone.Core.CustomFormats
[FieldDefinition(1, Label = "Flag", Type = FieldType.Select, SelectOptions = typeof(IndexerFlags))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return input.IndexerFlags.HasFlag((IndexerFlags)Value) == true;
var flags = movieInfo?.ExtraInfo?.GetValueOrDefault("IndexerFlags") as IndexerFlags?;
return flags?.HasFlag((IndexerFlags)Value) == true;
}
public override NzbDroneValidationResult Validate()

View File

@@ -32,12 +32,12 @@ namespace NzbDrone.Core.CustomFormats
[FieldDefinition(1, Label = "Language", Type = FieldType.Select, SelectOptions = typeof(LanguageFieldConverter))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
var comparedLanguage = input.MovieInfo != null && Value == Language.Original.Id && input.Movie.MovieMetadata.Value.OriginalLanguage != Language.Unknown
? input.Movie.MovieMetadata.Value.OriginalLanguage
var comparedLanguage = movieInfo != null && Value == Language.Original.Id && movieInfo.ExtraInfo.ContainsKey("OriginalLanguage")
? (Language)movieInfo.ExtraInfo["OriginalLanguage"]
: (Language)Value;
return input?.Languages?.Contains(comparedLanguage) ?? false;
return movieInfo?.Languages?.Contains(comparedLanguage) ?? false;
}
public override NzbDroneValidationResult Validate()

View File

@@ -32,9 +32,9 @@ namespace NzbDrone.Core.CustomFormats
[FieldDefinition(1, Label = "Quality Modifier", Type = FieldType.Select, SelectOptions = typeof(Modifier))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return (input.MovieInfo?.Quality?.Quality?.Modifier ?? (int)Modifier.NONE) == (Modifier)Value;
return (movieInfo?.Quality?.Quality?.Modifier ?? (int)Modifier.NONE) == (Modifier)Value;
}
public override NzbDroneValidationResult Validate()

View File

@@ -8,9 +8,9 @@ namespace NzbDrone.Core.CustomFormats
public override string ImplementationName => "Release Group";
public override string InfoLink => "https://wiki.servarr.com/radarr/settings#custom-formats-2";
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return MatchString(input.MovieInfo?.ReleaseGroup);
return MatchString(movieInfo?.ReleaseGroup);
}
}
}

View File

@@ -9,9 +9,11 @@ namespace NzbDrone.Core.CustomFormats
public override string ImplementationName => "Release Title";
public override string InfoLink => "https://wiki.servarr.com/radarr/settings#custom-formats-2";
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return MatchString(input.MovieInfo?.SimpleReleaseTitle) || MatchString(input.Filename);
var filename = (string)movieInfo?.ExtraInfo?.GetValueOrDefault("Filename");
return MatchString(movieInfo?.SimpleReleaseTitle) || MatchString(filename);
}
}
}

View File

@@ -24,9 +24,9 @@ namespace NzbDrone.Core.CustomFormats
[FieldDefinition(1, Label = "Resolution", Type = FieldType.Select, SelectOptions = typeof(Resolution))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return (input.MovieInfo?.Quality?.Quality?.Resolution ?? (int)Resolution.Unknown) == Value;
return (movieInfo?.Quality?.Quality?.Resolution ?? (int)Resolution.Unknown) == Value;
}
public override NzbDroneValidationResult Validate()

View File

@@ -28,9 +28,9 @@ namespace NzbDrone.Core.CustomFormats
[FieldDefinition(1, Label = "Maximum Size", HelpText = "Release must be less than or equal to this size", Unit = "GB", Type = FieldType.Number)]
public double Max { get; set; }
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
var size = input.Size;
var size = (movieInfo?.ExtraInfo?.GetValueOrDefault("Size", 0.0) as long?) ?? 0;
return size > Min.Gigabytes() && size <= Max.Gigabytes();
}

View File

@@ -24,9 +24,9 @@ namespace NzbDrone.Core.CustomFormats
[FieldDefinition(1, Label = "Source", Type = FieldType.Select, SelectOptions = typeof(Source))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
{
return (input.MovieInfo?.Quality?.Quality?.Source ?? (int)Source.UNKNOWN) == (Source)Value;
return (movieInfo?.Quality?.Quality?.Source ?? (int)Source.UNKNOWN) == (Source)Value;
}
public override NzbDroneValidationResult Validate()

View File

@@ -1,14 +0,0 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(217)]
public class remove_omg : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Delete.FromTable("Indexers").Row(new { Implementation = "Omgwtfnzbs" });
}
}
}

View File

@@ -8,7 +8,6 @@ using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Download.Aggregation;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Parser;
@@ -29,21 +28,18 @@ namespace NzbDrone.Core.DecisionEngine
private readonly IParsingService _parsingService;
private readonly IConfigService _configService;
private readonly ICustomFormatCalculationService _formatCalculator;
private readonly IRemoteMovieAggregationService _aggregationService;
private readonly Logger _logger;
public DownloadDecisionMaker(IEnumerable<IDecisionEngineSpecification> specifications,
IParsingService parsingService,
IConfigService configService,
ICustomFormatCalculationService formatCalculator,
IRemoteMovieAggregationService aggregationService,
Logger logger)
{
_specifications = specifications;
_parsingService = parsingService;
_configService = configService;
_formatCalculator = formatCalculator;
_aggregationService = aggregationService;
_logger = logger;
}
@@ -108,11 +104,11 @@ namespace NzbDrone.Core.DecisionEngine
result.ReleaseName = report.Title;
var remoteMovie = result.RemoteMovie;
remoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(parsedMovieInfo, result?.Movie);
remoteMovie.CustomFormatScore = remoteMovie?.Movie?.Profile?.CalculateCustomFormatScore(remoteMovie.CustomFormats) ?? 0;
remoteMovie.Release = report;
remoteMovie.MappingResult = result.MappingResultType;
_aggregationService.Augment(remoteMovie);
if (result.MappingResultType != MappingResultType.Success)
{
var rejection = result.ToRejection();
@@ -120,11 +116,33 @@ namespace NzbDrone.Core.DecisionEngine
}
else
{
remoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(remoteMovie, remoteMovie.Release.Size);
remoteMovie.CustomFormatScore = remoteMovie?.Movie?.Profile?.CalculateCustomFormatScore(remoteMovie.CustomFormats) ?? 0;
remoteMovie.DownloadAllowed = remoteMovie.Movie != null;
decision = GetDecisionForReport(remoteMovie, searchCriteria);
if (parsedMovieInfo.Quality.HardcodedSubs.IsNotNullOrWhiteSpace())
{
// remoteMovie.DownloadAllowed = true;
if (_configService.AllowHardcodedSubs)
{
decision = GetDecisionForReport(remoteMovie, searchCriteria);
}
else
{
var whitelisted = _configService.WhitelistedHardcodedSubs.Split(',');
_logger.Debug("Testing: {0}", whitelisted);
if (whitelisted != null && whitelisted.Any(t => (parsedMovieInfo.Quality.HardcodedSubs.ToLower().Contains(t.ToLower()) && t.IsNotNullOrWhiteSpace())))
{
decision = GetDecisionForReport(remoteMovie, searchCriteria);
}
else
{
decision = new DownloadDecision(remoteMovie, new Rejection("Hardcoded subs found: " + parsedMovieInfo.Quality.HardcodedSubs));
}
}
}
else
{
// _aggregationService.Augment(remoteMovie);
remoteMovie.DownloadAllowed = remoteMovie.Movie != null;
decision = GetDecisionForReport(remoteMovie, searchCriteria);
}
}
}
catch (Exception e)

View File

@@ -1,47 +0,0 @@
using System.Linq;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
public class HardcodeSubsSpecification : IDecisionEngineSpecification
{
private readonly IConfigService _configService;
private readonly Logger _logger;
public HardcodeSubsSpecification(IConfigService configService, Logger logger)
{
_configService = configService;
_logger = logger;
}
public SpecificationPriority Priority => SpecificationPriority.Default;
public RejectionType Type => RejectionType.Permanent;
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
var hardcodeSubs = subject.ParsedMovieInfo.HardcodedSubs;
if (_configService.AllowHardcodedSubs || hardcodeSubs.IsNullOrWhiteSpace())
{
return Decision.Accept();
}
var whitelisted = _configService.WhitelistedHardcodedSubs.Split(',');
if (whitelisted != null && whitelisted.Any(t => (hardcodeSubs.ToLower().Contains(t.ToLower()) && t.IsNotNullOrWhiteSpace())))
{
_logger.Debug("Release hardcode subs ({0}) are in allowed values ({1})", hardcodeSubs, whitelisted);
return Decision.Accept();
}
else
{
_logger.Debug("Hardcode subs found: {0}", hardcodeSubs);
return Decision.Reject("Hardcode subs found: {0}", hardcodeSubs);
}
}
}
}

View File

@@ -31,10 +31,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
if (wantedLanguage == Language.Original)
{
if (!subject.Languages.Contains(originalLanguage))
if (!subject.ParsedMovieInfo.Languages.Contains(originalLanguage))
{
_logger.Debug("Original Language({0}) is wanted, but found {1}", originalLanguage, subject.Languages.ToExtendedString());
return Decision.Reject("Original Language ({0}) is wanted, but found {1}", originalLanguage, subject.Languages.ToExtendedString());
_logger.Debug("Original Language({0}) is wanted, but found {1}", originalLanguage, subject.ParsedMovieInfo.Languages.ToExtendedString());
return Decision.Reject("Original Language ({0}) is wanted, but found {1}", originalLanguage, subject.ParsedMovieInfo.Languages.ToExtendedString());
}
return Decision.Accept();
@@ -42,10 +42,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
_logger.Debug("Checking if report meets language requirements. {0}", subject.ParsedMovieInfo.Languages.ToExtendedString());
if (!subject.Languages.Contains(wantedLanguage))
if (!subject.ParsedMovieInfo.Languages.Contains(wantedLanguage))
{
_logger.Debug("Report Language: {0} rejected because it is not wanted, wanted {1}", subject.Languages.ToExtendedString(), wantedLanguage);
return Decision.Reject("{0} is wanted, but found {1}", wantedLanguage, subject.Languages.ToExtendedString());
_logger.Debug("Report Language: {0} rejected because it is not wanted, wanted {1}", subject.ParsedMovieInfo.Languages.ToExtendedString(), wantedLanguage);
return Decision.Reject("{0} is wanted, but found {1}", wantedLanguage, subject.ParsedMovieInfo.Languages.ToExtendedString());
}
return Decision.Accept();

View File

@@ -50,7 +50,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
continue;
}
var customFormats = _formatService.ParseCustomFormat(remoteMovie, (long)queueItem.Size);
var customFormats = _formatService.ParseCustomFormat(remoteMovie.ParsedMovieInfo, subject.Movie);
_logger.Debug("Checking if existing release in queue meets cutoff. Queued quality is: {0} - {1}",
remoteMovie.ParsedMovieInfo.Quality,

View File

@@ -49,7 +49,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
if (mostRecent != null && mostRecent.EventType == MovieHistoryEventType.Grabbed)
{
var customFormats = _formatService.ParseCustomFormat(mostRecent, subject.Movie);
var customFormats = _formatService.ParseCustomFormat(mostRecent);
var cutoffUnmet = _upgradableSpecification.CutoffNotMet(subject.Movie.Profile,
mostRecent.Quality,

View File

@@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download.Aggregation.Aggregators
{
public class AggregateLanguages : IAggregateRemoteMovie
{
private readonly Logger _logger;
public AggregateLanguages(Logger logger)
{
_logger = logger;
}
public RemoteMovie Aggregate(RemoteMovie remoteMovie)
{
var parsedMovieInfo = remoteMovie.ParsedMovieInfo;
var languages = parsedMovieInfo.Languages;
var movie = remoteMovie.Movie;
var releaseTokens = parsedMovieInfo.SimpleReleaseTitle ?? parsedMovieInfo.ReleaseTitle;
var normalizedReleaseTokens = Parser.Parser.NormalizeEpisodeTitle(releaseTokens);
var languagesToRemove = new List<Language>();
if (movie == null)
{
_logger.Debug("Unable to aggregate languages, using parsed values: {0}", string.Join(", ", languages.ToList()));
remoteMovie.Languages = languages;
return remoteMovie;
}
var movieTitleLanguage = LanguageParser.ParseLanguages(movie.Title);
if (!movieTitleLanguage.Contains(Language.Unknown))
{
var normalizedEpisodeTitle = Parser.Parser.NormalizeEpisodeTitle(movie.Title);
var movieTitleIndex = normalizedReleaseTokens.IndexOf(normalizedEpisodeTitle, StringComparison.CurrentCultureIgnoreCase);
if (movieTitleIndex >= 0)
{
releaseTokens = releaseTokens.Remove(movieTitleIndex, normalizedEpisodeTitle.Length);
languagesToRemove.AddRange(movieTitleLanguage);
}
}
// Remove any languages still in the title that would normally be removed
languagesToRemove = languagesToRemove.Except(LanguageParser.ParseLanguages(releaseTokens)).ToList();
// Remove all languages that aren't part of the updated releaseTokens
languages = languages.Except(languagesToRemove).ToList();
// Use movie language as fallback if we couldn't parse a language
if (languages.Count == 0 || (languages.Count == 1 && languages.First() == Language.Unknown))
{
languages = new List<Language> { movie.MovieMetadata.Value.OriginalLanguage };
_logger.Debug("Language couldn't be parsed from release, fallback to movie original language: {0}", movie.MovieMetadata.Value.OriginalLanguage.Name);
}
if (languages.Contains(Language.Original))
{
languages.Remove(Language.Original);
if (!languages.Contains(movie.MovieMetadata.Value.OriginalLanguage))
{
languages.Add(movie.MovieMetadata.Value.OriginalLanguage);
}
else
{
languages.Add(Language.Unknown);
}
}
_logger.Debug("Selected languages: {0}", string.Join(", ", languages.ToList()));
remoteMovie.Languages = languages;
return remoteMovie;
}
}
}

View File

@@ -1,9 +0,0 @@
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download.Aggregation.Aggregators
{
public interface IAggregateRemoteMovie
{
RemoteMovie Aggregate(RemoteMovie remoteMovie);
}
}

View File

@@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using NLog;
using NzbDrone.Core.Download.Aggregation.Aggregators;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download.Aggregation
{
public interface IRemoteMovieAggregationService
{
RemoteMovie Augment(RemoteMovie remoteMovie);
}
public class RemoteMovieAggregationService : IRemoteMovieAggregationService
{
private readonly IEnumerable<IAggregateRemoteMovie> _augmenters;
private readonly Logger _logger;
public RemoteMovieAggregationService(IEnumerable<IAggregateRemoteMovie> augmenters,
Logger logger)
{
_augmenters = augmenters;
_logger = logger;
}
public RemoteMovie Augment(RemoteMovie remoteMovie)
{
foreach (var augmenter in _augmenters)
{
try
{
augmenter.Aggregate(remoteMovie);
}
catch (Exception ex)
{
_logger.Warn(ex, ex.Message);
}
}
return remoteMovie;
}
}
}

View File

@@ -58,7 +58,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
result.Add(remoteMovie.ParsedMovieInfo.Quality.Quality.ToString());
break;
case (int)AdditionalTags.Languages:
result.UnionWith(remoteMovie.Languages.ConvertAll(language => language.ToString()));
result.UnionWith(remoteMovie.ParsedMovieInfo.Languages.ConvertAll(language => language.ToString()));
break;
case (int)AdditionalTags.ReleaseGroup:
result.Add(remoteMovie.ParsedMovieInfo.ReleaseGroup);

View File

@@ -134,33 +134,14 @@ namespace NzbDrone.Core.Download
trackedDownload.Warn("No files found are eligible for import in {0}", outputPath);
}
if (importResults.Count == 1)
{
var firstResult = importResults.First();
if (firstResult.Result == ImportResultType.Rejected && firstResult.ImportDecision.LocalMovie == null)
{
trackedDownload.Warn(new TrackedDownloadStatusMessage(firstResult.Errors.First(), new List<string>()));
return;
}
}
var statusMessages = new List<TrackedDownloadStatusMessage>
{
new TrackedDownloadStatusMessage("One or more movies expected in this release were not imported or missing", new List<string>())
};
if (importResults.Any(c => c.Result != ImportResultType.Imported))
{
statusMessages.AddRange(importResults
var statusMessages = importResults
.Where(v => v.Result != ImportResultType.Imported && v.ImportDecision.LocalMovie != null)
.Select(v => new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.LocalMovie.Path), v.Errors)));
.Select(v => new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.LocalMovie.Path), v.Errors))
.ToArray();
if (statusMessages.Any())
{
trackedDownload.Warn(statusMessages.ToArray());
}
trackedDownload.Warn(statusMessages);
}
}

View File

@@ -34,7 +34,7 @@ namespace NzbDrone.Core.Download
var downloadIgnoredEvent = new DownloadIgnoredEvent
{
MovieId = movie.Id,
Languages = trackedDownload.RemoteMovie.Languages,
Languages = trackedDownload.RemoteMovie.ParsedMovieInfo.Languages,
Quality = trackedDownload.RemoteMovie.ParsedMovieInfo.Quality,
SourceTitle = trackedDownload.DownloadItem.Title,
DownloadClientInfo = trackedDownload.DownloadItem.DownloadClientInfo,

View File

@@ -7,7 +7,6 @@ using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download.Aggregation;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Languages;
@@ -45,7 +44,6 @@ namespace NzbDrone.Core.Download.Pending
private readonly IDelayProfileService _delayProfileService;
private readonly ITaskManager _taskManager;
private readonly IConfigService _configService;
private readonly IRemoteMovieAggregationService _aggregationService;
private readonly ICustomFormatCalculationService _formatCalculator;
private readonly IEventAggregator _eventAggregator;
private readonly Logger _logger;
@@ -57,7 +55,6 @@ namespace NzbDrone.Core.Download.Pending
IDelayProfileService delayProfileService,
ITaskManager taskManager,
IConfigService configService,
IRemoteMovieAggregationService aggregationService,
ICustomFormatCalculationService formatCalculator,
IEventAggregator eventAggregator,
Logger logger)
@@ -69,7 +66,6 @@ namespace NzbDrone.Core.Download.Pending
_delayProfileService = delayProfileService;
_taskManager = taskManager;
_configService = configService;
_aggregationService = aggregationService;
_formatCalculator = formatCalculator;
_eventAggregator = eventAggregator;
_logger = logger;
@@ -167,6 +163,8 @@ namespace NzbDrone.Core.Download.Pending
{
if (pendingRelease.RemoteMovie != null)
{
pendingRelease.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(pendingRelease.ParsedMovieInfo, pendingRelease.RemoteMovie.Movie);
var ect = pendingRelease.Release.PublishDate.AddMinutes(GetDelay(pendingRelease.RemoteMovie));
if (ect < nextRssSync.Value)
@@ -190,7 +188,7 @@ namespace NzbDrone.Core.Download.Pending
Id = GetQueueId(pendingRelease, pendingRelease.RemoteMovie.Movie),
Movie = pendingRelease.RemoteMovie.Movie,
Quality = pendingRelease.RemoteMovie.ParsedMovieInfo?.Quality ?? new QualityModel(),
Languages = pendingRelease.RemoteMovie.Languages,
Languages = pendingRelease.RemoteMovie.ParsedMovieInfo?.Languages ?? new List<Language>(),
Title = pendingRelease.Title,
Size = pendingRelease.RemoteMovie.Release.Size,
Sizeleft = pendingRelease.RemoteMovie.Release.Size,
@@ -298,9 +296,6 @@ namespace NzbDrone.Core.Download.Pending
Release = release.Release
};
_aggregationService.Augment(release.RemoteMovie);
release.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(release.RemoteMovie, release.Release.Size);
result.Add(release);
}

View File

@@ -6,7 +6,6 @@ using NzbDrone.Common.Cache;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.Download.Aggregation;
using NzbDrone.Core.Download.History;
using NzbDrone.Core.History;
using NzbDrone.Core.Messaging.Events;
@@ -33,7 +32,6 @@ namespace NzbDrone.Core.Download.TrackedDownloads
private readonly IEventAggregator _eventAggregator;
private readonly IDownloadHistoryService _downloadHistoryService;
private readonly IConfigService _config;
private readonly IRemoteMovieAggregationService _aggregationService;
private readonly ICustomFormatCalculationService _formatCalculator;
private readonly Logger _logger;
private readonly ICached<TrackedDownload> _cache;
@@ -42,7 +40,6 @@ namespace NzbDrone.Core.Download.TrackedDownloads
ICacheManager cacheManager,
IHistoryService historyService,
IConfigService config,
IRemoteMovieAggregationService aggregationService,
ICustomFormatCalculationService formatCalculator,
IEventAggregator eventAggregator,
IDownloadHistoryService downloadHistoryService,
@@ -52,7 +49,6 @@ namespace NzbDrone.Core.Download.TrackedDownloads
_historyService = historyService;
_cache = cacheManager.GetCache<TrackedDownload>(GetType());
_config = config;
_aggregationService = aggregationService;
_formatCalculator = formatCalculator;
_eventAggregator = eventAggregator;
_downloadHistoryService = downloadHistoryService;
@@ -122,8 +118,6 @@ namespace NzbDrone.Core.Download.TrackedDownloads
if (parsedMovieInfo != null)
{
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie;
_aggregationService.Augment(trackedDownload.RemoteMovie);
}
var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId);
@@ -157,7 +151,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
// Calculate custom formats
if (trackedDownload.RemoteMovie != null)
{
trackedDownload.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(trackedDownload.RemoteMovie, downloadItem.TotalSize);
trackedDownload.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(parsedMovieInfo, trackedDownload.RemoteMovie.Movie);
}
// Track it so it can be displayed in the queue even though we can't determine which movie it is for
@@ -198,8 +192,6 @@ namespace NzbDrone.Core.Download.TrackedDownloads
var parsedMovieInfo = Parser.Parser.ParseMovieTitle(trackedDownload.DownloadItem.Title);
trackedDownload.RemoteMovie = parsedMovieInfo == null ? null : _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie;
_aggregationService.Augment(trackedDownload.RemoteMovie);
}
private static TrackedDownloadState GetStateFromHistory(DownloadHistoryEventType eventType)

View File

@@ -132,7 +132,7 @@ namespace NzbDrone.Core.History
EventType = MovieHistoryEventType.Grabbed,
Date = DateTime.UtcNow,
Quality = message.Movie.ParsedMovieInfo.Quality,
Languages = message.Movie.Languages,
Languages = message.Movie.ParsedMovieInfo.Languages,
SourceTitle = message.Movie.Release.Title,
DownloadId = message.DownloadId,
MovieId = message.Movie.Movie.Id
@@ -203,7 +203,6 @@ namespace NzbDrone.Core.History
history.Data.Add("DownloadClient", message.DownloadClientInfo?.Type);
history.Data.Add("DownloadClientName", message.DownloadClientInfo?.Name);
history.Data.Add("ReleaseGroup", message.MovieInfo.ReleaseGroup);
history.Data.Add("CustomFormatScore", message.MovieInfo.CustomFormatScore.ToString());
_historyRepository.Insert(history);
}

View File

@@ -1,91 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Profiles;
namespace NzbDrone.Core.Housekeeping.Housekeepers
{
public class CleanupQualityProfileFormatItems : IHousekeepingTask
{
private readonly IQualityProfileFormatItemsCleanupRepository _repository;
private readonly ICustomFormatRepository _customFormatRepository;
public CleanupQualityProfileFormatItems(IQualityProfileFormatItemsCleanupRepository repository,
ICustomFormatRepository customFormatRepository)
{
_repository = repository;
_customFormatRepository = customFormatRepository;
}
public void Clean()
{
var customFormats = _customFormatRepository.All().ToDictionary(c => c.Id);
var profiles = _repository.All();
var updatedProfiles = new List<Profile>();
foreach (var profile in profiles)
{
var formatItems = new List<ProfileFormatItem>();
// Make sure the profile doesn't include formats that have been removed
profile.FormatItems.ForEach(p =>
{
if (p.Format != null && customFormats.ContainsKey(p.Format.Id))
{
formatItems.Add(p);
}
});
// Make sure the profile includes all available formats
foreach (var customFormat in customFormats)
{
if (formatItems.None(f => f.Format.Id == customFormat.Key))
{
formatItems.Insert(0, new ProfileFormatItem
{
Format = customFormat.Value,
Score = 0
});
}
}
var previousIds = profile.FormatItems.Select(i => i.Format.Id).ToList();
var ids = formatItems.Select(i => i.Format.Id).ToList();
// Update the profile if any formats were added or removed
if (ids.Except(previousIds).Any() || previousIds.Except(ids).Any())
{
profile.FormatItems = formatItems;
if (profile.FormatItems.Empty())
{
profile.MinFormatScore = 0;
profile.CutoffFormatScore = 0;
}
updatedProfiles.Add(profile);
}
}
if (updatedProfiles.Any())
{
_repository.SetFields(updatedProfiles, p => p.FormatItems, p => p.MinFormatScore, p => p.CutoffFormatScore);
}
}
}
public interface IQualityProfileFormatItemsCleanupRepository : IBasicRepository<Profile>
{
}
public class QualityProfileFormatItemsCleanupRepository : BasicRepository<Profile>, IQualityProfileFormatItemsCleanupRepository
{
public QualityProfileFormatItemsCleanupRepository(IMainDatabase database, IEventAggregator eventAggregator)
: base(database, eventAggregator)
{
}
}
}

View File

@@ -48,6 +48,7 @@ namespace NzbDrone.Core.Indexers.Newznab
yield return GetDefinition("NZBFinder.ws", GetSettings("https://nzbfinder.ws", categories: new[] { 2030, 2040, 2045, 2050, 2060, 2070, 2080, 2090 }));
yield return GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info"));
yield return GetDefinition("nzbplanet.net", GetSettings("https://api.nzbplanet.net"));
yield return GetDefinition("omgwtfnzbs", GetSettings("https://api.omgwtfnzbs.me", categories: new[] { 2000, 2020, 2030, 2040, 2045, 2050, 2070 }));
yield return GetDefinition("OZnzb.com", GetSettings("https://api.oznzb.com"));
yield return GetDefinition("SimplyNZBs", GetSettings("https://simplynzbs.com"));
yield return GetDefinition("Tabula Rasa", GetSettings("https://www.tabula-rasa.pw", apiPath: @"/api/v1/api"));

View File

@@ -0,0 +1,29 @@
using NLog;
using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Parser;
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
{
public class Omgwtfnzbs : HttpIndexerBase<OmgwtfnzbsSettings>
{
public override string Name => "omgwtfnzbs";
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
public Omgwtfnzbs(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
: base(httpClient, indexerStatusService, configService, parsingService, logger)
{
}
public override IIndexerRequestGenerator GetRequestGenerator()
{
return new OmgwtfnzbsRequestGenerator() { Settings = Settings };
}
public override IParseIndexerResponse GetParser()
{
return new OmgwtfnzbsRssParser();
}
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Text;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Core.IndexerSearch.Definitions;
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
{
public class OmgwtfnzbsRequestGenerator : IIndexerRequestGenerator
{
public string BaseUrl { get; set; }
public OmgwtfnzbsSettings Settings { get; set; }
public OmgwtfnzbsRequestGenerator()
{
BaseUrl = "https://rss.omgwtfnzbs.me/rss-download.php";
}
public virtual IndexerPageableRequestChain GetRecentRequests()
{
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetPagedRequests(null));
return pageableRequests;
}
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
foreach (var queryTitle in searchCriteria.CleanSceneTitles)
{
pageableRequests.Add(GetPagedRequests(string.Format("{0}",
queryTitle)));
}
return pageableRequests;
}
private IEnumerable<IndexerRequest> GetPagedRequests(string query)
{
var url = new StringBuilder();
url.AppendFormat("{0}?catid=15,16,17,18,31,35&user={1}&api={2}&eng=1&delay={3}", BaseUrl, Settings.Username, Settings.ApiKey, Settings.Delay);
if (query.IsNotNullOrWhiteSpace())
{
url = url.Replace("rss-download.php", "rss-search.php");
url.AppendFormat("&search={0}", query);
}
yield return new IndexerRequest(url.ToString(), HttpAccept.Rss);
}
public Func<IDictionary<string, string>> GetCookies { get; set; }
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
}
}

View File

@@ -0,0 +1,50 @@
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Indexers.Exceptions;
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
{
public class OmgwtfnzbsRssParser : RssParser
{
public OmgwtfnzbsRssParser()
{
UseEnclosureUrl = true;
UseEnclosureLength = true;
}
protected override bool PreProcess(IndexerResponse indexerResponse)
{
var xdoc = LoadXmlDocument(indexerResponse);
var notice = xdoc.Descendants("notice").FirstOrDefault();
if (notice == null)
{
return true;
}
if (!notice.Value.ContainsIgnoreCase("api"))
{
return true;
}
throw new ApiKeyException(notice.Value);
}
protected override string GetInfoUrl(XElement item)
{
// Todo: Me thinks I need to parse details to get this...
var match = Regex.Match(item.Description(),
@"(?:\<b\>View NZB\:\<\/b\>\s\<a\shref\=\"")(?<URL>.+?)(?:\"")",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
if (match.Success)
{
return match.Groups["URL"].Value;
}
return string.Empty;
}
}
}

View File

@@ -0,0 +1,49 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
{
public class OmgwtfnzbsSettingsValidator : AbstractValidator<OmgwtfnzbsSettings>
{
public OmgwtfnzbsSettingsValidator()
{
RuleFor(c => c.Username).NotEmpty();
RuleFor(c => c.ApiKey).NotEmpty();
RuleFor(c => c.Delay).GreaterThanOrEqualTo(0);
}
}
public class OmgwtfnzbsSettings : IIndexerSettings
{
private static readonly OmgwtfnzbsSettingsValidator Validator = new OmgwtfnzbsSettingsValidator();
public OmgwtfnzbsSettings()
{
Delay = 30;
MultiLanguages = new List<int>();
}
// Unused since Omg has a hardcoded url.
public string BaseUrl { get; set; }
[FieldDefinition(0, Label = "Username", Privacy = PrivacyLevel.UserName)]
public string Username { get; set; }
[FieldDefinition(1, Label = "API Key", Privacy = PrivacyLevel.ApiKey)]
public string ApiKey { get; set; }
[FieldDefinition(2, Label = "Delay", HelpText = "Time in minutes to delay new nzbs before they appear on the RSS feed", Advanced = true)]
public int Delay { get; set; }
[FieldDefinition(3, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@@ -97,7 +97,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
InfoUrl = GetInfoUrl(result.GroupId, id),
Seeders = int.Parse(torrent.Seeders),
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
PublishDate = TimeZoneInfo.ConvertTimeToUtc(torrent.UploadTime, TimeZoneInfo.Utc), // PTP returns UTC timestamps, without a timezone specifier.
PublishDate = torrent.UploadTime.ToUniversalTime(),
Golden = torrent.GoldenPopcorn,
Scene = torrent.Scene,
Approved = torrent.Checked,

View File

@@ -107,7 +107,6 @@ namespace NzbDrone.Core.Languages
public static Language Bengali => new Language(34, "Bengali");
public static Language Slovak => new Language(35, "Slovak");
public static Language Latvian => new Language(36, "Latvian");
public static Language SpanishLatino => new Language(37, "Spanish (Latino)");
public static Language Any => new Language(-1, "Any");
public static Language Original => new Language(-2, "Original");
@@ -154,7 +153,6 @@ namespace NzbDrone.Core.Languages
Bengali,
Slovak,
Latvian,
SpanishLatino,
Any,
Original
};

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