Track Parsing Code (#10)

* We now have the ability to import local tracks into Lidarr. Switching to IDv3 tag reading over custom parsing for local tracks.

* Stable code for track refresh.

* RefreshArtist and RescanArtist events are working correctly. Need to add potential rejection decisions in future.

* Implemented code comments

* PR comments and fixing some odd db bugs.

* Fix some conflicts after Unit Test PR Merge

Fix some conflicts after Unit Test PR Merge

* Track/Album Add and Update Fixes

Track/Album Add and Update Fixes

* Fixed an issue with trackimport looking up trackId instead of artistId

* Add Handle to TrackService for TrackAddedEvent

Add Handle to TrackService for TrackAddedEvent

* Update Quality Regex, Store BitRateMode in TrackFile

Update Quality Regex, Store BitRateMode in TrackFile
pull/14/head
Joseph Milazzo 7 years ago committed by GitHub
parent 4cfd39f7fe
commit ef4da4ac9f

@ -5,7 +5,7 @@
#define AppPublisher "Team Lidarr" #define AppPublisher "Team Lidarr"
#define AppURL "https://lidarr.audio/" #define AppURL "https://lidarr.audio/"
#define ForumsURL "https://forums.lidarr.audio/" #define ForumsURL "https://forums.lidarr.audio/"
#define AppExeName "NzbDrone.exe" #define AppExeName "Lidarr.exe"
#define BuildNumber "2.0" #define BuildNumber "2.0"
#define BuildNumber GetEnv('BUILD_NUMBER') #define BuildNumber GetEnv('BUILD_NUMBER')
#define BranchName GetEnv('branch') #define BranchName GetEnv('branch')
@ -21,15 +21,15 @@ AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL} AppPublisherURL={#AppURL}
AppSupportURL={#ForumsURL} AppSupportURL={#ForumsURL}
AppUpdatesURL={#AppURL} AppUpdatesURL={#AppURL}
DefaultDirName={commonappdata}\NzbDrone\bin DefaultDirName={commonappdata}\Lidarr\bin
DisableDirPage=yes DisableDirPage=yes
DefaultGroupName={#AppName} DefaultGroupName={#AppName}
DisableProgramGroupPage=yes DisableProgramGroupPage=yes
OutputBaseFilename=NzbDrone.{#BranchName}.{#BuildNumber} OutputBaseFilename=Lidarr.{#BranchName}.{#BuildNumber}
SolidCompression=yes SolidCompression=yes
AppCopyright=Creative Commons 3.0 License AppCopyright=Creative Commons 3.0 License
AllowUNCPath=False AllowUNCPath=False
UninstallDisplayIcon={app}\NzbDrone.exe UninstallDisplayIcon={app}\Lidarr.exe
DisableReadyPage=True DisableReadyPage=True
CompressionThreads=2 CompressionThreads=2
Compression=lzma2/normal Compression=lzma2/normal

@ -184,14 +184,14 @@ namespace NzbDrone.Api.Music
public void Handle(TrackImportedEvent message) public void Handle(TrackImportedEvent message)
{ {
BroadcastResourceChange(ModelAction.Updated, message.ImportedTrack.Id); // TODO: Ensure we can pass DB ID instead of Metadata ID (SpotifyID) BroadcastResourceChange(ModelAction.Updated, message.ImportedTrack.ArtistId);
} }
public void Handle(TrackFileDeletedEvent message) public void Handle(TrackFileDeletedEvent message)
{ {
if (message.Reason == DeleteMediaFileReason.Upgrade) return; if (message.Reason == DeleteMediaFileReason.Upgrade) return;
BroadcastResourceChange(ModelAction.Updated, message.TrackFile.Id); // TODO: Ensure we can pass DB ID instead of Metadata ID (SpotifyID) BroadcastResourceChange(ModelAction.Updated, message.TrackFile.ArtistId);
} }
public void Handle(ArtistUpdatedEvent message) public void Handle(ArtistUpdatedEvent message)

@ -46,7 +46,7 @@ namespace NzbDrone.Api.Music
public int ProfileId { get; set; } public int ProfileId { get; set; }
//Editing Only //Editing Only
public bool ArtistFolder { get; set; } public bool AlbumFolder { get; set; }
public bool Monitored { get; set; } public bool Monitored { get; set; }
public string RootFolderPath { get; set; } public string RootFolderPath { get; set; }
@ -96,6 +96,7 @@ namespace NzbDrone.Api.Music
ProfileId = model.ProfileId, ProfileId = model.ProfileId,
Monitored = model.Monitored, Monitored = model.Monitored,
AlbumFolder = model.AlbumFolder,
//UseSceneNumbering = resource.UseSceneNumbering, //UseSceneNumbering = resource.UseSceneNumbering,
//Runtime = resource.Runtime, //Runtime = resource.Runtime,
@ -150,6 +151,7 @@ namespace NzbDrone.Api.Music
Path = resource.Path, Path = resource.Path,
ProfileId = resource.ProfileId, ProfileId = resource.ProfileId,
AlbumFolder = resource.AlbumFolder,
Monitored = resource.Monitored, Monitored = resource.Monitored,
//LastInfoSync = resource.LastInfoSync, //LastInfoSync = resource.LastInfoSync,

@ -52,11 +52,10 @@ namespace NzbDrone.Api.TrackFiles
private TrackFileResource GetTrackFile(int id) private TrackFileResource GetTrackFile(int id)
{ {
throw new NotImplementedException(); var trackFile = _mediaFileService.Get(id);
//var episodeFile = _mediaFileService.Get(id); var artist = _artistService.GetArtist(trackFile.ArtistId);
//var series = _seriesService.GetSeries(episodeFile.SeriesId);
//return episodeFile.ToResource(series, _qualityUpgradableSpecification); return trackFile.ToResource(artist, _qualityUpgradableSpecification);
} }
private List<TrackFileResource> GetTrackFiles() private List<TrackFileResource> GetTrackFiles()

@ -17,11 +17,11 @@ namespace NzbDrone.Automation.Test
} }
[Test] [Test]
public void series_page() public void artist_page()
{ {
page.SeriesNavIcon.Click(); page.ArtistNavIcon.Click();
page.WaitForNoSpinner(); page.WaitForNoSpinner();
page.FindByClass("iv-series-index-seriesindexlayout").Should().NotBeNull(); page.FindByClass("iv-artist-index-artistindexlayout").Should().NotBeNull();
} }
[Test] [Test]
@ -63,14 +63,14 @@ namespace NzbDrone.Automation.Test
[Test] [Test]
public void add_series_page() public void add_series_page()
{ {
page.SeriesNavIcon.Click(); page.ArtistNavIcon.Click();
page.WaitForNoSpinner(); page.WaitForNoSpinner();
page.Find(By.LinkText("Add Series")).Click(); page.Find(By.LinkText("Add Artist")).Click();
page.WaitForNoSpinner(); page.WaitForNoSpinner();
page.FindByClass("iv-addseries-addserieslayout").Should().NotBeNull(); page.FindByClass("iv-addartist-addartistlayout").Should().NotBeNull();
} }
} }
} }

@ -47,7 +47,7 @@ namespace NzbDrone.Automation.Test.PageModel
}); });
} }
public IWebElement SeriesNavIcon => FindByClass("x-series-nav"); public IWebElement ArtistNavIcon => FindByClass("x-artist-nav");
public IWebElement CalendarNavIcon => FindByClass("x-calendar-nav"); public IWebElement CalendarNavIcon => FindByClass("x-calendar-nav");

@ -17,7 +17,7 @@ namespace NzbDrone.Common.Cloud
Services = new HttpRequestBuilder("http://services.lidarr.tv/v1/") Services = new HttpRequestBuilder("http://services.lidarr.tv/v1/")
.CreateFactory(); .CreateFactory();
Search = new HttpRequestBuilder("http://localhost:3000/{route}/") // TODO: Add {version} once LidarrAPI.Metadata is released. Search = new HttpRequestBuilder("http://localhost:5000/{route}/") // TODO: Add {version} once LidarrAPI.Metadata is released.
.CreateFactory(); .CreateFactory();

@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.Blacklisting
{ {
SeriesId = 12345, SeriesId = 12345,
EpisodeIds = new List<int> {1}, EpisodeIds = new List<int> {1},
Quality = new QualityModel(Quality.MP3320), Quality = new QualityModel(Quality.MP3_320),
SourceTitle = "series.title.s01e01", SourceTitle = "series.title.s01e01",
DownloadClient = "SabnzbdClient", DownloadClient = "SabnzbdClient",
DownloadId = "Sabnzbd_nzo_2dfh73k" DownloadId = "Sabnzbd_nzo_2dfh73k"

@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.Datastore
[Test] [Test]
public void embedded_document_as_json() public void embedded_document_as_json()
{ {
var quality = new QualityModel { Quality = Quality.MP3320, Revision = new Revision(version: 2 )}; var quality = new QualityModel { Quality = Quality.MP3_320, Revision = new Revision(version: 2 )};
var history = Builder<History.History>.CreateNew() var history = Builder<History.History>.CreateNew()
.With(c => c.Id = 0) .With(c => c.Id = 0)
@ -75,15 +75,15 @@ namespace NzbDrone.Core.Test.Datastore
.All().With(c => c.Id = 0) .All().With(c => c.Id = 0)
.Build().ToList(); .Build().ToList();
history[0].Quality = new QualityModel(Quality.MP3512, new Revision(version: 2)); history[0].Quality = new QualityModel(Quality.MP3_512, new Revision(version: 2));
history[1].Quality = new QualityModel(Quality.MP3320, new Revision(version: 2)); history[1].Quality = new QualityModel(Quality.MP3_320, new Revision(version: 2));
Db.InsertMany(history); Db.InsertMany(history);
var returnedHistory = Db.All<History.History>(); var returnedHistory = Db.All<History.History>();
returnedHistory[0].Quality.Quality.Should().Be(Quality.MP3512); returnedHistory[0].Quality.Quality.Should().Be(Quality.MP3_512);
} }
} }
} }

@ -19,7 +19,7 @@ namespace NzbDrone.Core.Test.Datastore
var profile = new Profile var profile = new Profile
{ {
Name = "Test", Name = "Test",
Cutoff = Quality.MP3320, Cutoff = Quality.MP3_320,
Items = Qualities.QualityFixture.GetDefaultQualities() Items = Qualities.QualityFixture.GetDefaultQualities()
}; };

@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
Series = series, Series = series,
Release = new ReleaseInfo(), Release = new ReleaseInfo(),
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = new List<Episode> { new Episode(), new Episode(), new Episode(), new Episode(), new Episode(), new Episode() } Episodes = new List<Episode> { new Episode(), new Episode(), new Episode(), new Episode(), new Episode(), new Episode() }
}; };
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
Series = series, Series = series,
Release = new ReleaseInfo(), Release = new ReleaseInfo(),
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = new List<Episode> { new Episode(), new Episode() } Episodes = new List<Episode> { new Episode(), new Episode() }
}; };
@ -48,7 +48,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
Series = series, Series = series,
Release = new ReleaseInfo(), Release = new ReleaseInfo(),
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = new List<Episode> { new Episode() { Id = 2 } } Episodes = new List<Episode> { new Episode() { Id = 2 } }
}; };
@ -60,10 +60,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
qualityType = Builder<QualityDefinition>.CreateNew() qualityType = Builder<QualityDefinition>.CreateNew()
.With(q => q.MinSize = 2) .With(q => q.MinSize = 2)
.With(q => q.MaxSize = 10) .With(q => q.MaxSize = 10)
.With(q => q.Quality = Quality.MP3192) .With(q => q.Quality = Quality.MP3_192)
.Build(); .Build();
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.MP3192)).Returns(qualityType); Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.MP3_192)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.GetEpisodesBySeason(It.IsAny<int>(), It.IsAny<int>())) s => s.GetEpisodesBySeason(It.IsAny<int>(), It.IsAny<int>()))

@ -28,7 +28,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_episodeFile = new EpisodeFile _episodeFile = new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision()), Quality = new QualityModel(Quality.MP3_256, new Revision()),
ReleaseGroup = "DRONE2" ReleaseGroup = "DRONE2"
}; };
@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_remoteEpisode.Series = new Series { SeriesType = SeriesTypes.Anime }; _remoteEpisode.Series = new Series { SeriesType = SeriesTypes.Anime };
_remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo _remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(2)), Quality = new QualityModel(Quality.MP3_256, new Revision(2)),
ReleaseGroup = "DRONE" ReleaseGroup = "DRONE"
}; };

@ -13,38 +13,38 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_return_true_if_current_episode_is_less_than_cutoff() public void should_return_true_if_current_episode_is_less_than_cutoff()
{ {
Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3512, Items = Qualities.QualityFixture.GetDefaultQualities() }, Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3_512, Items = Qualities.QualityFixture.GetDefaultQualities() },
new QualityModel(Quality.MP3192, new Revision(version: 2))).Should().BeTrue(); new QualityModel(Quality.MP3_192, new Revision(version: 2))).Should().BeTrue();
} }
[Test] [Test]
public void should_return_false_if_current_episode_is_equal_to_cutoff() public void should_return_false_if_current_episode_is_equal_to_cutoff()
{ {
Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3256, Items = Qualities.QualityFixture.GetDefaultQualities() }, Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3_256, Items = Qualities.QualityFixture.GetDefaultQualities() },
new QualityModel(Quality.MP3256, new Revision(version: 2))).Should().BeFalse(); new QualityModel(Quality.MP3_256, new Revision(version: 2))).Should().BeFalse();
} }
[Test] [Test]
public void should_return_false_if_current_episode_is_greater_than_cutoff() public void should_return_false_if_current_episode_is_greater_than_cutoff()
{ {
Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3256, Items = Qualities.QualityFixture.GetDefaultQualities() }, Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3_256, Items = Qualities.QualityFixture.GetDefaultQualities() },
new QualityModel(Quality.MP3512, new Revision(version: 2))).Should().BeFalse(); new QualityModel(Quality.MP3_512, new Revision(version: 2))).Should().BeFalse();
} }
[Test] [Test]
public void should_return_true_when_new_episode_is_proper_but_existing_is_not() public void should_return_true_when_new_episode_is_proper_but_existing_is_not()
{ {
Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3256, Items = Qualities.QualityFixture.GetDefaultQualities() }, Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3_256, Items = Qualities.QualityFixture.GetDefaultQualities() },
new QualityModel(Quality.MP3256, new Revision(version: 1)), new QualityModel(Quality.MP3_256, new Revision(version: 1)),
new QualityModel(Quality.MP3256, new Revision(version: 2))).Should().BeTrue(); new QualityModel(Quality.MP3_256, new Revision(version: 2))).Should().BeTrue();
} }
[Test] [Test]
public void should_return_false_if_cutoff_is_met_and_quality_is_higher() public void should_return_false_if_cutoff_is_met_and_quality_is_higher()
{ {
Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3256, Items = Qualities.QualityFixture.GetDefaultQualities() }, Subject.CutoffNotMet(new Profile { Cutoff = Quality.MP3_256, Items = Qualities.QualityFixture.GetDefaultQualities() },
new QualityModel(Quality.MP3256, new Revision(version: 2)), new QualityModel(Quality.MP3_256, new Revision(version: 2)),
new QualityModel(Quality.MP3512, new Revision(version: 2))).Should().BeFalse(); new QualityModel(Quality.MP3_512, new Revision(version: 2))).Should().BeFalse();
} }
} }
} }

@ -1,75 +0,0 @@

using System;
using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
using FizzWare.NBuilder;
using System.Linq;
using FluentAssertions;
using NzbDrone.Core.Tv;
using Moq;
using System.Collections.Generic;
namespace NzbDrone.Core.Test.DecisionEngineTests
{
[TestFixture]
public class FullSeasonSpecificationFixture : CoreTest<FullSeasonSpecification>
{
private RemoteEpisode _remoteEpisode;
[SetUp]
public void Setup()
{
var show = Builder<Series>.CreateNew().With(s => s.Id = 1234).Build();
_remoteEpisode = new RemoteEpisode
{
ParsedEpisodeInfo = new ParsedEpisodeInfo
{
FullSeason = true
},
Episodes = Builder<Episode>.CreateListOfSize(3)
.All()
.With(e => e.AirDateUtc = DateTime.UtcNow.AddDays(-8))
.With(s => s.SeriesId = show.Id)
.BuildList(),
Series = show,
Release = new ReleaseInfo
{
Title = "Series.Title.S01.720p.BluRay.X264-RlsGrp"
}
};
Mocker.GetMock<IEpisodeService>().Setup(s => s.EpisodesBetweenDates(It.IsAny<DateTime>(), It.IsAny<DateTime>(), false))
.Returns(new List<Episode>());
}
[Test]
public void should_return_true_if_is_not_a_full_season()
{
_remoteEpisode.ParsedEpisodeInfo.FullSeason = false;
_remoteEpisode.Episodes.Last().AirDateUtc = DateTime.UtcNow.AddDays(+2);
Mocker.Resolve<FullSeasonSpecification>().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_true_if_all_episodes_have_aired()
{
Mocker.Resolve<FullSeasonSpecification>().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_false_if_one_episode_has_not_aired()
{
_remoteEpisode.Episodes.Last().AirDateUtc = DateTime.UtcNow.AddDays(+2);
Mocker.Resolve<FullSeasonSpecification>().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
}
[Test]
public void should_return_false_if_an_episode_does_not_have_an_air_date()
{
_remoteEpisode.Episodes.Last().AirDateUtc = null;
Mocker.Resolve<FullSeasonSpecification>().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
}
}
}

@ -45,25 +45,25 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
}; };
_fakeSeries = Builder<Series>.CreateNew() _fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = new Profile { Cutoff = Quality.MP3512, Items = Qualities.QualityFixture.GetDefaultQualities() }) .With(c => c.Profile = new Profile { Cutoff = Quality.MP3_512, Items = Qualities.QualityFixture.GetDefaultQualities() })
.Build(); .Build();
_parseResultMulti = new RemoteEpisode _parseResultMulti = new RemoteEpisode
{ {
Series = _fakeSeries, Series = _fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = doubleEpisodeList Episodes = doubleEpisodeList
}; };
_parseResultSingle = new RemoteEpisode _parseResultSingle = new RemoteEpisode
{ {
Series = _fakeSeries, Series = _fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = singleEpisodeList Episodes = singleEpisodeList
}; };
_upgradableQuality = new QualityModel(Quality.MP3192, new Revision(version: 1)); _upgradableQuality = new QualityModel(Quality.MP3_192, new Revision(version: 1));
_notupgradableQuality = new QualityModel(Quality.MP3512, new Revision(version: 2)); _notupgradableQuality = new QualityModel(Quality.MP3_512, new Revision(version: 2));
Mocker.GetMock<IConfigService>() Mocker.GetMock<IConfigService>()
.SetupGet(s => s.EnableCompletedDownloadHandling) .SetupGet(s => s.EnableCompletedDownloadHandling)
@ -159,9 +159,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_not_be_upgradable_if_episode_is_of_same_quality_as_existing() public void should_not_be_upgradable_if_episode_is_of_same_quality_as_existing()
{ {
_fakeSeries.Profile = new Profile { Cutoff = Quality.MP3512, Items = Qualities.QualityFixture.GetDefaultQualities() }; _fakeSeries.Profile = new Profile { Cutoff = Quality.MP3_512, Items = Qualities.QualityFixture.GetDefaultQualities() };
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3512, new Revision(version: 1)); _parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
_upgradableQuality = new QualityModel(Quality.MP3512, new Revision(version: 1)); _upgradableQuality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed); GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed);
@ -171,9 +171,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_not_be_upgradable_if_cutoff_already_met() public void should_not_be_upgradable_if_cutoff_already_met()
{ {
_fakeSeries.Profile = new Profile { Cutoff = Quality.MP3512, Items = Qualities.QualityFixture.GetDefaultQualities() }; _fakeSeries.Profile = new Profile { Cutoff = Quality.MP3_512, Items = Qualities.QualityFixture.GetDefaultQualities() };
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3512, new Revision(version: 1)); _parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
_upgradableQuality = new QualityModel(Quality.MP3512, new Revision(version: 1)); _upgradableQuality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed); GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed);
@ -199,9 +199,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
public void should_return_false_if_cutoff_already_met_and_cdh_is_disabled() public void should_return_false_if_cutoff_already_met_and_cdh_is_disabled()
{ {
GivenCdhDisabled(); GivenCdhDisabled();
_fakeSeries.Profile = new Profile { Cutoff = Quality.MP3512, Items = Qualities.QualityFixture.GetDefaultQualities() }; _fakeSeries.Profile = new Profile { Cutoff = Quality.MP3_512, Items = Qualities.QualityFixture.GetDefaultQualities() };
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3512, new Revision(version: 1)); _parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
_upgradableQuality = new QualityModel(Quality.MP3512, new Revision(version: 1)); _upgradableQuality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
GivenMostRecentForEpisode(FIRST_EPISODE_ID, "test", _upgradableQuality, DateTime.UtcNow.AddDays(-100), HistoryEventType.Grabbed); GivenMostRecentForEpisode(FIRST_EPISODE_ID, "test", _upgradableQuality, DateTime.UtcNow.AddDays(-100), HistoryEventType.Grabbed);

@ -68,8 +68,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_put_propers_before_non_propers() public void should_put_propers_before_non_propers()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256, new Revision(version: 1))); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256, new Revision(version: 1)));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256, new Revision(version: 2))); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256, new Revision(version: 2)));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode1));
@ -82,22 +82,22 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_put_higher_quality_before_lower() public void should_put_higher_quality_before_lower()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3192)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_192));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2)); decisions.Add(new DownloadDecision(remoteEpisode2));
var qualifiedReports = Subject.PrioritizeDecisions(decisions); var qualifiedReports = Subject.PrioritizeDecisions(decisions);
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Quality.Should().Be(Quality.MP3256); qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Quality.Should().Be(Quality.MP3_256);
} }
[Test] [Test]
public void should_order_by_lowest_number_of_episodes() public void should_order_by_lowest_number_of_episodes()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(2) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(2) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode1));
@ -110,8 +110,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_order_by_lowest_number_of_episodes_with_multiple_episodes() public void should_order_by_lowest_number_of_episodes_with_multiple_episodes()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(2), GivenEpisode(3) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(2), GivenEpisode(3) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.MP3_256));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode1));
@ -124,10 +124,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_order_by_age_then_largest_rounded_to_200mb() public void should_order_by_age_then_largest_rounded_to_200mb()
{ {
var remoteEpisodeSd = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3192), size: 100.Megabytes(), age: 1); var remoteEpisodeSd = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_192), size: 100.Megabytes(), age: 1);
var remoteEpisodeHdSmallOld = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), size: 1200.Megabytes(), age: 1000); var remoteEpisodeHdSmallOld = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), size: 1200.Megabytes(), age: 1000);
var remoteEpisodeSmallYoung = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), size: 1250.Megabytes(), age: 10); var remoteEpisodeSmallYoung = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), size: 1250.Megabytes(), age: 10);
var remoteEpisodeHdLargeYoung = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), size: 3000.Megabytes(), age: 1); var remoteEpisodeHdLargeYoung = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), size: 3000.Megabytes(), age: 1);
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisodeSd)); decisions.Add(new DownloadDecision(remoteEpisodeSd));
@ -142,8 +142,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_order_by_youngest() public void should_order_by_youngest()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), age: 10); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), age: 10);
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), age: 5); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), age: 5);
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
@ -157,8 +157,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_not_throw_if_no_episodes_are_found() public void should_not_throw_if_no_episodes_are_found()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), size: 500.Megabytes()); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), size: 500.Megabytes());
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), size: 500.Megabytes()); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), size: 500.Megabytes());
remoteEpisode1.Episodes = new List<Episode>(); remoteEpisode1.Episodes = new List<Episode>();
@ -174,8 +174,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
GivenPreferredDownloadProtocol(DownloadProtocol.Usenet); GivenPreferredDownloadProtocol(DownloadProtocol.Usenet);
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), downloadProtocol: DownloadProtocol.Torrent); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), downloadProtocol: DownloadProtocol.Torrent);
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), downloadProtocol: DownloadProtocol.Usenet); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), downloadProtocol: DownloadProtocol.Usenet);
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode1));
@ -190,8 +190,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
GivenPreferredDownloadProtocol(DownloadProtocol.Torrent); GivenPreferredDownloadProtocol(DownloadProtocol.Torrent);
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), downloadProtocol: DownloadProtocol.Torrent); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), downloadProtocol: DownloadProtocol.Torrent);
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256), downloadProtocol: DownloadProtocol.Usenet); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256), downloadProtocol: DownloadProtocol.Usenet);
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode1));
@ -204,8 +204,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_season_pack_above_single_episode() public void should_prefer_season_pack_above_single_episode()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
remoteEpisode1.ParsedEpisodeInfo.FullSeason = true; remoteEpisode1.ParsedEpisodeInfo.FullSeason = true;
@ -220,8 +220,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_multiepisode_over_single_episode_for_anime() public void should_prefer_multiepisode_over_single_episode_for_anime()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
remoteEpisode1.Series.SeriesType = SeriesTypes.Anime; remoteEpisode1.Series.SeriesType = SeriesTypes.Anime;
remoteEpisode2.Series.SeriesType = SeriesTypes.Anime; remoteEpisode2.Series.SeriesType = SeriesTypes.Anime;
@ -237,8 +237,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_single_episode_over_multi_episode_for_non_anime() public void should_prefer_single_episode_over_multi_episode_for_non_anime()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode1));
@ -251,8 +251,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_releases_with_more_seeders() public void should_prefer_releases_with_more_seeders()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var torrentInfo1 = new TorrentInfo(); var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.PublishDate = DateTime.Now;
@ -277,8 +277,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_releases_with_more_peers_given_equal_number_of_seeds() public void should_prefer_releases_with_more_peers_given_equal_number_of_seeds()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var torrentInfo1 = new TorrentInfo(); var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.PublishDate = DateTime.Now;
@ -305,8 +305,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_releases_with_more_peers_no_seeds() public void should_prefer_releases_with_more_peers_no_seeds()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var torrentInfo1 = new TorrentInfo(); var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.PublishDate = DateTime.Now;
@ -334,8 +334,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_first_release_if_peers_and_size_are_too_similar() public void should_prefer_first_release_if_peers_and_size_are_too_similar()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var torrentInfo1 = new TorrentInfo(); var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.PublishDate = DateTime.Now;
@ -363,8 +363,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_first_release_if_age_and_size_are_too_similar() public void should_prefer_first_release_if_age_and_size_are_too_similar()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3256)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_256));
remoteEpisode1.Release.PublishDate = DateTime.UtcNow.AddDays(-100); remoteEpisode1.Release.PublishDate = DateTime.UtcNow.AddDays(-100);
remoteEpisode1.Release.Size = 200.Megabytes(); remoteEpisode1.Release.Size = 200.Megabytes();
@ -383,8 +383,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_prefer_quality_over_the_number_of_peers() public void should_prefer_quality_over_the_number_of_peers()
{ {
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3512)); var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_512));
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3192)); var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.MP3_192));
var torrentInfo1 = new TorrentInfo(); var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.PublishDate = DateTime.Now;

@ -19,29 +19,29 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
public static object[] AllowedTestCases = public static object[] AllowedTestCases =
{ {
new object[] { Quality.MP3192 }, new object[] { Quality.MP3_192 },
new object[] { Quality.MP3256 }, new object[] { Quality.MP3_256 },
new object[] { Quality.MP3512 } new object[] { Quality.MP3_512 }
}; };
public static object[] DeniedTestCases = public static object[] DeniedTestCases =
{ {
new object[] { Quality.MP3192 }, new object[] { Quality.MP3_192 },
new object[] { Quality.MP3320 }, new object[] { Quality.MP3_320 },
new object[] { Quality.MP3320 } new object[] { Quality.MP3_320 }
}; };
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
var fakeSeries = Builder<Series>.CreateNew() var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = (LazyLoaded<Profile>)new Profile { Cutoff = Quality.MP3512 }) .With(c => c.Profile = (LazyLoaded<Profile>)new Profile { Cutoff = Quality.MP3_512 })
.Build(); .Build();
remoteEpisode = new RemoteEpisode remoteEpisode = new RemoteEpisode
{ {
Series = fakeSeries, Series = fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
}; };
} }
@ -49,7 +49,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
public void should_allow_if_quality_is_defined_in_profile(Quality qualityType) public void should_allow_if_quality_is_defined_in_profile(Quality qualityType)
{ {
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType; remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
remoteEpisode.Series.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3192, Quality.MP3256, Quality.MP3512); remoteEpisode.Series.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_192, Quality.MP3_256, Quality.MP3_512);
Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeTrue(); Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeTrue();
} }
@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
public void should_not_allow_if_quality_is_not_defined_in_profile(Quality qualityType) public void should_not_allow_if_quality_is_not_defined_in_profile(Quality qualityType)
{ {
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType; remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
remoteEpisode.Series.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3192, Quality.MP3256, Quality.MP3512); remoteEpisode.Series.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_192, Quality.MP3_256, Quality.MP3_512);
Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeFalse(); Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeFalse();
} }

@ -14,13 +14,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
public static object[] IsUpgradeTestCases = public static object[] IsUpgradeTestCases =
{ {
new object[] { Quality.MP3192, 1, Quality.MP3192, 2, Quality.MP3192, true }, new object[] { Quality.MP3_192, 1, Quality.MP3_192, 2, Quality.MP3_192, true },
new object[] { Quality.MP3320, 1, Quality.MP3320, 2, Quality.MP3320, true }, new object[] { Quality.MP3_320, 1, Quality.MP3_320, 2, Quality.MP3_320, true },
new object[] { Quality.MP3192, 1, Quality.MP3192, 1, Quality.MP3192, false }, new object[] { Quality.MP3_192, 1, Quality.MP3_192, 1, Quality.MP3_192, false },
new object[] { Quality.MP3320, 1, Quality.MP3256, 2, Quality.MP3320, false }, new object[] { Quality.MP3_320, 1, Quality.MP3_256, 2, Quality.MP3_320, false },
new object[] { Quality.MP3320, 1, Quality.MP3256, 2, Quality.MP3320, false }, new object[] { Quality.MP3_320, 1, Quality.MP3_256, 2, Quality.MP3_320, false },
new object[] { Quality.MP3320, 1, Quality.MP3320, 1, Quality.MP3320, false }, new object[] { Quality.MP3_320, 1, Quality.MP3_320, 1, Quality.MP3_320, false },
new object[] { Quality.MP3512, 1, Quality.MP3512, 1, Quality.MP3512, false } new object[] { Quality.MP3_512, 1, Quality.MP3_512, 1, Quality.MP3_512, false }
}; };
[SetUp] [SetUp]
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
var profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() }; var profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() };
Subject.IsUpgradable(profile, new QualityModel(Quality.MP3192, new Revision(version: 2)), new QualityModel(Quality.MP3192, new Revision(version: 1))) Subject.IsUpgradable(profile, new QualityModel(Quality.MP3_192, new Revision(version: 2)), new QualityModel(Quality.MP3_192, new Revision(version: 1)))
.Should().BeFalse(); .Should().BeFalse();
} }
} }

@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_remoteEpisode = Builder<RemoteEpisode>.CreateNew() _remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series) .With(r => r.Series = _series)
.With(r => r.Episodes = new List<Episode> { _episode }) .With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192) }) .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192) })
.Build(); .Build();
} }
@ -96,14 +96,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_return_true_when_quality_in_queue_is_lower() public void should_return_true_when_quality_in_queue_is_lower()
{ {
_series.Profile.Value.Cutoff = Quality.MP3512; _series.Profile.Value.Cutoff = Quality.MP3_512;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew() var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series) .With(r => r.Series = _series)
.With(r => r.Episodes = new List<Episode> { _episode }) .With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3192) Quality = new QualityModel(Quality.MP3_192)
}) })
.Build(); .Build();
@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
.With(r => r.Episodes = new List<Episode> { _otherEpisode }) .With(r => r.Episodes = new List<Episode> { _otherEpisode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3192) Quality = new QualityModel(Quality.MP3_192)
}) })
.Build(); .Build();
@ -135,7 +135,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
.With(r => r.Episodes = new List<Episode> { _episode }) .With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3192) Quality = new QualityModel(Quality.MP3_192)
}) })
.Build(); .Build();
@ -146,14 +146,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_return_false_when_quality_in_queue_is_better() public void should_return_false_when_quality_in_queue_is_better()
{ {
_series.Profile.Value.Cutoff = Quality.MP3512; _series.Profile.Value.Cutoff = Quality.MP3_512;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew() var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series) .With(r => r.Series = _series)
.With(r => r.Episodes = new List<Episode> { _episode }) .With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3256) Quality = new QualityModel(Quality.MP3_256)
}) })
.Build(); .Build();
@ -169,7 +169,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
.With(r => r.Episodes = new List<Episode> { _episode, _otherEpisode }) .With(r => r.Episodes = new List<Episode> { _episode, _otherEpisode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3256) Quality = new QualityModel(Quality.MP3_256)
}) })
.Build(); .Build();
@ -185,7 +185,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
.With(r => r.Episodes = new List<Episode> { _episode }) .With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3256) Quality = new QualityModel(Quality.MP3_256)
}) })
.Build(); .Build();
@ -203,7 +203,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
.With(r => r.Episodes = new List<Episode> { _episode, _otherEpisode }) .With(r => r.Episodes = new List<Episode> { _episode, _otherEpisode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3256) Quality = new QualityModel(Quality.MP3_256)
}) })
.Build(); .Build();
@ -223,7 +223,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
Quality = Quality =
new QualityModel( new QualityModel(
Quality.MP3256) Quality.MP3_256)
}) })
.TheFirst(1) .TheFirst(1)
.With(r => r.Episodes = new List<Episode> { _episode }) .With(r => r.Episodes = new List<Episode> { _episode })
@ -246,7 +246,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
.With(r => r.Episodes = new List<Episode> { _episode }) .With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{ {
Quality = new QualityModel(Quality.MP3256) Quality = new QualityModel(Quality.MP3_256)
}) })
.Build(); .Build();

@ -47,11 +47,11 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
.Build(); .Build();
_profile.Items = new List<ProfileQualityItem>(); _profile.Items = new List<ProfileQualityItem>();
_profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.MP3256 }); _profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_256 });
_profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.MP3320 }); _profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_320 });
_profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.MP3320 }); _profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_320 });
_profile.Cutoff = Quality.MP3320; _profile.Cutoff = Quality.MP3_320;
_remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo(); _remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
_remoteEpisode.Release = new ReleaseInfo(); _remoteEpisode.Release = new ReleaseInfo();
@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_be_false_when_system_invoked_search_and_release_is_younger_than_delay() public void should_be_false_when_system_invoked_search_and_release_is_younger_than_delay()
{ {
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3192); _remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_192);
_remoteEpisode.Release.PublishDate = DateTime.UtcNow; _remoteEpisode.Release.PublishDate = DateTime.UtcNow;
_delayProfile.UsenetDelay = 720; _delayProfile.UsenetDelay = 720;
@ -114,7 +114,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_be_true_when_quality_is_last_allowed_in_profile() public void should_be_true_when_quality_is_last_allowed_in_profile()
{ {
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3320); _remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_320);
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
} }
@ -122,7 +122,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_be_true_when_release_is_older_than_delay() public void should_be_true_when_release_is_older_than_delay()
{ {
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3256); _remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_256);
_remoteEpisode.Release.PublishDate = DateTime.UtcNow.AddHours(-10); _remoteEpisode.Release.PublishDate = DateTime.UtcNow.AddHours(-10);
_delayProfile.UsenetDelay = 60; _delayProfile.UsenetDelay = 60;
@ -133,7 +133,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_be_false_when_release_is_younger_than_delay() public void should_be_false_when_release_is_younger_than_delay()
{ {
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3192); _remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_192);
_remoteEpisode.Release.PublishDate = DateTime.UtcNow; _remoteEpisode.Release.PublishDate = DateTime.UtcNow;
_delayProfile.UsenetDelay = 720; _delayProfile.UsenetDelay = 720;
@ -144,10 +144,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_be_true_when_release_is_a_proper_for_existing_episode() public void should_be_true_when_release_is_a_proper_for_existing_episode()
{ {
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3256, new Revision(version: 2)); _remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_256, new Revision(version: 2));
_remoteEpisode.Release.PublishDate = DateTime.UtcNow; _remoteEpisode.Release.PublishDate = DateTime.UtcNow;
GivenExistingFile(new QualityModel(Quality.MP3256)); GivenExistingFile(new QualityModel(Quality.MP3_256));
GivenUpgradeForExistingFile(); GivenUpgradeForExistingFile();
Mocker.GetMock<IQualityUpgradableSpecification>() Mocker.GetMock<IQualityUpgradableSpecification>()
@ -162,10 +162,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_be_true_when_release_is_a_real_for_existing_episode() public void should_be_true_when_release_is_a_real_for_existing_episode()
{ {
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3256, new Revision(real: 1)); _remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_256, new Revision(real: 1));
_remoteEpisode.Release.PublishDate = DateTime.UtcNow; _remoteEpisode.Release.PublishDate = DateTime.UtcNow;
GivenExistingFile(new QualityModel(Quality.MP3256)); GivenExistingFile(new QualityModel(Quality.MP3_256));
GivenUpgradeForExistingFile(); GivenUpgradeForExistingFile();
Mocker.GetMock<IQualityUpgradableSpecification>() Mocker.GetMock<IQualityUpgradableSpecification>()
@ -180,10 +180,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_be_false_when_release_is_proper_for_existing_episode_of_different_quality() public void should_be_false_when_release_is_proper_for_existing_episode_of_different_quality()
{ {
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3256, new Revision(version: 2)); _remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_256, new Revision(version: 2));
_remoteEpisode.Release.PublishDate = DateTime.UtcNow; _remoteEpisode.Release.PublishDate = DateTime.UtcNow;
GivenExistingFile(new QualityModel(Quality.MP3192)); GivenExistingFile(new QualityModel(Quality.MP3_192));
_delayProfile.UsenetDelay = 720; _delayProfile.UsenetDelay = 720;

@ -31,34 +31,34 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
{ {
Mocker.Resolve<QualityUpgradableSpecification>(); Mocker.Resolve<QualityUpgradableSpecification>();
_firstFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3512, new Revision(version: 1)), DateAdded = DateTime.Now }; _firstFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3_512, new Revision(version: 1)), DateAdded = DateTime.Now };
_secondFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3512, new Revision(version: 1)), DateAdded = DateTime.Now }; _secondFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3_512, new Revision(version: 1)), DateAdded = DateTime.Now };
var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } }; var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } }; var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
var fakeSeries = Builder<Series>.CreateNew() var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = new Profile { Cutoff = Quality.MP3512 }) .With(c => c.Profile = new Profile { Cutoff = Quality.MP3_512 })
.Build(); .Build();
_parseResultMulti = new RemoteEpisode _parseResultMulti = new RemoteEpisode
{ {
Series = fakeSeries, Series = fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = doubleEpisodeList Episodes = doubleEpisodeList
}; };
_parseResultSingle = new RemoteEpisode _parseResultSingle = new RemoteEpisode
{ {
Series = fakeSeries, Series = fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = singleEpisodeList Episodes = singleEpisodeList
}; };
} }
private void WithFirstFileUpgradable() private void WithFirstFileUpgradable()
{ {
_firstFile.Quality = new QualityModel(Quality.MP3192); _firstFile.Quality = new QualityModel(Quality.MP3_192);
} }
private void GivenAutoDownloadPropers() private void GivenAutoDownloadPropers()
@ -71,7 +71,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_return_false_when_episodeFile_was_added_more_than_7_days_ago() public void should_return_false_when_episodeFile_was_added_more_than_7_days_ago()
{ {
_firstFile.Quality.Quality = Quality.MP3192; _firstFile.Quality.Quality = Quality.MP3_192;
_firstFile.DateAdded = DateTime.Today.AddDays(-30); _firstFile.DateAdded = DateTime.Today.AddDays(-30);
Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse();
@ -80,8 +80,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_return_false_when_first_episodeFile_was_added_more_than_7_days_ago() public void should_return_false_when_first_episodeFile_was_added_more_than_7_days_ago()
{ {
_firstFile.Quality.Quality = Quality.MP3192; _firstFile.Quality.Quality = Quality.MP3_192;
_secondFile.Quality.Quality = Quality.MP3192; _secondFile.Quality.Quality = Quality.MP3_192;
_firstFile.DateAdded = DateTime.Today.AddDays(-30); _firstFile.DateAdded = DateTime.Today.AddDays(-30);
Subject.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); Subject.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse();
@ -90,8 +90,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_return_false_when_second_episodeFile_was_added_more_than_7_days_ago() public void should_return_false_when_second_episodeFile_was_added_more_than_7_days_ago()
{ {
_firstFile.Quality.Quality = Quality.MP3192; _firstFile.Quality.Quality = Quality.MP3_192;
_secondFile.Quality.Quality = Quality.MP3192; _secondFile.Quality.Quality = Quality.MP3_192;
_secondFile.DateAdded = DateTime.Today.AddDays(-30); _secondFile.DateAdded = DateTime.Today.AddDays(-30);
Subject.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); Subject.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse();
@ -118,7 +118,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[Test] [Test]
public void should_return_false_when_proper_but_auto_download_propers_is_false() public void should_return_false_when_proper_but_auto_download_propers_is_false()
{ {
_firstFile.Quality.Quality = Quality.MP3192; _firstFile.Quality.Quality = Quality.MP3_192;
_firstFile.DateAdded = DateTime.Today; _firstFile.DateAdded = DateTime.Today;
Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse();
@ -129,7 +129,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
{ {
GivenAutoDownloadPropers(); GivenAutoDownloadPropers();
_firstFile.Quality.Quality = Quality.MP3192; _firstFile.Quality.Quality = Quality.MP3_192;
_firstFile.DateAdded = DateTime.Today; _firstFile.DateAdded = DateTime.Today;
Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue();

@ -32,39 +32,39 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Mocker.Resolve<QualityUpgradableSpecification>(); Mocker.Resolve<QualityUpgradableSpecification>();
_upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>(); _upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>();
_firstFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3512, new Revision(version: 2)), DateAdded = DateTime.Now }; _firstFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3_512, new Revision(version: 2)), DateAdded = DateTime.Now };
_secondFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3512, new Revision(version: 2)), DateAdded = DateTime.Now }; _secondFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3_512, new Revision(version: 2)), DateAdded = DateTime.Now };
var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } }; var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } }; var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
var fakeSeries = Builder<Series>.CreateNew() var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = new Profile { Cutoff = Quality.MP3512, Items = Qualities.QualityFixture.GetDefaultQualities() }) .With(c => c.Profile = new Profile { Cutoff = Quality.MP3_512, Items = Qualities.QualityFixture.GetDefaultQualities() })
.Build(); .Build();
_parseResultMulti = new RemoteEpisode _parseResultMulti = new RemoteEpisode
{ {
Series = fakeSeries, Series = fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = doubleEpisodeList Episodes = doubleEpisodeList
}; };
_parseResultSingle = new RemoteEpisode _parseResultSingle = new RemoteEpisode
{ {
Series = fakeSeries, Series = fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3192, new Revision(version: 2)) }, ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) },
Episodes = singleEpisodeList Episodes = singleEpisodeList
}; };
} }
private void WithFirstFileUpgradable() private void WithFirstFileUpgradable()
{ {
_firstFile.Quality = new QualityModel(Quality.MP3192); _firstFile.Quality = new QualityModel(Quality.MP3_192);
} }
private void WithSecondFileUpgradable() private void WithSecondFileUpgradable()
{ {
_secondFile.Quality = new QualityModel(Quality.MP3192); _secondFile.Quality = new QualityModel(Quality.MP3_192);
} }
[Test] [Test]
@ -120,8 +120,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test] [Test]
public void should_not_be_upgradable_if_qualities_are_the_same() public void should_not_be_upgradable_if_qualities_are_the_same()
{ {
_firstFile.Quality = new QualityModel(Quality.MP3512); _firstFile.Quality = new QualityModel(Quality.MP3_512);
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3512); _parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_512);
_upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse();
} }
} }

@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
public void should_download_report_if_epsiode_was_not_already_downloaded() public void should_download_report_if_epsiode_was_not_already_downloaded()
{ {
var episodes = new List<Episode> { GetEpisode(1) }; var episodes = new List<Episode> { GetEpisode(1) };
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3192)); var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3_192));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode)); decisions.Add(new DownloadDecision(remoteEpisode));
@ -71,7 +71,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
public void should_only_download_episode_once() public void should_only_download_episode_once()
{ {
var episodes = new List<Episode> { GetEpisode(1) }; var episodes = new List<Episode> { GetEpisode(1) };
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3192)); var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3_192));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode)); decisions.Add(new DownloadDecision(remoteEpisode));
@ -86,12 +86,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
{ {
var remoteEpisode1 = GetRemoteEpisode( var remoteEpisode1 = GetRemoteEpisode(
new List<Episode> { GetEpisode(1) }, new List<Episode> { GetEpisode(1) },
new QualityModel(Quality.MP3192) new QualityModel(Quality.MP3_192)
); );
var remoteEpisode2 = GetRemoteEpisode( var remoteEpisode2 = GetRemoteEpisode(
new List<Episode> { GetEpisode(1), GetEpisode(2) }, new List<Episode> { GetEpisode(1), GetEpisode(2) },
new QualityModel(Quality.MP3192) new QualityModel(Quality.MP3_192)
); );
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
@ -106,7 +106,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
public void should_return_downloaded_reports() public void should_return_downloaded_reports()
{ {
var episodes = new List<Episode> { GetEpisode(1) }; var episodes = new List<Episode> { GetEpisode(1) };
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3192)); var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3_192));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode)); decisions.Add(new DownloadDecision(remoteEpisode));
@ -119,12 +119,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
{ {
var remoteEpisode1 = GetRemoteEpisode( var remoteEpisode1 = GetRemoteEpisode(
new List<Episode> { GetEpisode(1) }, new List<Episode> { GetEpisode(1) },
new QualityModel(Quality.MP3192) new QualityModel(Quality.MP3_192)
); );
var remoteEpisode2 = GetRemoteEpisode( var remoteEpisode2 = GetRemoteEpisode(
new List<Episode> { GetEpisode(2) }, new List<Episode> { GetEpisode(2) },
new QualityModel(Quality.MP3192) new QualityModel(Quality.MP3_192)
); );
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
@ -139,17 +139,17 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
{ {
var remoteEpisode1 = GetRemoteEpisode( var remoteEpisode1 = GetRemoteEpisode(
new List<Episode> { GetEpisode(1) }, new List<Episode> { GetEpisode(1) },
new QualityModel(Quality.MP3192) new QualityModel(Quality.MP3_192)
); );
var remoteEpisode2 = GetRemoteEpisode( var remoteEpisode2 = GetRemoteEpisode(
new List<Episode> { GetEpisode(2) }, new List<Episode> { GetEpisode(2) },
new QualityModel(Quality.MP3192) new QualityModel(Quality.MP3_192)
); );
var remoteEpisode3 = GetRemoteEpisode( var remoteEpisode3 = GetRemoteEpisode(
new List<Episode> { GetEpisode(2) }, new List<Episode> { GetEpisode(2) },
new QualityModel(Quality.MP3192) new QualityModel(Quality.MP3_192)
); );
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
@ -164,7 +164,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
public void should_not_add_to_downloaded_list_when_download_fails() public void should_not_add_to_downloaded_list_when_download_fails()
{ {
var episodes = new List<Episode> { GetEpisode(1) }; var episodes = new List<Episode> { GetEpisode(1) };
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3192)); var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3_192));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode)); decisions.Add(new DownloadDecision(remoteEpisode));
@ -188,7 +188,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
public void should_not_grab_if_pending() public void should_not_grab_if_pending()
{ {
var episodes = new List<Episode> { GetEpisode(1) }; var episodes = new List<Episode> { GetEpisode(1) };
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3192)); var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3_192));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary))); decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
@ -202,7 +202,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
public void should_not_add_to_pending_if_episode_was_grabbed() public void should_not_add_to_pending_if_episode_was_grabbed()
{ {
var episodes = new List<Episode> { GetEpisode(1) }; var episodes = new List<Episode> { GetEpisode(1) };
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3192)); var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3_192));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode)); decisions.Add(new DownloadDecision(remoteEpisode));
@ -216,7 +216,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
public void should_add_to_pending_even_if_already_added_to_pending() public void should_add_to_pending_even_if_already_added_to_pending()
{ {
var episodes = new List<Episode> { GetEpisode(1) }; var episodes = new List<Episode> { GetEpisode(1) };
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3192)); var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.MP3_192));
var decisions = new List<DownloadDecision>(); var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary))); decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));

@ -39,12 +39,12 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_profile = new Profile _profile = new Profile
{ {
Name = "Test", Name = "Test",
Cutoff = Quality.MP3256, Cutoff = Quality.MP3_256,
Items = new List<ProfileQualityItem> Items = new List<ProfileQualityItem>
{ {
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3256 }, new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_256 },
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3320 }, new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_320 },
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3320 } new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_320 }
}, },
}; };
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_release = Builder<ReleaseInfo>.CreateNew().Build(); _release = Builder<ReleaseInfo>.CreateNew().Build();
_parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew().Build(); _parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew().Build();
_parsedEpisodeInfo.Quality = new QualityModel(Quality.MP3256); _parsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_256);
_remoteEpisode = new RemoteEpisode(); _remoteEpisode = new RemoteEpisode();
_remoteEpisode.Episodes = new List<Episode>{ _episode }; _remoteEpisode.Episodes = new List<Episode>{ _episode };

@ -39,12 +39,12 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_profile = new Profile _profile = new Profile
{ {
Name = "Test", Name = "Test",
Cutoff = Quality.MP3256, Cutoff = Quality.MP3_256,
Items = new List<ProfileQualityItem> Items = new List<ProfileQualityItem>
{ {
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3256 }, new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_256 },
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3320 }, new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_320 },
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3512 } new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_512 }
}, },
}; };
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_release = Builder<ReleaseInfo>.CreateNew().Build(); _release = Builder<ReleaseInfo>.CreateNew().Build();
_parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew().Build(); _parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew().Build();
_parsedEpisodeInfo.Quality = new QualityModel(Quality.MP3256); _parsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_256);
_remoteEpisode = new RemoteEpisode(); _remoteEpisode = new RemoteEpisode();
_remoteEpisode.Episodes = new List<Episode>{ _episode }; _remoteEpisode.Episodes = new List<Episode>{ _episode };
@ -110,7 +110,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
[Test] [Test]
public void should_delete_if_the_grabbed_quality_is_the_higher() public void should_delete_if_the_grabbed_quality_is_the_higher()
{ {
GivenHeldRelease(new QualityModel(Quality.MP3192)); GivenHeldRelease(new QualityModel(Quality.MP3_192));
Subject.Handle(new EpisodeGrabbedEvent(_remoteEpisode)); Subject.Handle(new EpisodeGrabbedEvent(_remoteEpisode));
@ -120,7 +120,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
[Test] [Test]
public void should_not_delete_if_the_grabbed_quality_is_the_lower() public void should_not_delete_if_the_grabbed_quality_is_the_lower()
{ {
GivenHeldRelease(new QualityModel(Quality.MP3512)); GivenHeldRelease(new QualityModel(Quality.MP3_512));
Subject.Handle(new EpisodeGrabbedEvent(_remoteEpisode)); Subject.Handle(new EpisodeGrabbedEvent(_remoteEpisode));

@ -41,12 +41,12 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_profile = new Profile _profile = new Profile
{ {
Name = "Test", Name = "Test",
Cutoff = Quality.MP3192, Cutoff = Quality.MP3_192,
Items = new List<ProfileQualityItem> Items = new List<ProfileQualityItem>
{ {
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3192 }, new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_192 },
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3256 }, new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_256 },
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3320 } new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_320 }
}, },
}; };
@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_release = Builder<ReleaseInfo>.CreateNew().Build(); _release = Builder<ReleaseInfo>.CreateNew().Build();
_parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew().Build(); _parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew().Build();
_parsedEpisodeInfo.Quality = new QualityModel(Quality.MP3192); _parsedEpisodeInfo.Quality = new QualityModel(Quality.MP3_192);
_remoteEpisode = new RemoteEpisode(); _remoteEpisode = new RemoteEpisode();
_remoteEpisode.Episodes = new List<Episode>{ _episode }; _remoteEpisode.Episodes = new List<Episode>{ _episode };

@ -289,7 +289,7 @@
&lt;br /&gt; &lt;br /&gt;
Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.&lt;br /&gt; Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.&lt;br /&gt;
&lt;br /&gt; &lt;br /&gt;
All together, this unit of comedians make the shows half-hour episodes pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!&lt;br /&gt; All together, this unit of comedians make the shows half-hour tracks pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!&lt;br /&gt;
&lt;br /&gt; &lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;span id=&quot;lazyload&quot;&gt;&lt;span id=&quot;1776335379_620778c1a5d72709be3fc47a2262cdb9&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;a href=&quot;https://immortalseed.me/images/modpics/41872.jpg&quot; id=&quot;ts_show_preview&quot; alt=&quot;&quot;&gt;&lt;img src=&quot;https://immortalseed.me/images/modpics/41872.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; onload=&quot;TSResizeImage(this, '1776335379_620778c1a5d72709be3fc47a2262cdb9');&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style=&quot;text-align: center;&quot;&gt;&lt;span id=&quot;lazyload&quot;&gt;&lt;span id=&quot;1776335379_620778c1a5d72709be3fc47a2262cdb9&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;a href=&quot;https://immortalseed.me/images/modpics/41872.jpg&quot; id=&quot;ts_show_preview&quot; alt=&quot;&quot;&gt;&lt;img src=&quot;https://immortalseed.me/images/modpics/41872.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; onload=&quot;TSResizeImage(this, '1776335379_620778c1a5d72709be3fc47a2262cdb9');&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
</description> </description>
@ -375,7 +375,7 @@
&lt;br /&gt; &lt;br /&gt;
Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.&lt;br /&gt; Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.&lt;br /&gt;
&lt;br /&gt; &lt;br /&gt;
All together, this unit of comedians make the shows half-hour episodes pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!&lt;br /&gt; All together, this unit of comedians make the shows half-hour tracks pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!&lt;br /&gt;
&lt;br /&gt; &lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;span id=&quot;lazyload&quot;&gt;&lt;span id=&quot;1099410497_49fffcedd2eef0506d6b92e66fc4f3d4&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;a href=&quot;https://immortalseed.me/images/modpics/57412.jpg&quot; id=&quot;ts_show_preview&quot; alt=&quot;&quot;&gt;&lt;img src=&quot;https://immortalseed.me/images/modpics/57412.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; onload=&quot;TSResizeImage(this, '1099410497_49fffcedd2eef0506d6b92e66fc4f3d4');&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style=&quot;text-align: center;&quot;&gt;&lt;span id=&quot;lazyload&quot;&gt;&lt;span id=&quot;1099410497_49fffcedd2eef0506d6b92e66fc4f3d4&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;a href=&quot;https://immortalseed.me/images/modpics/57412.jpg&quot; id=&quot;ts_show_preview&quot; alt=&quot;&quot;&gt;&lt;img src=&quot;https://immortalseed.me/images/modpics/57412.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; onload=&quot;TSResizeImage(this, '1099410497_49fffcedd2eef0506d6b92e66fc4f3d4');&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
</description> </description>
@ -473,7 +473,7 @@
&lt;br /&gt; &lt;br /&gt;
Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.&lt;br /&gt; Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.&lt;br /&gt;
&lt;br /&gt; &lt;br /&gt;
All together, this unit of comedians make the shows half-hour episodes pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!&lt;br /&gt; All together, this unit of comedians make the shows half-hour tracks pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!&lt;br /&gt;
&lt;br /&gt; &lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;span id=&quot;lazyload&quot;&gt;&lt;span id=&quot;1183173375_229d6c19d62f235698f60e876f0f5ab4&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;a href=&quot;https://immortalseed.me/images/modpics/55069.jpg&quot; id=&quot;ts_show_preview&quot; alt=&quot;&quot;&gt;&lt;img src=&quot;https://immortalseed.me/images/modpics/55069.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; onload=&quot;TSResizeImage(this, '1183173375_229d6c19d62f235698f60e876f0f5ab4');&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style=&quot;text-align: center;&quot;&gt;&lt;span id=&quot;lazyload&quot;&gt;&lt;span id=&quot;1183173375_229d6c19d62f235698f60e876f0f5ab4&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;a href=&quot;https://immortalseed.me/images/modpics/55069.jpg&quot; id=&quot;ts_show_preview&quot; alt=&quot;&quot;&gt;&lt;img src=&quot;https://immortalseed.me/images/modpics/55069.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; onload=&quot;TSResizeImage(this, '1183173375_229d6c19d62f235698f60e876f0f5ab4');&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
</description> </description>

@ -31,13 +31,13 @@ namespace NzbDrone.Core.Test.HistoryTests
public void should_get_download_history() public void should_get_download_history()
{ {
var historyBluray = Builder<History.History>.CreateNew() var historyBluray = Builder<History.History>.CreateNew()
.With(c => c.Quality = new QualityModel(Quality.MP3320)) .With(c => c.Quality = new QualityModel(Quality.MP3_320))
.With(c => c.SeriesId = 12) .With(c => c.SeriesId = 12)
.With(c => c.EventType = HistoryEventType.Grabbed) .With(c => c.EventType = HistoryEventType.Grabbed)
.BuildNew(); .BuildNew();
var historyDvd = Builder<History.History>.CreateNew() var historyDvd = Builder<History.History>.CreateNew()
.With(c => c.Quality = new QualityModel(Quality.MP3192)) .With(c => c.Quality = new QualityModel(Quality.MP3_192))
.With(c => c.SeriesId = 12) .With(c => c.SeriesId = 12)
.With(c => c.EventType = HistoryEventType.Grabbed) .With(c => c.EventType = HistoryEventType.Grabbed)
.BuildNew(); .BuildNew();
@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.HistoryTests
Subject.Insert(historyBluray); Subject.Insert(historyBluray);
Subject.Insert(historyDvd); Subject.Insert(historyDvd);
var downloadHistory = Subject.FindDownloadHistory(12, new QualityModel(Quality.MP3320)); var downloadHistory = Subject.FindDownloadHistory(12, new QualityModel(Quality.MP3_320));
downloadHistory.Should().HaveCount(1); downloadHistory.Should().HaveCount(1);
} }

@ -25,8 +25,8 @@ namespace NzbDrone.Core.Test.HistoryTests
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_profile = new Profile { Cutoff = Quality.MP3256, Items = QualityFixture.GetDefaultQualities() }; _profile = new Profile { Cutoff = Quality.MP3_256, Items = QualityFixture.GetDefaultQualities() };
_profileCustom = new Profile { Cutoff = Quality.MP3256, Items = QualityFixture.GetDefaultQualities(Quality.MP3192) }; _profileCustom = new Profile { Cutoff = Quality.MP3_256, Items = QualityFixture.GetDefaultQualities(Quality.MP3_192) };
} }
[Test] [Test]
@ -46,11 +46,11 @@ namespace NzbDrone.Core.Test.HistoryTests
{ {
Mocker.GetMock<IHistoryRepository>() Mocker.GetMock<IHistoryRepository>()
.Setup(v => v.GetBestQualityInHistory(2)) .Setup(v => v.GetBestQualityInHistory(2))
.Returns(new List<QualityModel> { new QualityModel(Quality.MP3192), new QualityModel(Quality.MP3256) }); .Returns(new List<QualityModel> { new QualityModel(Quality.MP3_192), new QualityModel(Quality.MP3_256) });
var quality = Subject.GetBestQualityInHistory(_profile, 2); var quality = Subject.GetBestQualityInHistory(_profile, 2);
quality.Should().Be(new QualityModel(Quality.MP3256)); quality.Should().Be(new QualityModel(Quality.MP3_256));
} }
[Test] [Test]
@ -58,11 +58,11 @@ namespace NzbDrone.Core.Test.HistoryTests
{ {
Mocker.GetMock<IHistoryRepository>() Mocker.GetMock<IHistoryRepository>()
.Setup(v => v.GetBestQualityInHistory(2)) .Setup(v => v.GetBestQualityInHistory(2))
.Returns(new List<QualityModel> { new QualityModel(Quality.MP3192), new QualityModel(Quality.MP3256) }); .Returns(new List<QualityModel> { new QualityModel(Quality.MP3_192), new QualityModel(Quality.MP3_256) });
var quality = Subject.GetBestQualityInHistory(_profileCustom, 2); var quality = Subject.GetBestQualityInHistory(_profileCustom, 2);
quality.Should().Be(new QualityModel(Quality.MP3192)); quality.Should().Be(new QualityModel(Quality.MP3_192));
} }
[Test] [Test]

@ -56,7 +56,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() }) .With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
.Build(); .Build();
_quality = new QualityModel(Quality.MP3256); _quality = new QualityModel(Quality.MP3_256);
_localTrack = new LocalTrack _localTrack = new LocalTrack
{ {
@ -184,7 +184,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
GivenSpecifications(_pass1, _pass2, _pass3); GivenSpecifications(_pass1, _pass2, _pass3);
var expectedQuality = QualityParser.ParseQuality(_audioFiles.Single()); var expectedQuality = QualityParser.ParseQuality(_audioFiles.Single());
var result = Subject.GetImportDecisions(_audioFiles, _artist, new ParsedTrackInfo{Quality = new QualityModel(Quality.MP3256) }); var result = Subject.GetImportDecisions(_audioFiles, _artist, new ParsedTrackInfo{Quality = new QualityModel(Quality.MP3_256) });
result.Single().LocalTrack.Quality.Should().Be(expectedQuality); result.Single().LocalTrack.Quality.Should().Be(expectedQuality);
} }
@ -197,9 +197,9 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
_localTrack.Path = _audioFiles.Single(); _localTrack.Path = _audioFiles.Single();
_localTrack.Quality.QualitySource = QualitySource.Extension; _localTrack.Quality.QualitySource = QualitySource.Extension;
_localTrack.Quality.Quality = Quality.MP3256; _localTrack.Quality.Quality = Quality.MP3_256;
var expectedQuality = new QualityModel(Quality.MP3256); var expectedQuality = new QualityModel(Quality.MP3_256);
var result = Subject.GetImportDecisions(_audioFiles, _artist, new ParsedTrackInfo { Quality = expectedQuality }); var result = Subject.GetImportDecisions(_audioFiles, _artist, new ParsedTrackInfo { Quality = expectedQuality });
@ -213,9 +213,9 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
GivenVideoFiles(new string[] { @"C:\Test\Unsorted\The.Office.S03E115.mkv".AsOsAgnostic() }); GivenVideoFiles(new string[] { @"C:\Test\Unsorted\The.Office.S03E115.mkv".AsOsAgnostic() });
_localTrack.Path = _audioFiles.Single(); _localTrack.Path = _audioFiles.Single();
_localTrack.Quality.Quality = Quality.MP3256; _localTrack.Quality.Quality = Quality.MP3_256;
var expectedQuality = new QualityModel(Quality.MP3256); var expectedQuality = new QualityModel(Quality.MP3_256);
var result = Subject.GetImportDecisions(_audioFiles, _artist, new ParsedTrackInfo { Quality = expectedQuality }); var result = Subject.GetImportDecisions(_audioFiles, _artist, new ParsedTrackInfo { Quality = expectedQuality });
@ -374,7 +374,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
_artist.Profile = new Profile _artist.Profile = new Profile
{ {
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3256, Quality.Unknown) Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_256, Quality.Unknown)
}; };

@ -38,7 +38,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi", Path = @"C:\Test\30 Rock\30.rock.s01e01.avi",
Episodes = episodes, Episodes = episodes,
Series = _series, Series = _series,
Quality = new QualityModel(Quality.MP3256) Quality = new QualityModel(Quality.MP3_256)
}; };
} }

@ -1,46 +0,0 @@
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
{
[TestFixture]
public class FullSeasonSpecificationFixture : CoreTest<FullSeasonSpecification>
{
private LocalEpisode _localEpisode;
[SetUp]
public void Setup()
{
_localEpisode = new LocalEpisode
{
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi".AsOsAgnostic(),
Size = 100,
Series = Builder<Series>.CreateNew().Build(),
ParsedEpisodeInfo = new ParsedEpisodeInfo
{
FullSeason = false
}
};
}
[Test]
public void should_return_false_when_file_contains_the_full_season()
{
_localEpisode.ParsedEpisodeInfo.FullSeason = true;
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeFalse();
}
[Test]
public void should_return_true_when_file_does_not_contain_the_full_season()
{
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeTrue();
}
}
}

@ -1,84 +0,0 @@
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
{
[TestFixture]
public class MatchesFolderSpecificationFixture : CoreTest<MatchesFolderSpecification>
{
private LocalEpisode _localEpisode;
[SetUp]
public void Setup()
{
_localEpisode = Builder<LocalEpisode>.CreateNew()
.With(l => l.Path = @"C:\Test\Unsorted\Series.Title.S01E01.720p.HDTV-Lidarr\S01E05.mkv".AsOsAgnostic())
.With(l => l.ParsedEpisodeInfo =
Builder<ParsedEpisodeInfo>.CreateNew()
.With(p => p.EpisodeNumbers = new[] {5})
.With(p => p.FullSeason = false)
.Build())
.Build();
}
[Test]
public void should_be_accepted_for_existing_file()
{
_localEpisode.ExistingFile = true;
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeTrue();
}
[Test]
public void should_be_accepted_if_folder_name_is_not_parseable()
{
_localEpisode.Path = @"C:\Test\Unsorted\Series.Title\S01E01.mkv".AsOsAgnostic();
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeTrue();
}
[Test]
public void should_should_be_accepted_for_full_season()
{
_localEpisode.Path = @"C:\Test\Unsorted\Series.Title.S01\S01E01.mkv".AsOsAgnostic();
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeTrue();
}
[Test]
public void should_be_accepted_if_file_and_folder_have_the_same_episode()
{
_localEpisode.ParsedEpisodeInfo.EpisodeNumbers = new[] { 1 };
_localEpisode.Path = @"C:\Test\Unsorted\Series.Title.S01E01.720p.HDTV-Lidarr\S01E01.mkv".AsOsAgnostic();
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeTrue();
}
[Test]
public void should_be_accepted_if_file_is_one_episode_in_folder()
{
_localEpisode.ParsedEpisodeInfo.EpisodeNumbers = new[] { 1 };
_localEpisode.Path = @"C:\Test\Unsorted\Series.Title.S01E01E02.720p.HDTV-Lidarr\S01E01.mkv".AsOsAgnostic();
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeTrue();
}
[Test]
public void should_be_rejected_if_file_and_folder_do_not_have_same_episode()
{
_localEpisode.Path = @"C:\Test\Unsorted\Series.Title.S01E01.720p.HDTV-Lidarr\S01E05.mkv".AsOsAgnostic();
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeFalse();
}
[Test]
public void should_be_rejected_if_file_and_folder_do_not_have_same_episodes()
{
_localEpisode.ParsedEpisodeInfo.EpisodeNumbers = new[] { 5, 6 };
_localEpisode.Path = @"C:\Test\Unsorted\Series.Title.S01E01E02.720p.HDTV-Lidarr\S01E05E06.mkv".AsOsAgnostic();
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeFalse();
}
}
}

@ -1,48 +0,0 @@
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
{
[TestFixture]
public class NotSampleSpecificationFixture : CoreTest<NotSampleSpecification>
{
private Series _series;
private LocalEpisode _localEpisode;
[SetUp]
public void Setup()
{
_series = Builder<Series>.CreateNew()
.With(s => s.SeriesType = SeriesTypes.Standard)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(1)
.All()
.With(e => e.SeasonNumber = 1)
.Build()
.ToList();
_localEpisode = new LocalEpisode
{
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi",
Episodes = episodes,
Series = _series,
Quality = new QualityModel(Quality.MP3256)
};
}
[Test]
public void should_return_true_for_existing_file()
{
_localEpisode.ExistingFile = true;
Subject.IsSatisfiedBy(_localEpisode).Accepted.Should().BeTrue();
}
}
}

@ -30,7 +30,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
_localEpisode = new LocalEpisode _localEpisode = new LocalEpisode
{ {
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi", Path = @"C:\Test\30 Rock\30.rock.s01e01.avi",
Quality = new QualityModel(Quality.MP3256, new Revision(version: 1)), Quality = new QualityModel(Quality.MP3_256, new Revision(version: 1)),
Series = _series Series = _series
}; };
} }
@ -70,7 +70,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>( .With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(version: 1)) Quality = new QualityModel(Quality.MP3_256, new Revision(version: 1))
})) }))
.Build() .Build()
.ToList(); .ToList();
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>( .With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(version: 1)) Quality = new QualityModel(Quality.MP3_256, new Revision(version: 1))
})) }))
.Build() .Build()
.ToList(); .ToList();
@ -104,7 +104,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>( .With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(version: 1)) Quality = new QualityModel(Quality.MP3_256, new Revision(version: 1))
})) }))
.Build() .Build()
.ToList(); .ToList();
@ -121,7 +121,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>( .With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(version: 1)) Quality = new QualityModel(Quality.MP3_256, new Revision(version: 1))
})) }))
.Build() .Build()
.ToList(); .ToList();
@ -138,14 +138,14 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>( .With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(version: 1)) Quality = new QualityModel(Quality.MP3_256, new Revision(version: 1))
})) }))
.TheNext(1) .TheNext(1)
.With(e => e.EpisodeFileId = 2) .With(e => e.EpisodeFileId = 2)
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>( .With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(version: 1)) Quality = new QualityModel(Quality.MP3_256, new Revision(version: 1))
})) }))
.Build() .Build()
.ToList(); .ToList();

@ -57,7 +57,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Artist = artist, Artist = artist,
Tracks = new List<Track> { track }, Tracks = new List<Track> { track },
Path = Path.Combine(artist.Path, "30 Rock - S01E01 - Pilot.avi"), Path = Path.Combine(artist.Path, "30 Rock - S01E01 - Pilot.avi"),
Quality = new QualityModel(Quality.MP3256), Quality = new QualityModel(Quality.MP3_256),
ParsedTrackInfo = new ParsedTrackInfo ParsedTrackInfo = new ParsedTrackInfo
{ {
ReleaseGroup = "DRONE" ReleaseGroup = "DRONE"
@ -207,7 +207,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Artist = fileDecision.LocalTrack.Artist, Artist = fileDecision.LocalTrack.Artist,
Tracks = new List<Track> { fileDecision.LocalTrack.Tracks.First() }, Tracks = new List<Track> { fileDecision.LocalTrack.Tracks.First() },
Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilot.avi".AsOsAgnostic(), Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilot.avi".AsOsAgnostic(),
Quality = new QualityModel(Quality.MP3256), Quality = new QualityModel(Quality.MP3_256),
Size = 80.Megabytes() Size = 80.Megabytes()
}); });

@ -16,7 +16,7 @@ namespace NzbDrone.Core.Test.MediaFiles
var files = Builder<TrackFile>.CreateListOfSize(10) var files = Builder<TrackFile>.CreateListOfSize(10)
.All() .All()
.With(c => c.Id = 0) .With(c => c.Id = 0)
.With(c => c.Quality =new QualityModel(Quality.MP3192)) .With(c => c.Quality =new QualityModel(Quality.MP3_192))
.Random(4) .Random(4)
.With(s => s.ArtistId = 12) .With(s => s.ArtistId = 12)
.BuildListOfNew(); .BuildListOfNew();

@ -151,7 +151,6 @@
<Compile Include="Datastore\SqliteSchemaDumperTests\SqliteSchemaDumperFixture.cs" /> <Compile Include="Datastore\SqliteSchemaDumperTests\SqliteSchemaDumperFixture.cs" />
<Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\AnimeVersionUpgradeSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\AnimeVersionUpgradeSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\FullSeasonSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\ProtocolSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\ProtocolSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\CutoffSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\CutoffSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\DownloadDecisionMakerFixture.cs" /> <Compile Include="DecisionEngineTests\DownloadDecisionMakerFixture.cs" />
@ -288,9 +287,6 @@
<Compile Include="MediaFiles\EpisodeImport\ImportDecisionMakerFixture.cs" /> <Compile Include="MediaFiles\EpisodeImport\ImportDecisionMakerFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\SampleServiceFixture.cs" /> <Compile Include="MediaFiles\EpisodeImport\SampleServiceFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FreeSpaceSpecificationFixture.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\FreeSpaceSpecificationFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecificationFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\MatchesFolderSpecificationFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotSampleSpecificationFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotUnpackingSpecificationFixture.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\NotUnpackingSpecificationFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecificationFixture.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecificationFixture.cs" />
<Compile Include="MediaFiles\ImportApprovedEpisodesFixture.cs" /> <Compile Include="MediaFiles\ImportApprovedEpisodesFixture.cs" />
@ -306,6 +302,7 @@
<Compile Include="OrganizerTests\FileNameBuilderTests\EpisodeTitleCollapseFixture.cs" /> <Compile Include="OrganizerTests\FileNameBuilderTests\EpisodeTitleCollapseFixture.cs" />
<Compile Include="OrganizerTests\FileNameBuilderTests\MultiEpisodeFixture.cs" /> <Compile Include="OrganizerTests\FileNameBuilderTests\MultiEpisodeFixture.cs" />
<Compile Include="ParserTests\MiniSeriesEpisodeParserFixture.cs" /> <Compile Include="ParserTests\MiniSeriesEpisodeParserFixture.cs" />
<Compile Include="ParserTests\MusicParserFixture.cs" />
<Compile Include="Qualities\RevisionComparableFixture.cs" /> <Compile Include="Qualities\RevisionComparableFixture.cs" />
<Compile Include="QueueTests\QueueServiceFixture.cs" /> <Compile Include="QueueTests\QueueServiceFixture.cs" />
<Compile Include="RemotePathMappingsTests\RemotePathMappingServiceFixture.cs" /> <Compile Include="RemotePathMappingsTests\RemotePathMappingServiceFixture.cs" />

@ -34,7 +34,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
.With(e => e.AbsoluteEpisodeNumber = 100) .With(e => e.AbsoluteEpisodeNumber = 100)
.Build(); .Build();
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3256), ReleaseGroup = "LidarrTest" }; _episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3_256), ReleaseGroup = "LidarrTest" };
_namingConfig = NamingConfig.Default; _namingConfig = NamingConfig.Default;
_namingConfig.RenameEpisodes = true; _namingConfig.RenameEpisodes = true;

@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
.With(e => e.AbsoluteEpisodeNumber = 102) .With(e => e.AbsoluteEpisodeNumber = 102)
.Build(); .Build();
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3256), ReleaseGroup = "LidarrTest" }; _episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3_256), ReleaseGroup = "LidarrTest" };
Mocker.GetMock<IQualityDefinitionService>() Mocker.GetMock<IQualityDefinitionService>()
.Setup(v => v.Get(Moq.It.IsAny<Quality>())) .Setup(v => v.Get(Moq.It.IsAny<Quality>()))

@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
.With(e => e.AbsoluteEpisodeNumber = 100) .With(e => e.AbsoluteEpisodeNumber = 100)
.Build(); .Build();
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3256), ReleaseGroup = "LidarrTest" }; _episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3_256), ReleaseGroup = "LidarrTest" };
Mocker.GetMock<IQualityDefinitionService>() Mocker.GetMock<IQualityDefinitionService>()
.Setup(v => v.Get(Moq.It.IsAny<Quality>())) .Setup(v => v.Get(Moq.It.IsAny<Quality>()))

@ -59,7 +59,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
.With(e => e.AbsoluteEpisodeNumber = 102) .With(e => e.AbsoluteEpisodeNumber = 102)
.Build(); .Build();
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3256), ReleaseGroup = "LidarrTest" }; _episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.MP3_256), ReleaseGroup = "LidarrTest" };
Mocker.GetMock<IQualityDefinitionService>() Mocker.GetMock<IQualityDefinitionService>()
.Setup(v => v.Get(Moq.It.IsAny<Quality>())) .Setup(v => v.Get(Moq.It.IsAny<Quality>()))

@ -15,70 +15,70 @@ namespace NzbDrone.Core.Test.ParserTests
{ {
@"C:\Test\Some.Hashed.Release.(256kbps)-Mercury\0e895c37245186812cb08aab1529cf8ee389dd05.mp3".AsOsAgnostic(), @"C:\Test\Some.Hashed.Release.(256kbps)-Mercury\0e895c37245186812cb08aab1529cf8ee389dd05.mp3".AsOsAgnostic(),
"Some Hashed Release", "Some Hashed Release",
Quality.MP3256, Quality.MP3_256,
"Mercury" "Mercury"
}, },
new object[] new object[]
{ {
@"C:\Test-[256]\0e895c37245186812cb08aab1529cf8ee389dd05\Some.Hashed.Release.S01E01.720p.WEB-DL.AAC2.0.H.264-Mercury.mp3".AsOsAgnostic(), @"C:\Test-[256]\0e895c37245186812cb08aab1529cf8ee389dd05\Some.Hashed.Release.S01E01.720p.WEB-DL.AAC2.0.H.264-Mercury.mp3".AsOsAgnostic(),
"Some Hashed Release", "Some Hashed Release",
Quality.MP3256, Quality.MP3_256,
"Mercury" "Mercury"
}, },
new object[] new object[]
{ {
@"C:\Test\Fake.Dir.S01E01-Test\yrucreM-462.H.0.2CAA.LD-BEW.p027.10E10S.esaeleR.dehsaH.emoS.mp3".AsOsAgnostic(), @"C:\Test\Fake.Dir.S01E01-Test\yrucreM-462.H.0.2CAA.LD-BEW.p027.10E10S.esaeleR.dehsaH.emoS.mp3".AsOsAgnostic(),
"Some Hashed Release", "Some Hashed Release",
Quality.MP3256, Quality.MP3_256,
"Mercury" "Mercury"
}, },
new object[] new object[]
{ {
@"C:\Test\Fake.Dir.S01E01-Test\yrucreM-LN 1.5DD LD-BEW P0801 10E10S esaeleR dehsaH emoS.mp3".AsOsAgnostic(), @"C:\Test\Fake.Dir.S01E01-Test\yrucreM-LN 1.5DD LD-BEW P0801 10E10S esaeleR dehsaH emoS.mp3".AsOsAgnostic(),
"Some Hashed Release", "Some Hashed Release",
Quality.MP3256, Quality.MP3_256,
"Mercury" "Mercury"
}, },
new object[] new object[]
{ {
@"C:\Test\Weeds.S01E10.DVDRip.XviD-Lidarr\AHFMZXGHEWD660.mp3".AsOsAgnostic(), @"C:\Test\Weeds.S01E10.DVDRip.XviD-Lidarr\AHFMZXGHEWD660.mp3".AsOsAgnostic(),
"Weeds", "Weeds",
Quality.MP3256, Quality.MP3_256,
"Lidarr" "Lidarr"
}, },
new object[] new object[]
{ {
@"C:\Test\Deadwood.S02E12.1080p.BluRay.x264-Lidarr\Backup_72023S02-12.mp3".AsOsAgnostic(), @"C:\Test\Deadwood.S02E12.1080p.BluRay.x264-Lidarr\Backup_72023S02-12.mp3".AsOsAgnostic(),
"Deadwood", "Deadwood",
Quality.MP3256, Quality.MP3_256,
null null
}, },
new object[] new object[]
{ {
@"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\123.mp3".AsOsAgnostic(), @"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\123.mp3".AsOsAgnostic(),
"Grimm", "Grimm",
Quality.MP3256, Quality.MP3_256,
"ECI" "ECI"
}, },
new object[] new object[]
{ {
@"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\abc.mp3".AsOsAgnostic(), @"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\abc.mp3".AsOsAgnostic(),
"Grimm", "Grimm",
Quality.MP3256, Quality.MP3_256,
"ECI" "ECI"
}, },
new object[] new object[]
{ {
@"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\b00bs.mp3".AsOsAgnostic(), @"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\b00bs.mp3".AsOsAgnostic(),
"Grimm", "Grimm",
Quality.MP3256, Quality.MP3_256,
"ECI" "ECI"
}, },
new object[] new object[]
{ {
@"C:\Test\The.Good.Wife.S02E23.720p.HDTV.x264-NZBgeek/cgajsofuejsa501.mp3".AsOsAgnostic(), @"C:\Test\The.Good.Wife.S02E23.720p.HDTV.x264-NZBgeek/cgajsofuejsa501.mp3".AsOsAgnostic(),
"The Good Wife", "The Good Wife",
Quality.MP3256, Quality.MP3_256,
"NZBgeek" "NZBgeek"
} }
}; };

@ -0,0 +1,39 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Core.Test.ParserTests
{
[TestFixture]
public class MusicParserFixture : CoreTest
{
[TestCase("___▲▲▲___")]
[TestCase("Add N to (X)")]
[TestCase("Animal Collective")]
[TestCase("D12")]
[TestCase("David Sylvian[Discography]")]
[TestCase("Eagle-Eye Cherry")]
[TestCase("Erlend Øye")]
[TestCase("Adult.")] // Not sure if valid, not openable in Windows OS
[TestCase("Maroon 5")]
[TestCase("Moimir Papalescu & The Nihilists")]
[TestCase("N.W.A")]
[TestCase("oOoOO")]
[TestCase("Panic! at the Disco")]
[TestCase("The 5 6 7 8's")]
[TestCase("tUnE-yArDs")]
[TestCase("U2")]
[TestCase("Белые Братья")]
[TestCase("Zog Bogbean - From The Marcy Playground")]
public void should_parse_artist_names(string title)
{
Parser.Parser.ParseMusicTitle(title).ArtistTitle.Should().Be(title);
ExceptionVerification.IgnoreWarns();
}
}
}

@ -12,11 +12,11 @@ namespace NzbDrone.Core.Test.ParserTests
{ {
public static object[] SelfQualityParserCases = public static object[] SelfQualityParserCases =
{ {
new object[] {Quality.MP3192}, new object[] {Quality.MP3_192},
new object[] {Quality.MP3VBR}, new object[] {Quality.MP3_VBR},
new object[] {Quality.MP3256}, new object[] {Quality.MP3_256},
new object[] {Quality.MP3320}, new object[] {Quality.MP3_320},
new object[] {Quality.MP3512}, new object[] {Quality.MP3_512},
new object[] {Quality.FLAC}, new object[] {Quality.FLAC},
}; };
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Other Song (192)[2014][MP3]")] [TestCase("Other Song (192)[2014][MP3]")]
public void should_parse_mp3_192_quality(string title) public void should_parse_mp3_192_quality(string title)
{ {
ParseAndVerifyQuality(title, Quality.MP3192); ParseAndVerifyQuality(title, Quality.MP3_192);
} }
[TestCase("Beyoncé Lemonade [320] 2016 Beyonce Lemonade [320] 2016")] [TestCase("Beyoncé Lemonade [320] 2016 Beyonce Lemonade [320] 2016")]
@ -43,7 +43,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Anderson Paak - Malibu (320)(2016)")] [TestCase("Anderson Paak - Malibu (320)(2016)")]
public void should_parse_mp3_320_quality(string title) public void should_parse_mp3_320_quality(string title)
{ {
ParseAndVerifyQuality(title, Quality.MP3320); ParseAndVerifyQuality(title, Quality.MP3_320);
} }
@ -59,7 +59,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Walk the Line Soundtrack (2005) [AAC, 256 kbps]")] [TestCase("Walk the Line Soundtrack (2005) [AAC, 256 kbps]")]
public void should_parse_mp3_256_quality(string title) public void should_parse_mp3_256_quality(string title)
{ {
ParseAndVerifyQuality(title, Quality.MP3256); ParseAndVerifyQuality(title, Quality.MP3_256);
} }
[TestCase("Caetano Veloso Discografia Completa MP3 @512")] [TestCase("Caetano Veloso Discografia Completa MP3 @512")]
@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Emeli Sande Next To Me (512 Kbps)")] [TestCase("Emeli Sande Next To Me (512 Kbps)")]
public void should_parse_mp3_512_quality(string title) public void should_parse_mp3_512_quality(string title)
{ {
ParseAndVerifyQuality(title, Quality.MP3512); ParseAndVerifyQuality(title, Quality.MP3_512);
} }
[TestCase("Kendrick Lamar - DAMN (2017) FLAC")] [TestCase("Kendrick Lamar - DAMN (2017) FLAC")]

@ -14,8 +14,8 @@ namespace NzbDrone.Core.Test.Profiles
{ {
var profile = new Profile var profile = new Profile
{ {
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3320, Quality.MP3192, Quality.MP3256), Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_320, Quality.MP3_192, Quality.MP3_256),
Cutoff = Quality.MP3320, Cutoff = Quality.MP3_320,
Name = "TestProfile" Name = "TestProfile"
}; };

@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.Qualities
.Setup(s => s.All()) .Setup(s => s.All())
.Returns(new List<QualityDefinition> .Returns(new List<QualityDefinition>
{ {
new QualityDefinition(Quality.MP3192) { Weight = 1, MinSize = 0, MaxSize = 100, Id = 20 } new QualityDefinition(Quality.MP3_192) { Weight = 1, MinSize = 0, MaxSize = 100, Id = 20 }
}); });
Subject.Handle(new ApplicationStartedEvent()); Subject.Handle(new ApplicationStartedEvent());
@ -42,7 +42,7 @@ namespace NzbDrone.Core.Test.Qualities
.Setup(s => s.All()) .Setup(s => s.All())
.Returns(new List<QualityDefinition> .Returns(new List<QualityDefinition>
{ {
new QualityDefinition(Quality.MP3192) { Weight = 1, MinSize = 0, MaxSize = 100, Id = 20 } new QualityDefinition(Quality.MP3_192) { Weight = 1, MinSize = 0, MaxSize = 100, Id = 20 }
}); });
Subject.Handle(new ApplicationStartedEvent()); Subject.Handle(new ApplicationStartedEvent());

@ -14,22 +14,22 @@ namespace NzbDrone.Core.Test.Qualities
public static object[] FromIntCases = public static object[] FromIntCases =
{ {
new object[] {0, Quality.Unknown}, new object[] {0, Quality.Unknown},
new object[] {1, Quality.MP3192}, new object[] {1, Quality.MP3_192},
new object[] {2, Quality.MP3VBR}, new object[] {2, Quality.MP3_VBR},
new object[] {3, Quality.MP3256}, new object[] {3, Quality.MP3_256},
new object[] {4, Quality.MP3320}, new object[] {4, Quality.MP3_320},
new object[] {5, Quality.MP3512}, new object[] {5, Quality.MP3_512},
new object[] {6, Quality.FLAC}, new object[] {6, Quality.FLAC},
}; };
public static object[] ToIntCases = public static object[] ToIntCases =
{ {
new object[] {Quality.Unknown, 0}, new object[] {Quality.Unknown, 0},
new object[] {Quality.MP3192, 1}, new object[] {Quality.MP3_192, 1},
new object[] {Quality.MP3VBR, 2}, new object[] {Quality.MP3_VBR, 2},
new object[] {Quality.MP3256, 3}, new object[] {Quality.MP3_256, 3},
new object[] {Quality.MP3320, 4}, new object[] {Quality.MP3_320, 4},
new object[] {Quality.MP3512, 5}, new object[] {Quality.MP3_512, 5},
new object[] {Quality.FLAC, 6}, new object[] {Quality.FLAC, 6},
}; };
@ -52,11 +52,11 @@ namespace NzbDrone.Core.Test.Qualities
var qualities = new List<Quality> var qualities = new List<Quality>
{ {
Quality.Unknown, Quality.Unknown,
Quality.MP3192, Quality.MP3_192,
Quality.MP3VBR, Quality.MP3_VBR,
Quality.MP3256, Quality.MP3_256,
Quality.MP3320, Quality.MP3_320,
Quality.MP3512, Quality.MP3_512,
Quality.FLAC, Quality.FLAC,
}; };

@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.Qualities
private void GivenCustomProfile() private void GivenCustomProfile()
{ {
Subject = new QualityModelComparer(new Profile { Items = QualityFixture.GetDefaultQualities(Quality.MP3320, Quality.MP3192) }); Subject = new QualityModelComparer(new Profile { Items = QualityFixture.GetDefaultQualities(Quality.MP3_320, Quality.MP3_192) });
} }
[Test] [Test]
@ -26,8 +26,8 @@ namespace NzbDrone.Core.Test.Qualities
{ {
GivenDefaultProfile(); GivenDefaultProfile();
var first = new QualityModel(Quality.MP3320); var first = new QualityModel(Quality.MP3_320);
var second = new QualityModel(Quality.MP3192); var second = new QualityModel(Quality.MP3_192);
var compare = Subject.Compare(first, second); var compare = Subject.Compare(first, second);
@ -39,8 +39,8 @@ namespace NzbDrone.Core.Test.Qualities
{ {
GivenDefaultProfile(); GivenDefaultProfile();
var first = new QualityModel(Quality.MP3192); var first = new QualityModel(Quality.MP3_192);
var second = new QualityModel(Quality.MP3320); var second = new QualityModel(Quality.MP3_320);
var compare = Subject.Compare(first, second); var compare = Subject.Compare(first, second);
@ -52,8 +52,8 @@ namespace NzbDrone.Core.Test.Qualities
{ {
GivenDefaultProfile(); GivenDefaultProfile();
var first = new QualityModel(Quality.MP3320, new Revision(version: 2)); var first = new QualityModel(Quality.MP3_320, new Revision(version: 2));
var second = new QualityModel(Quality.MP3320, new Revision(version: 1)); var second = new QualityModel(Quality.MP3_320, new Revision(version: 1));
var compare = Subject.Compare(first, second); var compare = Subject.Compare(first, second);
@ -65,8 +65,8 @@ namespace NzbDrone.Core.Test.Qualities
{ {
GivenCustomProfile(); GivenCustomProfile();
var first = new QualityModel(Quality.MP3192); var first = new QualityModel(Quality.MP3_192);
var second = new QualityModel(Quality.MP3320); var second = new QualityModel(Quality.MP3_320);
var compare = Subject.Compare(first, second); var compare = Subject.Compare(first, second);

@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
_episodeFile = Builder<EpisodeFile>.CreateNew() _episodeFile = Builder<EpisodeFile>.CreateNew()
.With(e => e.SeriesId = _series.Id) .With(e => e.SeriesId = _series.Id)
.With(e => e.Quality = new QualityModel(Quality.MP3256)) .With(e => e.Quality = new QualityModel(Quality.MP3_256))
.BuildNew(); .BuildNew();
} }

@ -28,11 +28,11 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
var profile = new Profile var profile = new Profile
{ {
Id = 1, Id = 1,
Cutoff = Quality.MP3256, Cutoff = Quality.MP3_256,
Items = new List<ProfileQualityItem> Items = new List<ProfileQualityItem>
{ {
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3192 }, new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_192 },
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3256 }, new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_256 },
new ProfileQualityItem { Allowed = true, Quality = Quality.FLAC } new ProfileQualityItem { Allowed = true, Quality = Quality.FLAC }
} }
}; };
@ -66,11 +66,11 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
_qualitiesBelowCutoff = new List<QualitiesBelowCutoff> _qualitiesBelowCutoff = new List<QualitiesBelowCutoff>
{ {
new QualitiesBelowCutoff(profile.Id, new[] {Quality.MP3192.Id}) new QualitiesBelowCutoff(profile.Id, new[] {Quality.MP3_192.Id})
}; };
var qualityMet = new TrackFile { RelativePath = "a", Quality = new QualityModel { Quality = Quality.MP3256 } }; var qualityMet = new TrackFile { RelativePath = "a", Quality = new QualityModel { Quality = Quality.MP3_256 } };
var qualityUnmet = new TrackFile { RelativePath = "b", Quality = new QualityModel { Quality = Quality.MP3192 } }; var qualityUnmet = new TrackFile { RelativePath = "b", Quality = new QualityModel { Quality = Quality.MP3_192 } };
var qualityRawHD = new TrackFile { RelativePath = "c", Quality = new QualityModel { Quality = Quality.FLAC } }; var qualityRawHD = new TrackFile { RelativePath = "c", Quality = new QualityModel { Quality = Quality.FLAC } };
MediaFileRepository fileRepository = Mocker.Resolve<MediaFileRepository>(); MediaFileRepository fileRepository = Mocker.Resolve<MediaFileRepository>();
@ -142,7 +142,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
var spec = Subject.EpisodesWhereCutoffUnmet(_pagingSpec, _qualitiesBelowCutoff, false); var spec = Subject.EpisodesWhereCutoffUnmet(_pagingSpec, _qualitiesBelowCutoff, false);
spec.Records.Should().HaveCount(1); spec.Records.Should().HaveCount(1);
spec.Records.Should().OnlyContain(e => e.EpisodeFile.Value.Quality.Quality == Quality.MP3192); spec.Records.Should().OnlyContain(e => e.EpisodeFile.Value.Quality.Quality == Quality.MP3_192);
} }
[Test] [Test]

@ -17,9 +17,9 @@ namespace NzbDrone.Core.Test.TvTests.SeriesRepositoryTests
{ {
var profile = new Profile var profile = new Profile
{ {
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3320, Quality.MP3256, Quality.MP3192), Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_320, Quality.MP3_256, Quality.MP3_192),
Cutoff = Quality.MP3320, Cutoff = Quality.MP3_320,
Name = "TestProfile" Name = "TestProfile"
}; };

@ -59,7 +59,7 @@ namespace NzbDrone.Core.Test.UpdateTests
Mocker.GetMock<IVerifyUpdates>().Setup(c => c.Verify(It.IsAny<UpdatePackage>(), It.IsAny<string>())).Returns(true); Mocker.GetMock<IVerifyUpdates>().Setup(c => c.Verify(It.IsAny<UpdatePackage>(), It.IsAny<string>())).Returns(true);
Mocker.GetMock<IProcessProvider>().Setup(c => c.GetCurrentProcess()).Returns(new ProcessInfo { Id = 12 }); Mocker.GetMock<IProcessProvider>().Setup(c => c.GetCurrentProcess()).Returns(new ProcessInfo { Id = 12 });
Mocker.GetMock<IRuntimeInfo>().Setup(c => c.ExecutingApplication).Returns(@"C:\Test\NzbDrone.exe"); Mocker.GetMock<IRuntimeInfo>().Setup(c => c.ExecutingApplication).Returns(@"C:\Test\Lidarr.exe");
Mocker.GetMock<IConfigFileProvider>() Mocker.GetMock<IConfigFileProvider>()
.SetupGet(s => s.UpdateAutomatically) .SetupGet(s => s.UpdateAutomatically)

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Music;
namespace NzbDrone.Core.DecisionEngine
{
public class SameTracksSpecification
{
private readonly ITrackService _trackService;
public SameTracksSpecification(ITrackService trackService)
{
_trackService = trackService;
}
public bool IsSatisfiedBy(List<Track> tracks)
{
var trackIds = tracks.SelectList(e => e.Id);
var trackFileIds = tracks.Where(c => c.TrackFileId != 0).Select(c => c.TrackFileId).Distinct();
foreach (var trackFileId in trackFileIds)
{
var tracksInFile = _trackService.GetTracksByFileId(trackFileId);
if (tracksInFile.Select(e => e.Id).Except(trackIds).Any())
{
return false;
}
}
return true;
}
}
}

@ -33,7 +33,7 @@ namespace NzbDrone.Core.MediaFiles
public class DiskScanService : public class DiskScanService :
IDiskScanService, IDiskScanService,
IHandle<ArtistUpdatedEvent>, IHandle<ArtistUpdatedEvent>,
IExecute<RescanArtistCommand> IExecute<RescanArtistCommand>
{ {
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly IMakeImportDecision _importDecisionMaker; private readonly IMakeImportDecision _importDecisionMaker;

@ -1,33 +0,0 @@
using System;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
{
public class FullSeasonSpecification : IImportDecisionEngineSpecification
{
private readonly Logger _logger;
public FullSeasonSpecification(Logger logger)
{
_logger = logger;
}
public Decision IsSatisfiedBy(LocalTrack localTrack)
{
throw new NotImplementedException("Interface will be removed");
}
public Decision IsSatisfiedBy(LocalEpisode localEpisode)
{
if (localEpisode.ParsedEpisodeInfo.FullSeason)
{
_logger.Debug("Single episode file detected as containing all episodes in the season");
return Decision.Reject("Single episode file contains all episodes in seasons");
}
return Decision.Accept();
}
}
}

@ -1,113 +0,0 @@
using System;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
{
public class MatchesFolderSpecification : IImportDecisionEngineSpecification
{
private readonly Logger _logger;
public MatchesFolderSpecification(Logger logger)
{
_logger = logger;
}
public Decision IsSatisfiedBy(LocalTrack localTrack)
{
if (localTrack.ExistingFile)
{
return Decision.Accept();
}
var dirInfo = new FileInfo(localTrack.Path).Directory;
if (dirInfo == null)
{
return Decision.Accept();
}
throw new System.NotImplementedException("Needs to be implemented");
//var folderInfo = Parser.Parser.ParseTitle(dirInfo.Name);
//if (folderInfo == null)
//{
// return Decision.Accept();
//}
//if (!folderInfo.TrackNumbers.Any())
//{
// return Decision.Accept();
//}
//var unexpected = localTrack.ParsedTrackInfo.TrackNumbers.Where(f => !folderInfo.TrackNumbers.Contains(f)).ToList();
//// TODO: Implement MatchesFolderSpecification
//if (unexpected.Any())
//{
// _logger.Debug("Unexpected track number(s) in file: {0}", string.Join(", ", unexpected));
// if (unexpected.Count == 1)
// {
// return Decision.Reject("Track Number {0} was unexpected considering the {1} folder name", unexpected.First(), dirInfo.Name);
// }
// return Decision.Reject("Episode Numbers {0} were unexpected considering the {1} folder name", string.Join(", ", unexpected), dirInfo.Name);
//}
return Decision.Accept();
}
public Decision IsSatisfiedBy(LocalEpisode localEpisode)
{
if (localEpisode.ExistingFile)
{
return Decision.Accept();
}
var dirInfo = new FileInfo(localEpisode.Path).Directory;
if (dirInfo == null)
{
return Decision.Accept();
}
var folderInfo = Parser.Parser.ParseTitle(dirInfo.Name);
if (folderInfo == null)
{
return Decision.Accept();
}
if (!folderInfo.EpisodeNumbers.Any())
{
return Decision.Accept();
}
if (folderInfo.FullSeason)
{
return Decision.Accept();
}
var unexpected = localEpisode.ParsedEpisodeInfo.EpisodeNumbers.Where(f => !folderInfo.EpisodeNumbers.Contains(f)).ToList();
if (unexpected.Any())
{
_logger.Debug("Unexpected episode number(s) in file: {0}", string.Join(", ", unexpected));
if (unexpected.Count == 1)
{
return Decision.Reject("Episode Number {0} was unexpected considering the {1} folder name", unexpected.First(), dirInfo.Name);
}
return Decision.Reject("Episode Numbers {0} were unexpected considering the {1} folder name", string.Join(", ", unexpected), dirInfo.Name);
}
return Decision.Accept();
}
}
}

@ -1,47 +0,0 @@
using System;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
{
public class NotSampleSpecification : IImportDecisionEngineSpecification
{
private readonly IDetectSample _detectSample;
private readonly Logger _logger;
public NotSampleSpecification(IDetectSample detectSample,
Logger logger)
{
_detectSample = detectSample;
_logger = logger;
}
public Decision IsSatisfiedBy(LocalTrack localTrack)
{
throw new NotImplementedException();
}
public Decision IsSatisfiedBy(LocalEpisode localEpisode)
{
if (localEpisode.ExistingFile)
{
_logger.Debug("Existing file, skipping sample check");
return Decision.Accept();
}
var sample = _detectSample.IsSample(localEpisode.Series,
localEpisode.Quality,
localEpisode.Path,
localEpisode.Size,
localEpisode.IsSpecial);
if (sample)
{
return Decision.Reject("Sample");
}
return Decision.Accept();
}
}
}

@ -59,6 +59,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
public Decision IsSatisfiedBy(LocalTrack localTrack) public Decision IsSatisfiedBy(LocalTrack localTrack)
{ {
return Decision.Accept();
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }

@ -31,6 +31,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
public Decision IsSatisfiedBy(LocalTrack localTrack) public Decision IsSatisfiedBy(LocalTrack localTrack)
{ {
return Decision.Accept();
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }

@ -1,39 +0,0 @@
using System;
using System.Linq;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
{
public class UnverifiedSceneNumberingSpecification : IImportDecisionEngineSpecification
{
private readonly Logger _logger;
public UnverifiedSceneNumberingSpecification(Logger logger)
{
_logger = logger;
}
public Decision IsSatisfiedBy(LocalTrack localTrack)
{
throw new NotImplementedException("This is not needed, Interface will be removed");
}
public Decision IsSatisfiedBy(LocalEpisode localEpisode)
{
if (localEpisode.ExistingFile)
{
_logger.Debug("Skipping scene numbering check for existing episode");
return Decision.Accept();
}
if (localEpisode.Episodes.Any(v => v.UnverifiedSceneNumbering))
{
_logger.Debug("This file uses unverified scene numbers, will not auto-import until numbering is confirmed on TheXEM. Skipping {0}", localEpisode.Path);
return Decision.Reject("This show has individual episode mappings on TheXEM but the mapping for this episode has not been confirmed yet by their administrators. TheXEM needs manual input.");
}
return Decision.Accept();
}
}
}

@ -55,7 +55,7 @@ namespace NzbDrone.Core.MediaFiles
public void Delete(TrackFile trackFile, DeleteMediaFileReason reason) public void Delete(TrackFile trackFile, DeleteMediaFileReason reason)
{ {
//Little hack so we have the tracks and artist attached for the event consumers //Little hack so we have the tracks and artist attached for the event consumers
trackFile.Episodes.LazyLoad(); trackFile.Tracks.LazyLoad();
trackFile.Path = Path.Combine(trackFile.Artist.Value.Path, trackFile.RelativePath); trackFile.Path = Path.Combine(trackFile.Artist.Value.Path, trackFile.RelativePath);
_mediaFileRepository.Delete(trackFile); _mediaFileRepository.Delete(trackFile);
@ -70,7 +70,6 @@ namespace NzbDrone.Core.MediaFiles
public List<string> FilterExistingFiles(List<string> files, Artist artist) public List<string> FilterExistingFiles(List<string> files, Artist artist)
{ {
//var artistFiles = GetFilesByArtist(artist.ForeignArtistId).Select(f => Path.Combine(artist.Path, f.RelativePath)).ToList();
var artistFiles = GetFilesByArtist(artist.Id).Select(f => Path.Combine(artist.Path, f.RelativePath)).ToList(); var artistFiles = GetFilesByArtist(artist.Id).Select(f => Path.Combine(artist.Path, f.RelativePath)).ToList();
if (!artistFiles.Any()) return files; if (!artistFiles.Any()) return files;
@ -80,7 +79,6 @@ namespace NzbDrone.Core.MediaFiles
public TrackFile Get(int id) public TrackFile Get(int id)
{ {
// TODO: Should this be spotifyID or DB Id?
return _mediaFileRepository.Get(id); return _mediaFileRepository.Get(id);
} }

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;

@ -16,6 +16,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
public int Height { get; set; } public int Height { get; set; }
public string AudioFormat { get; set; } public string AudioFormat { get; set; }
public int AudioBitrate { get; set; } public int AudioBitrate { get; set; }
public string AudioBitrateMode { get; set; }
public TimeSpan RunTime { get; set; } public TimeSpan RunTime { get; set; }
public int AudioStreamCount { get; set; } public int AudioStreamCount { get; set; }
public int AudioChannels { get; set; } public int AudioChannels { get; set; }

@ -104,6 +104,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime); int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
int.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime); int.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);
string audioBitRateMode = mediaInfo.Get(StreamKind.Audio, 0, "BitRate_Mode");
string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate"); string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate");
int aBindex = aBitRate.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase); int aBindex = aBitRate.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);
if (aBindex > 0) if (aBindex > 0)
@ -145,6 +146,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
Height = height, Height = height,
Width = width, Width = width,
AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"), AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
AudioBitrateMode = audioBitRateMode,
AudioBitrate = audioBitRate, AudioBitrate = audioBitRate,
RunTime = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime), RunTime = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime),
AudioStreamCount = streamCount, AudioStreamCount = streamCount,

@ -24,7 +24,7 @@ namespace NzbDrone.Core.MediaFiles
public string ReleaseGroup { get; set; } public string ReleaseGroup { get; set; }
public QualityModel Quality { get; set; } public QualityModel Quality { get; set; }
public MediaInfoModel MediaInfo { get; set; } public MediaInfoModel MediaInfo { get; set; }
public LazyLoaded<List<Track>> Episodes { get; set; } //public LazyLoaded<List<Track>> Episodes { get; set; }
public LazyLoaded<Artist> Artist { get; set; } public LazyLoaded<Artist> Artist { get; set; }
public LazyLoaded<List<Track>> Tracks { get; set; } public LazyLoaded<List<Track>> Tracks { get; set; }

@ -6,10 +6,12 @@ using NzbDrone.Core.MediaFiles.EpisodeImport;
using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Parser;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using NzbDrone.Core.Music;
namespace NzbDrone.Core.MediaFiles.TrackImport namespace NzbDrone.Core.MediaFiles.TrackImport
{ {
@ -25,19 +27,22 @@ namespace NzbDrone.Core.MediaFiles.TrackImport
//private readonly IExtraService _extraService; //private readonly IExtraService _extraService;
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IAlbumRepository _albumRepository;
private readonly Logger _logger; private readonly Logger _logger;
public ImportApprovedTracks(IUpgradeMediaFiles episodeFileUpgrader, public ImportApprovedTracks(IUpgradeMediaFiles episodeFileUpgrader,
IMediaFileService mediaFileService, IMediaFileService mediaFileService,
//IExtraService extraService, //IExtraService extraService,
IAlbumRepository albumRepository,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
Logger logger) Logger logger)
{ {
_trackFileUpgrader = episodeFileUpgrader; _trackFileUpgrader = episodeFileUpgrader;
_mediaFileService = mediaFileService; _mediaFileService = mediaFileService;
// _extraService = extraService; // _extraService = extraService;
_diskProvider = diskProvider; _albumRepository = albumRepository;
_diskProvider = diskProvider;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_logger = logger; _logger = logger;
} }
@ -78,9 +83,9 @@ namespace NzbDrone.Core.MediaFiles.TrackImport
trackFile.Size = _diskProvider.GetFileSize(localTrack.Path); trackFile.Size = _diskProvider.GetFileSize(localTrack.Path);
trackFile.Quality = localTrack.Quality; trackFile.Quality = localTrack.Quality;
trackFile.MediaInfo = localTrack.MediaInfo; trackFile.MediaInfo = localTrack.MediaInfo;
trackFile.AlbumId = localTrack.Album.Id; trackFile.AlbumId = _albumRepository.FindByArtistAndName(localTrack.Artist.Name, Parser.Parser.CleanArtistTitle(localTrack.ParsedTrackInfo.AlbumTitle)).Id;
trackFile.Tracks = localTrack.Tracks;
trackFile.ReleaseGroup = localTrack.ParsedTrackInfo.ReleaseGroup; trackFile.ReleaseGroup = localTrack.ParsedTrackInfo.ReleaseGroup;
trackFile.Tracks = localTrack.Tracks;
bool copyOnly; bool copyOnly;
switch (importMode) switch (importMode)

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.MediaFiles.EpisodeImport;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.TrackImport.Specifications
{
public class SameTracksImportSpecification : IImportDecisionEngineSpecification
{
private readonly SameTracksSpecification _sameTracksSpecification;
private readonly Logger _logger;
public SameTracksImportSpecification(SameTracksSpecification sameTracksSpecification, Logger logger)
{
_sameTracksSpecification = sameTracksSpecification;
_logger = logger;
}
public RejectionType Type => RejectionType.Permanent;
public Decision IsSatisfiedBy(LocalEpisode localEpisode)
{
throw new NotImplementedException();
}
public Decision IsSatisfiedBy(LocalTrack localTrack)
{
if (_sameTracksSpecification.IsSatisfiedBy(localTrack.Tracks))
{
return Decision.Accept();
}
_logger.Debug("Track file on disk contains more tracks than this file contains");
return Decision.Reject("Track file on disk contains more tracks than this file contains");
}
}
}

@ -81,7 +81,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
// We need to perform a direct lookup of the artist // We need to perform a direct lookup of the artist
var httpRequest = _requestBuilder.Create() var httpRequest = _requestBuilder.Create()
.SetSegment("route", "artist/" + foreignArtistId) .SetSegment("route", "artists/" + foreignArtistId)
//.SetSegment("route", "search") //.SetSegment("route", "search")
//.AddQueryParam("type", "artist,album") //.AddQueryParam("type", "artist,album")
//.AddQueryParam("q", spotifyId.ToString()) //.AddQueryParam("q", spotifyId.ToString())

@ -32,6 +32,9 @@ namespace NzbDrone.Core.Music
public List<MediaCover.MediaCover> Images { get; set; } public List<MediaCover.MediaCover> Images { get; set; }
//public List<Actor> Actors { get; set; } // TODO: These are band members. TODO: Refactor //public List<Actor> Actors { get; set; } // TODO: These are band members. TODO: Refactor
public List<string> Genres { get; set; } public List<string> Genres { get; set; }
public DateTime? LastInfoSync { get; set; }
public DateTime? LastDiskSync { get; set; }
public DateTime Added { get; set; }
public String AlbumType { get; set; } // TODO: Turn this into a type similar to Series Type in TV public String AlbumType { get; set; } // TODO: Turn this into a type similar to Series Type in TV
//public string ArtworkUrl { get; set; } //public string ArtworkUrl { get; set; }
//public string Explicitness { get; set; } //public string Explicitness { get; set; }

@ -5,6 +5,7 @@ using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Extensions; using NzbDrone.Core.Datastore.Extensions;
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using Marr.Data.QGen;
namespace NzbDrone.Core.Music namespace NzbDrone.Core.Music
{ {
@ -13,6 +14,7 @@ namespace NzbDrone.Core.Music
bool AlbumPathExists(string path); bool AlbumPathExists(string path);
List<Album> GetAlbums(int artistId); List<Album> GetAlbums(int artistId);
Album FindByName(string cleanTitle); Album FindByName(string cleanTitle);
Album FindByArtistAndName(string artistName, string cleanTitle);
Album FindById(string spotifyId); Album FindById(string spotifyId);
PagingSpec<Album> AlbumsWithoutFiles(PagingSpec<Album> pagingSpec); PagingSpec<Album> AlbumsWithoutFiles(PagingSpec<Album> pagingSpec);
List<Album> AlbumsBetweenDates(DateTime startDate, DateTime endDate, bool includeUnmonitored); List<Album> AlbumsBetweenDates(DateTime startDate, DateTime endDate, bool includeUnmonitored);
@ -31,6 +33,7 @@ namespace NzbDrone.Core.Music
{ {
return Query.Where(c => c.Path == path).Any(); return Query.Where(c => c.Path == path).Any();
} }
public List<Album> GetAlbums(int artistId) public List<Album> GetAlbums(int artistId)
{ {
return Query.Where(s => s.ArtistId == artistId).ToList(); return Query.Where(s => s.ArtistId == artistId).ToList();
@ -98,5 +101,18 @@ namespace NzbDrone.Core.Music
return Query.Where(s => s.CleanTitle == cleanTitle) return Query.Where(s => s.CleanTitle == cleanTitle)
.SingleOrDefault(); .SingleOrDefault();
} }
public Album FindByArtistAndName(string artistName, string cleanTitle)
{
var cleanArtistName = Parser.Parser.CleanArtistTitle(artistName);
cleanTitle = cleanTitle.ToLowerInvariant();
var query = Query.Join<Album, Artist>(JoinType.Inner, album => album.Artist, (album, artist) => album.ArtistId == artist.Id)
.Where<Artist>(artist => artist.CleanName == cleanArtistName)
.Where<Album>(album => album.CleanTitle == cleanTitle);
return Query.Join<Album, Artist>(JoinType.Inner, album => album.Artist, (album, artist) => album.ArtistId == artist.Id )
.Where<Artist>(artist => artist.CleanName == cleanArtistName)
.Where<Album>(album => album.CleanTitle == cleanTitle)
.SingleOrDefault();
}
} }
} }

@ -35,7 +35,8 @@ namespace NzbDrone.Core.Music
void RemoveAddOptions(Album album); void RemoveAddOptions(Album album);
} }
public class AlbumService : IAlbumService public class AlbumService : IAlbumService,
IHandleAsync<ArtistDeletedEvent>
{ {
private readonly IAlbumRepository _albumRepository; private readonly IAlbumRepository _albumRepository;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
@ -76,9 +77,9 @@ namespace NzbDrone.Core.Music
_eventAggregator.PublishEvent(new AlbumDeletedEvent(album, deleteFiles)); _eventAggregator.PublishEvent(new AlbumDeletedEvent(album, deleteFiles));
} }
public Album FindById(string spotifyId) public Album FindById(string lidarrId)
{ {
return _albumRepository.FindById(spotifyId); return _albumRepository.FindById(lidarrId);
} }
@ -169,5 +170,16 @@ namespace NzbDrone.Core.Music
return album; return album;
} }
public void HandleAsync(ArtistDeletedEvent message)
{
var albums = GetAlbumsByArtist(message.Artist.Id);
_albumRepository.DeleteMany(albums);
}
public void Handle(ArtistDeletedEvent message)
{
throw new NotImplementedException();
}
} }
} }

@ -81,14 +81,6 @@ namespace NzbDrone.Core.Music
Ratings = otherArtist.Ratings; Ratings = otherArtist.Ratings;
Members = otherArtist.Members; Members = otherArtist.Members;
Albums = otherArtist.Albums;
Path = otherArtist.Path;
ProfileId = otherArtist.ProfileId;
AlbumFolder = otherArtist.AlbumFolder;
Monitored = otherArtist.Monitored;
RootFolderPath = otherArtist.RootFolderPath;
Tags = otherArtist.Tags;
AddOptions = otherArtist.AddOptions;
} }

@ -8,6 +8,7 @@ namespace NzbDrone.Core.Music
{ {
bool ArtistPathExists(string path); bool ArtistPathExists(string path);
Artist FindByName(string cleanTitle); Artist FindByName(string cleanTitle);
Artist FindById(int dbId);
Artist FindById(string spotifyId); Artist FindById(string spotifyId);
} }
@ -29,6 +30,11 @@ namespace NzbDrone.Core.Music
return Query.Where(s => s.ForeignArtistId == foreignArtistId).SingleOrDefault(); return Query.Where(s => s.ForeignArtistId == foreignArtistId).SingleOrDefault();
} }
public Artist FindById(int dbId)
{
return Query.Where(s => s.Id == dbId).SingleOrDefault();
}
public Artist FindByName(string cleanName) public Artist FindByName(string cleanName)
{ {
cleanName = cleanName.ToLowerInvariant(); cleanName = cleanName.ToLowerInvariant();

@ -19,12 +19,14 @@ namespace NzbDrone.Core.Music
{ {
private readonly IAlbumService _albumService; private readonly IAlbumService _albumService;
private readonly IRefreshTrackService _refreshTrackService; private readonly IRefreshTrackService _refreshTrackService;
private readonly IBuildFileNames _fileNameBuilder;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly Logger _logger; private readonly Logger _logger;
public RefreshAlbumService(IAlbumService albumService, IRefreshTrackService refreshTrackService, IEventAggregator eventAggregator, Logger logger) public RefreshAlbumService(IAlbumService albumService, IBuildFileNames fileNameBuilder, IRefreshTrackService refreshTrackService, IEventAggregator eventAggregator, Logger logger)
{ {
_albumService = albumService; _albumService = albumService;
_fileNameBuilder = fileNameBuilder;
_refreshTrackService = refreshTrackService; _refreshTrackService = refreshTrackService;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_logger = logger; _logger = logger;
@ -58,24 +60,28 @@ namespace NzbDrone.Core.Music
{ {
albumToUpdate = new Album(); albumToUpdate = new Album();
albumToUpdate.Monitored = artist.Monitored; albumToUpdate.Monitored = artist.Monitored;
albumToUpdate.ProfileId = artist.ProfileId;
albumToUpdate.Added = DateTime.UtcNow;
if (string.IsNullOrWhiteSpace(albumToUpdate.Path))
{
albumToUpdate.Path = _fileNameBuilder.BuildAlbumPath(artist, album);
}
newList.Add(albumToUpdate); newList.Add(albumToUpdate);
//var folderName = _fileNameBuilder.GetAlbumFolder(albumToUpdate); //This likely does not belong here, need to create AddAlbumService
//albumToUpdate.Path = Path.Combine(newArtist.RootFolderPath, folderName);
} }
albumToUpdate.ForeignAlbumId = album.ForeignAlbumId; albumToUpdate.ForeignAlbumId = album.ForeignAlbumId;
albumToUpdate.LastInfoSync = DateTime.UtcNow;
albumToUpdate.CleanTitle = album.CleanTitle; albumToUpdate.CleanTitle = album.CleanTitle;
//albumToUpdate.TrackNumber = album.TrackNumber;
albumToUpdate.Title = album.Title ?? "Unknown"; albumToUpdate.Title = album.Title ?? "Unknown";
//albumToUpdate.AlbumId = album.AlbumId; albumToUpdate.CleanTitle = Parser.Parser.CleanArtistTitle(albumToUpdate.Title);
//albumToUpdate.Album = album.Album;
//albumToUpdate.Explicit = album.Explicit;
albumToUpdate.ArtistId = artist.Id; albumToUpdate.ArtistId = artist.Id;
albumToUpdate.Path = artist.Path + album.Title;
albumToUpdate.AlbumType = album.AlbumType; albumToUpdate.AlbumType = album.AlbumType;
//albumToUpdate.Compilation = album.Compilation; albumToUpdate.Genres = album.Genres;
albumToUpdate.Images = album.Images;
_refreshTrackService.RefreshTrackInfo(album, album.Tracks); albumToUpdate.ReleaseDate = album.ReleaseDate;
successCount++; successCount++;
@ -121,7 +127,7 @@ namespace NzbDrone.Core.Music
private Album GetAlbumToUpdate(Artist artist, Album album, List<Album> existingAlbums) private Album GetAlbumToUpdate(Artist artist, Album album, List<Album> existingAlbums)
{ {
return existingAlbums.FirstOrDefault(e => e.ForeignAlbumId == album.ForeignAlbumId && e.ReleaseDate == album.ReleaseDate); return existingAlbums.FirstOrDefault(e => e.ForeignAlbumId == album.ForeignAlbumId/* && e.ReleaseDate == album.ReleaseDate*/);
} }
private IEnumerable<Album> OrderAlbums(Artist artist, List<Album> albums) private IEnumerable<Album> OrderAlbums(Artist artist, List<Album> albums)

@ -21,6 +21,7 @@ namespace NzbDrone.Core.Music
private readonly IProvideArtistInfo _artistInfo; private readonly IProvideArtistInfo _artistInfo;
private readonly IArtistService _artistService; private readonly IArtistService _artistService;
private readonly IRefreshAlbumService _refreshAlbumService; private readonly IRefreshAlbumService _refreshAlbumService;
private readonly IRefreshTrackService _refreshTrackService;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IDiskScanService _diskScanService; private readonly IDiskScanService _diskScanService;
private readonly ICheckIfArtistShouldBeRefreshed _checkIfArtistShouldBeRefreshed; private readonly ICheckIfArtistShouldBeRefreshed _checkIfArtistShouldBeRefreshed;
@ -29,6 +30,7 @@ namespace NzbDrone.Core.Music
public RefreshArtistService(IProvideArtistInfo artistInfo, public RefreshArtistService(IProvideArtistInfo artistInfo,
IArtistService artistService, IArtistService artistService,
IRefreshAlbumService refreshAlbumService, IRefreshAlbumService refreshAlbumService,
IRefreshTrackService refreshTrackService,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
IDiskScanService diskScanService, IDiskScanService diskScanService,
ICheckIfArtistShouldBeRefreshed checkIfArtistShouldBeRefreshed, ICheckIfArtistShouldBeRefreshed checkIfArtistShouldBeRefreshed,
@ -37,6 +39,7 @@ namespace NzbDrone.Core.Music
_artistInfo = artistInfo; _artistInfo = artistInfo;
_artistService = artistService; _artistService = artistService;
_refreshAlbumService = refreshAlbumService; _refreshAlbumService = refreshAlbumService;
_refreshTrackService = refreshTrackService;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_diskScanService = diskScanService; _diskScanService = diskScanService;
_checkIfArtistShouldBeRefreshed = checkIfArtistShouldBeRefreshed; _checkIfArtistShouldBeRefreshed = checkIfArtistShouldBeRefreshed;
@ -55,7 +58,7 @@ namespace NzbDrone.Core.Music
} }
catch (ArtistNotFoundException) catch (ArtistNotFoundException)
{ {
_logger.Error("Artist '{0}' (SpotifyId {1}) was not found, it may have been removed from Spotify.", artist.Name, artist.ForeignArtistId); _logger.Error("Artist '{0}' (LidarrAPI {1}) was not found, it may have been removed from Metadata sources.", artist.Name, artist.ForeignArtistId);
return; return;
} }
@ -63,7 +66,7 @@ namespace NzbDrone.Core.Music
if (artist.ForeignArtistId != artistInfo.ForeignArtistId) if (artist.ForeignArtistId != artistInfo.ForeignArtistId)
{ {
_logger.Warn("Artist '{0}' (SpotifyId {1}) was replaced with '{2}' (SpotifyId {3}), because the original was a duplicate.", artist.Name, artist.ForeignArtistId, artistInfo.Name, artistInfo.ForeignArtistId); _logger.Warn("Artist '{0}' (Artist {1}) was replaced with '{2}' (LidarrAPI {3}), because the original was a duplicate.", artist.Name, artist.ForeignArtistId, artistInfo.Name, artistInfo.ForeignArtistId);
artist.ForeignArtistId = artistInfo.ForeignArtistId; artist.ForeignArtistId = artistInfo.ForeignArtistId;
} }
@ -86,11 +89,16 @@ namespace NzbDrone.Core.Music
_logger.Warn(e, "Couldn't update artist path for " + artist.Path); _logger.Warn(e, "Couldn't update artist path for " + artist.Path);
} }
artist.Albums = UpdateAlbums(artist, artistInfo); //artist.Albums = UpdateAlbums(artist, artistInfo); # We don't need this since we don't store albums in artist table.
_artistService.UpdateArtist(artist); _artistService.UpdateArtist(artist);
_refreshAlbumService.RefreshAlbumInfo(artist, tuple.Item2); _refreshAlbumService.RefreshAlbumInfo(artist, tuple.Item2);
//_refreshTrackService.RefreshTrackInfo(artist, tuple.Item2); foreach (var album in tuple.Item2)
{
_refreshTrackService.RefreshTrackInfo(album, album.Tracks);
}
_logger.Debug("Finished artist refresh for {0}", artist.Name); _logger.Debug("Finished artist refresh for {0}", artist.Name);
_eventAggregator.PublishEvent(new ArtistUpdatedEvent(artist)); _eventAggregator.PublishEvent(new ArtistUpdatedEvent(artist));

@ -17,12 +17,14 @@ namespace NzbDrone.Core.Music
public class RefreshTrackService : IRefreshTrackService public class RefreshTrackService : IRefreshTrackService
{ {
private readonly ITrackService _trackService; private readonly ITrackService _trackService;
private readonly IAlbumService _albumService;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly Logger _logger; private readonly Logger _logger;
public RefreshTrackService(ITrackService trackService, IEventAggregator eventAggregator, Logger logger) public RefreshTrackService(ITrackService trackService, IAlbumService albumService, IEventAggregator eventAggregator, Logger logger)
{ {
_trackService = trackService; _trackService = trackService;
_albumService = albumService;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_logger = logger; _logger = logger;
} }
@ -33,11 +35,13 @@ namespace NzbDrone.Core.Music
var successCount = 0; var successCount = 0;
var failCount = 0; var failCount = 0;
var existingTracks = _trackService.GetTracksByAlbum(album.ArtistId, album.Id); // TODO: JOE: I believe this should be string, string album = _albumService.FindById(album.ForeignAlbumId);
var existingTracks = _trackService.GetTracksByAlbum(album.ArtistId, album.Id);
var updateList = new List<Track>(); var updateList = new List<Track>();
var newList = new List<Track>(); var newList = new List<Track>();
var dupeFreeRemoteTracks = remoteTracks.DistinctBy(m => new { m.AlbumId, m.TrackNumber }).ToList(); var dupeFreeRemoteTracks = remoteTracks.DistinctBy(m => new { m.ForeignTrackId, m.TrackNumber }).ToList();
foreach (var track in OrderTracks(album, dupeFreeRemoteTracks)) foreach (var track in OrderTracks(album, dupeFreeRemoteTracks))
{ {
@ -54,21 +58,20 @@ namespace NzbDrone.Core.Music
{ {
trackToUpdate = new Track(); trackToUpdate = new Track();
trackToUpdate.Monitored = album.Monitored; trackToUpdate.Monitored = album.Monitored;
trackToUpdate.Id = track.Id;
newList.Add(trackToUpdate); newList.Add(trackToUpdate);
} }
// TODO: Use object mapper to automatically handle this
trackToUpdate.ForeignTrackId = track.ForeignTrackId; trackToUpdate.ForeignTrackId = track.ForeignTrackId;
trackToUpdate.TrackNumber = track.TrackNumber; trackToUpdate.TrackNumber = track.TrackNumber;
trackToUpdate.Title = track.Title ?? "Unknown"; trackToUpdate.Title = track.Title ?? "Unknown";
trackToUpdate.AlbumId = album.Id; trackToUpdate.AlbumId = album.Id;
trackToUpdate.Album = track.Album; trackToUpdate.Album = track.Album ?? album;
trackToUpdate.Explicit = track.Explicit; trackToUpdate.Explicit = track.Explicit;
trackToUpdate.ArtistId = album.ArtistId; trackToUpdate.ArtistId = album.ArtistId;
trackToUpdate.Compilation = track.Compilation; trackToUpdate.Compilation = track.Compilation;
// TODO: Implement rest of [RefreshTrackService] fields
successCount++; successCount++;
} }
@ -118,7 +121,8 @@ namespace NzbDrone.Core.Music
private Track GetTrackToUpdate(Album album, Track track, List<Track> existingTracks) private Track GetTrackToUpdate(Album album, Track track, List<Track> existingTracks)
{ {
return existingTracks.FirstOrDefault(e => e.AlbumId == track.AlbumId && e.TrackNumber == track.TrackNumber); var result = existingTracks.FirstOrDefault(e => e.ForeignTrackId == track.ForeignTrackId && e.TrackNumber == track.TrackNumber);
return result;
} }
private IEnumerable<Track> OrderTracks(Album album, List<Track> tracks) private IEnumerable<Track> OrderTracks(Album album, List<Track> tracks)

@ -3,6 +3,7 @@ using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Music.Events; using NzbDrone.Core.Music.Events;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -32,7 +33,10 @@ namespace NzbDrone.Core.Music
void SetTrackMonitoredByAlbum(int artistId, int albumId, bool monitored); void SetTrackMonitoredByAlbum(int artistId, int albumId, bool monitored);
} }
public class TrackService : ITrackService public class TrackService : ITrackService,
IHandleAsync<ArtistDeletedEvent>,
IHandle<TrackFileDeletedEvent>,
IHandle<TrackFileAddedEvent>
{ {
private readonly ITrackRepository _trackRepository; private readonly ITrackRepository _trackRepository;
private readonly IConfigService _configService; private readonly IConfigService _configService;
@ -62,6 +66,7 @@ namespace NzbDrone.Core.Music
public List<Track> GetTracksByArtist(int artistId) public List<Track> GetTracksByArtist(int artistId)
{ {
_logger.Debug("Getting Tracks for ArtistId {0}", artistId);
return _trackRepository.GetTracks(artistId).ToList(); return _trackRepository.GetTracks(artistId).ToList();
} }

@ -90,6 +90,10 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll</HintPath> <HintPath>..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll</HintPath>
</Reference> </Reference>
<Reference Include="policy.2.0.taglib-sharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=db62eba44689b5b0, processorArchitecture=MSIL">
<HintPath>..\packages\taglib.2.1.0.0\lib\policy.2.0.taglib-sharp.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.105.2.3\lib\net4\RestSharp.dll</HintPath> <HintPath>..\packages\RestSharp.105.2.3\lib\net4\RestSharp.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@ -110,6 +114,10 @@
<Reference Include="System.Data.SQLite"> <Reference Include="System.Data.SQLite">
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath> <HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
</Reference> </Reference>
<Reference Include="taglib-sharp, Version=2.1.0.0, Culture=neutral, PublicKeyToken=db62eba44689b5b0, processorArchitecture=MSIL">
<HintPath>..\packages\taglib.2.1.0.0\lib\taglib-sharp.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs"> <Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
@ -316,6 +324,7 @@
<Compile Include="DecisionEngine\Rejection.cs" /> <Compile Include="DecisionEngine\Rejection.cs" />
<Compile Include="DecisionEngine\RejectionType.cs" /> <Compile Include="DecisionEngine\RejectionType.cs" />
<Compile Include="DecisionEngine\SameEpisodesSpecification.cs" /> <Compile Include="DecisionEngine\SameEpisodesSpecification.cs" />
<Compile Include="DecisionEngine\SameTracksSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\AcceptableSizeSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\AcceptableSizeSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\BlacklistSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\BlacklistSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\AnimeVersionUpgradeSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\AnimeVersionUpgradeSpecification.cs" />
@ -756,12 +765,8 @@
<Compile Include="MediaFiles\EpisodeImport\DetectSample.cs" /> <Compile Include="MediaFiles\EpisodeImport\DetectSample.cs" />
<Compile Include="MediaFiles\EpisodeImport\Manual\ManuallyImportedFile.cs" /> <Compile Include="MediaFiles\EpisodeImport\Manual\ManuallyImportedFile.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FreeSpaceSpecification.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\FreeSpaceSpecification.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\MatchesFolderSpecification.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotSampleSpecification.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotUnpackingSpecification.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\NotUnpackingSpecification.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\SameEpisodesImportSpecification.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\SameEpisodesImportSpecification.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\UnverifiedSceneNumberingSpecification.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecification.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecification.cs" />
<Compile Include="MediaFiles\Events\ArtistRenamedEvent.cs" /> <Compile Include="MediaFiles\Events\ArtistRenamedEvent.cs" />
<Compile Include="MediaFiles\Events\ArtistScannedEvent.cs" /> <Compile Include="MediaFiles\Events\ArtistScannedEvent.cs" />
@ -798,6 +803,7 @@
<Compile Include="MediaFiles\TrackImport\ImportApprovedTracks.cs" /> <Compile Include="MediaFiles\TrackImport\ImportApprovedTracks.cs" />
<Compile Include="MediaFiles\TrackImport\ImportDecision.cs" /> <Compile Include="MediaFiles\TrackImport\ImportDecision.cs" />
<Compile Include="MediaFiles\TrackImport\ImportResult.cs" /> <Compile Include="MediaFiles\TrackImport\ImportResult.cs" />
<Compile Include="MediaFiles\TrackImport\Specifications\SameTracksImportSpecification.cs" />
<Compile Include="MediaFiles\UpdateEpisodeFileService.cs" /> <Compile Include="MediaFiles\UpdateEpisodeFileService.cs" />
<Compile Include="MediaFiles\UpgradeMediaFileService.cs" /> <Compile Include="MediaFiles\UpgradeMediaFileService.cs" />
<Compile Include="Messaging\Commands\BackendCommandAttribute.cs" /> <Compile Include="Messaging\Commands\BackendCommandAttribute.cs" />

@ -137,7 +137,7 @@ namespace NzbDrone.Core.Organizer
_singleEpisodeFile = new EpisodeFile _singleEpisodeFile = new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(2)), Quality = new QualityModel(Quality.MP3_256, new Revision(2)),
RelativePath = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv", RelativePath = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv",
SceneName = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE", SceneName = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE",
ReleaseGroup = "RlsGrp", ReleaseGroup = "RlsGrp",
@ -146,7 +146,7 @@ namespace NzbDrone.Core.Organizer
_singleTrackFile = new TrackFile _singleTrackFile = new TrackFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(2)), Quality = new QualityModel(Quality.MP3_256, new Revision(2)),
RelativePath = "Artist.Name.Album.Name.TrackNum.Track.Title.MP3256.mp3", RelativePath = "Artist.Name.Album.Name.TrackNum.Track.Title.MP3256.mp3",
SceneName = "Artist.Name.Album.Name.TrackNum.Track.Title.MP3256", SceneName = "Artist.Name.Album.Name.TrackNum.Track.Title.MP3256",
ReleaseGroup = "RlsGrp", ReleaseGroup = "RlsGrp",
@ -155,7 +155,7 @@ namespace NzbDrone.Core.Organizer
_multiEpisodeFile = new EpisodeFile _multiEpisodeFile = new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(2)), Quality = new QualityModel(Quality.MP3_256, new Revision(2)),
RelativePath = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE.mkv", RelativePath = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE.mkv",
SceneName = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE", SceneName = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE",
ReleaseGroup = "RlsGrp", ReleaseGroup = "RlsGrp",
@ -164,7 +164,7 @@ namespace NzbDrone.Core.Organizer
_dailyEpisodeFile = new EpisodeFile _dailyEpisodeFile = new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(2)), Quality = new QualityModel(Quality.MP3_256, new Revision(2)),
RelativePath = "Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv", RelativePath = "Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv",
SceneName = "Series.Title.2013.10.30.HDTV.x264-EVOLVE", SceneName = "Series.Title.2013.10.30.HDTV.x264-EVOLVE",
ReleaseGroup = "RlsGrp", ReleaseGroup = "RlsGrp",
@ -173,7 +173,7 @@ namespace NzbDrone.Core.Organizer
_animeEpisodeFile = new EpisodeFile _animeEpisodeFile = new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(2)), Quality = new QualityModel(Quality.MP3_256, new Revision(2)),
RelativePath = "[RlsGroup] Series Title - 001 [720p].mkv", RelativePath = "[RlsGroup] Series Title - 001 [720p].mkv",
SceneName = "[RlsGroup] Series Title - 001 [720p]", SceneName = "[RlsGroup] Series Title - 001 [720p]",
ReleaseGroup = "RlsGrp", ReleaseGroup = "RlsGrp",
@ -182,7 +182,7 @@ namespace NzbDrone.Core.Organizer
_animeMultiEpisodeFile = new EpisodeFile _animeMultiEpisodeFile = new EpisodeFile
{ {
Quality = new QualityModel(Quality.MP3256, new Revision(2)), Quality = new QualityModel(Quality.MP3_256, new Revision(2)),
RelativePath = "[RlsGroup] Series Title - 001 - 103 [720p].mkv", RelativePath = "[RlsGroup] Series Title - 001 - 103 [720p].mkv",
SceneName = "[RlsGroup] Series Title - 001 - 103 [720p]", SceneName = "[RlsGroup] Series Title - 001 - 103 [720p]",
ReleaseGroup = "RlsGrp", ReleaseGroup = "RlsGrp",

@ -9,11 +9,12 @@ namespace NzbDrone.Core.Parser.Model
{ {
public class ParsedTrackInfo public class ParsedTrackInfo
{ {
//public int TrackNumber { get; set; }
public string Title { get; set; }
public string ArtistTitle { get; set; } public string ArtistTitle { get; set; }
public string AlbumTitle { get; set; } public string AlbumTitle { get; set; }
public ArtistTitleInfo ArtistTitleInfo { get; set; } public ArtistTitleInfo ArtistTitleInfo { get; set; }
public QualityModel Quality { get; set; } public QualityModel Quality { get; set; }
public string AlbumId { get; set; } // maybe
public int[] TrackNumbers { get; set; } public int[] TrackNumbers { get; set; }
//public Language Language { get; set; } //public Language Language { get; set; }
public string ReleaseGroup { get; set; } public string ReleaseGroup { get; set; }
@ -34,7 +35,7 @@ namespace NzbDrone.Core.Parser.Model
if (TrackNumbers != null && TrackNumbers.Any()) if (TrackNumbers != null && TrackNumbers.Any())
{ {
episodeString = string.Format("T{1}", string.Join("-", TrackNumbers.Select(c => c.ToString("00")))); episodeString = string.Format("T{0}", string.Join("-", TrackNumbers.Select(c => c.ToString("00"))));
} }

@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
using NLog; using NLog;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.MediaFiles.MediaInfo;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
@ -15,6 +16,29 @@ namespace NzbDrone.Core.Parser
{ {
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(Parser)); private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(Parser));
private static readonly Regex[] ReportMusicTitleRegex = new[]
{
// Track with artist (01 - artist - trackName)
new Regex(@"(?<trackNumber>\d*){0,1}([-| ]{0,1})(?<artist>[a-zA-Z0-9, ().&_]*)[-| ]{0,1}(?<trackName>[a-zA-Z0-9, ().&_]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Track without artist (01 - trackName)
new Regex(@"(?<trackNumber>\d*)[-| .]{0,1}(?<trackName>[a-zA-Z0-9, ().&_]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Track without trackNumber or artist(trackName)
new Regex(@"(?<trackNumber>\d*)[-| .]{0,1}(?<trackName>[a-zA-Z0-9, ().&_]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Track without trackNumber and with artist(artist - trackName)
new Regex(@"(?<trackNumber>\d*)[-| .]{0,1}(?<trackName>[a-zA-Z0-9, ().&_]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Track with artist and starting title (01 - artist - trackName)
new Regex(@"(?<trackNumber>\d*){0,1}[-| ]{0,1}(?<artist>[a-zA-Z0-9, ().&_]*)[-| ]{0,1}(?<trackName>[a-zA-Z0-9, ().&_]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
};
private static readonly Regex[] ReportTitleRegex = new[] private static readonly Regex[] ReportTitleRegex = new[]
{ {
//Anime - Absolute Episode Number + Title + Season+Episode //Anime - Absolute Episode Number + Title + Season+Episode
@ -22,6 +46,7 @@ namespace NzbDrone.Core.Parser
// new Regex(@"^(?:(?<absoluteepisode>\d{2,3})(?:_|-|\s|\.)+)+(?<title>.+?)(?:\W|_)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)", // new Regex(@"^(?:(?<absoluteepisode>\d{2,3})(?:_|-|\s|\.)+)+(?<title>.+?)(?:\W|_)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)",
// RegexOptions.IgnoreCase | RegexOptions.Compiled), // RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Multi-Part episodes without a title (S01E05.S01E06) //Multi-Part episodes without a title (S01E05.S01E06)
new Regex(@"^(?:\W*S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,3}(?!\d+)))+){2,}", new Regex(@"^(?:\W*S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,3}(?!\d+)))+){2,}",
RegexOptions.IgnoreCase | RegexOptions.Compiled), RegexOptions.IgnoreCase | RegexOptions.Compiled),
@ -209,7 +234,7 @@ namespace NzbDrone.Core.Parser
{ {
// Generic match for md5 and mixed-case hashes. // Generic match for md5 and mixed-case hashes.
new Regex(@"^[0-9a-zA-Z]{32}", RegexOptions.Compiled), new Regex(@"^[0-9a-zA-Z]{32}", RegexOptions.Compiled),
// Generic match for shorter lower-case hashes. // Generic match for shorter lower-case hashes.
new Regex(@"^[a-z0-9]{24}$", RegexOptions.Compiled), new Regex(@"^[a-z0-9]{24}$", RegexOptions.Compiled),
@ -240,7 +265,7 @@ namespace NzbDrone.Core.Parser
private static readonly Regex FileExtensionRegex = new Regex(@"\.[a-z0-9]{2,4}$", private static readonly Regex FileExtensionRegex = new Regex(@"\.[a-z0-9]{2,4}$",
RegexOptions.IgnoreCase | RegexOptions.Compiled); RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:(480|720|1080|2160)[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|3840x2160|4096x2160|(8|10)b(it)?)\s*", private static readonly Regex SimpleTitleRegex = new Regex(@"(?:(480|720|1080|2160|320)[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|3840x2160|4096x2160|(8|10)b(it)?)\s*",
RegexOptions.IgnoreCase | RegexOptions.Compiled); RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*", private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
@ -280,8 +305,52 @@ namespace NzbDrone.Core.Parser
public static ParsedTrackInfo ParseMusicPath(string path) public static ParsedTrackInfo ParseMusicPath(string path)
{ {
var fileInfo = new FileInfo(path); var fileInfo = new FileInfo(path);
var file = TagLib.File.Create(path);
var trackName = file.Tag.Title;
var trackNumber = file.Tag.Track;
var artistTitleInfo = new ArtistTitleInfo
{
Title = file.Tag.Title,
Year = (int) file.Tag.Year
};
var temp = new int[1];
temp[0] = (int) trackNumber;
var result = new ParsedTrackInfo
{
AlbumTitle = file.Tag.Album,
ArtistTitle = file.Tag.FirstAlbumArtist,
Quality = QualityParser.ParseQuality(trackName),
TrackNumbers = temp,
ArtistTitleInfo = artistTitleInfo,
Title = file.Tag.Title
};
Logger.Debug("Quality parsed: {0}", file.Tag.BeatsPerMinute);
foreach (TagLib.ICodec codec in file.Properties.Codecs)
{
TagLib.IAudioCodec acodec = codec as TagLib.IAudioCodec;
TagLib.IVideoCodec vcodec = codec as TagLib.IVideoCodec;
if (acodec != null && (acodec.MediaTypes & TagLib.MediaTypes.Audio) != TagLib.MediaTypes.None)
{
Logger.Debug("Audio Properties : " + acodec.Description);
Logger.Debug("Bitrate: " + acodec.AudioBitrate);
Logger.Debug("SampleRate: " + acodec.AudioSampleRate);
Logger.Debug("Channels: " + acodec.AudioChannels + "\n");
var result = ParseMusicTitle(fileInfo.Name); result.Quality = QualityParser.ParseQuality(acodec.Description, acodec.AudioBitrate, acodec.AudioSampleRate);
}
}
// TODO: Check if it is common that we might need to fallback to parser to gather details
//var result = ParseMusicTitle(fileInfo.Name);
if (result == null) if (result == null)
{ {
@ -367,7 +436,7 @@ namespace NzbDrone.Core.Parser
} }
} }
foreach (var regex in ReportTitleRegex) foreach (var regex in ReportMusicTitleRegex)
{ {
var match = regex.Matches(simpleTitle); var match = regex.Matches(simpleTitle);
@ -392,7 +461,7 @@ namespace NzbDrone.Core.Parser
result.Quality = QualityParser.ParseQuality(title); result.Quality = QualityParser.ParseQuality(title);
Logger.Debug("Quality parsed: {0}", result.Quality); Logger.Debug("Quality parsed: {0}", result.Quality);
// Majora: We don't currently need Release Group for Music. // Majora: We don't currently need Release Group for Music.
//result.ReleaseGroup = ParseReleaseGroup(title); //result.ReleaseGroup = ParseReleaseGroup(title);
//var subGroup = GetSubGroup(match); //var subGroup = GetSubGroup(match);
@ -667,8 +736,79 @@ namespace NzbDrone.Core.Parser
private static ParsedTrackInfo ParseMatchMusicCollection(MatchCollection matchCollection) private static ParsedTrackInfo ParseMatchMusicCollection(MatchCollection matchCollection)
{ {
throw new NotImplementedException(); var artistName = matchCollection[0].Groups["artist"].Value./*Removed for cases like Will.I.Am Replace('.', ' ').*/Replace('_', ' ');
artistName = RequestInfoRegex.Replace(artistName, "").Trim(' ');
// Coppied from Radarr (https://github.com/Radarr/Radarr/blob/develop/src/NzbDrone.Core/Parser/Parser.cs)
// TODO: Split into separate method and write unit tests for.
var parts = artistName.Split('.');
artistName = "";
int n = 0;
bool previousAcronym = false;
string nextPart = "";
foreach (var part in parts)
{
if (parts.Length >= n + 2)
{
nextPart = parts[n + 1];
}
if (part.Length == 1 && part.ToLower() != "a" && !int.TryParse(part, out n))
{
artistName += part + ".";
previousAcronym = true;
}
else if (part.ToLower() == "a" && (previousAcronym == true || nextPart.Length == 1))
{
artistName += part + ".";
previousAcronym = true;
}
else
{
if (previousAcronym)
{
artistName += " ";
previousAcronym = false;
}
artistName += part + " ";
}
n++;
}
artistName = artistName.Trim(' ');
int trackNumber;
int.TryParse(matchCollection[0].Groups["trackNumber"].Value, out trackNumber);
ParsedTrackInfo result = new ParsedTrackInfo();
result.ArtistTitle = artistName;
result.ArtistTitleInfo = GetArtistTitleInfo(result.ArtistTitle);
Logger.Debug("Episode Parsed. {0}", result);
return result;
} }
private static ArtistTitleInfo GetArtistTitleInfo(string title)
{
var artistTitleInfo = new ArtistTitleInfo();
artistTitleInfo.Title = title;
//var match = YearInTitleRegex.Match(title);
//if (!match.Success)
//{
// artistTitleInfo.TitleWithoutYear = title;
//}
//else
//{
// artistTitleInfo.TitleWithoutYear = match.Groups["title"].Value;
// artistTitleInfo.Year = Convert.ToInt32(match.Groups["year"].Value);
//}
return artistTitleInfo;
}
private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchCollection) private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchCollection)
{ {
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' '); var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');

@ -34,6 +34,7 @@ namespace NzbDrone.Core.Parser
private readonly IEpisodeService _episodeService; private readonly IEpisodeService _episodeService;
private readonly ISeriesService _seriesService; private readonly ISeriesService _seriesService;
private readonly IAlbumRepository _albumRepository;
private readonly IArtistService _artistService; private readonly IArtistService _artistService;
private readonly ITrackService _trackService; private readonly ITrackService _trackService;
private readonly Logger _logger; private readonly Logger _logger;
@ -41,11 +42,13 @@ namespace NzbDrone.Core.Parser
public ParsingService(IEpisodeService episodeService, public ParsingService(IEpisodeService episodeService,
ISeriesService seriesService, ISeriesService seriesService,
ITrackService trackService, ITrackService trackService,
IAlbumRepository albumRepository,
// ISceneMappingService sceneMappingService, // ISceneMappingService sceneMappingService,
Logger logger) Logger logger)
{ {
_episodeService = episodeService; _episodeService = episodeService;
_seriesService = seriesService; _seriesService = seriesService;
_albumRepository = albumRepository;
// _sceneMappingService = sceneMappingService; // _sceneMappingService = sceneMappingService;
_trackService = trackService; _trackService = trackService;
_logger = logger; _logger = logger;
@ -409,74 +412,46 @@ namespace NzbDrone.Core.Parser
return result; return result;
} }
private List<Track> GetStandardTracks(Artist artist, ParsedTrackInfo parsedTrackInfo, SearchCriteriaBase searchCriteria) //private List<Track> GetStandardTracks(Artist artist, ParsedTrackInfo parsedTrackInfo, SearchCriteriaBase searchCriteria)
{ //{
var result = new List<Track>(); // var result = new List<Track>();
if (parsedTrackInfo.TrackNumbers == null)
{
return result;
}
foreach (var trackNumber in parsedTrackInfo.TrackNumbers)
{
//if (series.UseSceneNumbering && sceneSource)
//{
// List<Episode> episodes = new List<Episode>();
// if (searchCriteria != null) // if (parsedTrackInfo.TrackNumbers == null)
// { // {
// episodes = searchCriteria.Episodes.Where(e => e.SceneSeasonNumber == parsedTrackInfo.SeasonNumber && // return result;
// e.SceneEpisodeNumber == trackNumber).ToList(); // }
// }
// if (!episodes.Any())
// {
// episodes = _episodeService.FindEpisodesBySceneNumbering(series.Id, seasonNumber, trackNumber);
// }
// if (episodes != null && episodes.Any()) // foreach (var trackNumber in parsedTrackInfo.TrackNumbers)
// { // {
// _logger.Debug("Using Scene to TVDB Mapping for: {0} - Scene: {1}x{2:00} - TVDB: {3}", // Track trackInfo = null;
// series.Title,
// episodes.First().SceneSeasonNumber,
// episodes.First().SceneEpisodeNumber,
// string.Join(", ", episodes.Select(e => string.Format("{0}x{1:00}", e.SeasonNumber, e.EpisodeNumber))));
// result.AddRange(episodes);
// continue;
// }
//}
Track trackInfo = null;
if (searchCriteria != null) // if (searchCriteria != null)
{ // {
trackInfo = searchCriteria.Tracks.SingleOrDefault(e => e.TrackNumber == trackNumber); //e => e.SeasonNumber == seasonNumber && e.TrackNumber == trackNumber // trackInfo = searchCriteria.Tracks.SingleOrDefault(e => e.TrackNumber == trackNumber); //e => e.SeasonNumber == seasonNumber && e.TrackNumber == trackNumber
} // }
if (trackInfo == null) // if (trackInfo == null)
{ // {
// TODO: [ParsingService]: FindTrack by artistID and trackNumber (or albumID and trackNumber if we change db schema to album as base) // // TODO: [ParsingService]: FindTrack by artistID and trackNumber (or albumID and trackNumber if we change db schema to album as base)
_logger.Debug("TrackInfo is null, we will not add as FindTrack(artistId, trackNumber) is not implemented"); // _logger.Debug("TrackInfo is null, we will not add as FindTrack(artistId, trackNumber) is not implemented");
//trackInfo = _trackService.FindTrack(artist.SpotifyId, trackNumber); // //trackInfo = _trackService.FindTrack(artist.SpotifyId, trackNumber);
} // }
if (trackInfo != null) // if (trackInfo != null)
{ // {
result.Add(trackInfo); // result.Add(trackInfo);
} // }
else // else
{ // {
_logger.Debug("Unable to find {0}", parsedTrackInfo); // _logger.Debug("Unable to find {0}", parsedTrackInfo);
} // }
} // }
return result; // return result;
} //}
private List<Episode> GetStandardEpisodes(Series series, ParsedEpisodeInfo parsedEpisodeInfo, bool sceneSource, SearchCriteriaBase searchCriteria) private List<Episode> GetStandardEpisodes(Series series, ParsedEpisodeInfo parsedEpisodeInfo, bool sceneSource, SearchCriteriaBase searchCriteria)
{ {
@ -565,6 +540,7 @@ namespace NzbDrone.Core.Parser
{ {
ParsedTrackInfo parsedTrackInfo; ParsedTrackInfo parsedTrackInfo;
if (folderInfo != null) if (folderInfo != null)
{ {
parsedTrackInfo = folderInfo.JsonClone(); parsedTrackInfo = folderInfo.JsonClone();
@ -576,16 +552,10 @@ namespace NzbDrone.Core.Parser
parsedTrackInfo = Parser.ParseMusicPath(filename); parsedTrackInfo = Parser.ParseMusicPath(filename);
} }
if (parsedTrackInfo == null) //if (parsedTrackInfo == null)
{ //{
var title = Path.GetFileNameWithoutExtension(filename); // var title = Path.GetFileNameWithoutExtension(filename);
//var specialEpisodeInfo = ParseSpecialEpisodeTitle(title, series); //}
//if (specialEpisodeInfo != null)
//{
// parsedTrackInfo = specialEpisodeInfo;
//}
}
if (parsedTrackInfo == null) if (parsedTrackInfo == null)
{ {
@ -612,50 +582,12 @@ namespace NzbDrone.Core.Parser
private List<Track> GetTracks(ParsedTrackInfo parsedTrackInfo, Artist artist) private List<Track> GetTracks(ParsedTrackInfo parsedTrackInfo, Artist artist)
{ {
// TODO: Ensure GetTracks(parsedTrackInfo, artist) doesn't need any checks
/*if (parsedTrackInfo.FullSeason) // IF Album
{
return _trackService.GetTracksByAlbumTitle(artist.Id, parsedTrackInfo.AlbumTitle);
}
if (parsedTrackInfo.IsDaily)
{
if (artist.SeriesType == SeriesTypes.Standard)
{
_logger.Warn("Found daily-style episode for non-daily series: {0}.", series);
return new List<Episode>();
}
var episodeInfo = GetDailyEpisode(artist, parsedTrackInfo.AirDate, searchCriteria);
if (episodeInfo != null)
{
return new List<Episode> { episodeInfo };
}
return new List<Track>();
}
return GetStandardEpisodes(artist, parsedTrackInfo, sceneSource, searchCriteria);*/
return GetStandardTracks(artist, parsedTrackInfo); return GetStandardTracks(artist, parsedTrackInfo);
} }
private List<Track> GetStandardTracks(Artist artist, ParsedTrackInfo parsedTrackInfo) private List<Track> GetStandardTracks(Artist artist, ParsedTrackInfo parsedTrackInfo)
{ {
var result = new List<Track>(); var result = new List<Track>();
//var seasonNumber = parsedEpisodeInfo.SeasonNumber;
//if (sceneSource)
//{
// var sceneMapping = _sceneMappingService.FindSceneMapping(parsedEpisodeInfo.SeriesTitle);
// if (sceneMapping != null && sceneMapping.SeasonNumber.HasValue && sceneMapping.SeasonNumber.Value >= 0 &&
// sceneMapping.SceneSeasonNumber == seasonNumber)
// {
// seasonNumber = sceneMapping.SeasonNumber.Value;
// }
//}
if (parsedTrackInfo.TrackNumbers == null) if (parsedTrackInfo.TrackNumbers == null)
{ {
@ -664,7 +596,7 @@ namespace NzbDrone.Core.Parser
foreach (var trackNumber in parsedTrackInfo.TrackNumbers) foreach (var trackNumber in parsedTrackInfo.TrackNumbers)
{ {
Track trackInfo = null; Track trackInfo = null;
@ -675,9 +607,12 @@ namespace NzbDrone.Core.Parser
if (trackInfo == null) if (trackInfo == null)
{ {
// TODO: [ParsingService]: FindTrack by artistID and trackNumber (or albumID and trackNumber if we change db schema to album as base) var album = _albumRepository.FindByArtistAndName(parsedTrackInfo.ArtistTitle, Parser.CleanArtistTitle(parsedTrackInfo.AlbumTitle));
_logger.Debug("TrackInfo is null, we will not add as FindTrack(artistId, trackNumber) is not implemented"); if (album == null)
//trackInfo = _trackService.FindTrack(artist.SpotifyId, trackNumber); //series.Id, seasonNumber, trackNumber {
return new List<Track>();
}
trackInfo = _trackService.FindTrack(artist.Id, album.Id, trackNumber);
} }
if (trackInfo != null) if (trackInfo != null)
@ -694,4 +629,4 @@ namespace NzbDrone.Core.Parser
return result; return result;
} }
} }
} }

@ -39,18 +39,48 @@ namespace NzbDrone.Core.Parser
private static readonly Regex RealRegex = new Regex(@"\b(?<real>REAL)\b", private static readonly Regex RealRegex = new Regex(@"\b(?<real>REAL)\b",
RegexOptions.Compiled); RegexOptions.Compiled);
private static readonly Regex BitRateRegex = new Regex(@"(?: private static readonly Regex BitRateRegex = new Regex(@"\b(?:(?<B192>192[ ]?kbps|192|[\[\(].*192.*[\]\)])|
(?<B192>192[ ]?kbps)|(?<B192>192$)|(?<B192>[\[\(].*192.*[\]\)])| (?<B256>256[ ]?kbps|256|[\[\(].*256.*[\]\)])|
(?<B256>256[ ]?kbps)|(?<B256>256$)|(?<B256>[\[\(].*256.*[\]\)])| (?<B320>320[ ]?kbps|320|[\[\(].*320.*[\]\)])|
(?<B320>320[ ]?kbps)|(?<B320>320$)|(?<B320>[\[\(].*320.*[\]\)])| (?<B512>512[ ]?kbps|512|[\[\(].*512.*[\]\)])|
(?<B512>512[ ]?kbps)|(?<B512>512$)|(?<B512>[\[\(].*512.*[\]\)])| (?<VBR>VBR[ ]?kbps|VBR|[\[\(].*VBR.*[\]\)])|
(?<Flac>flac[-_.\]\b)} ])|(?<Flac>flac$)| (?<FLAC>FLAC))\b",
(?<VBR>VBR[ ]?kbps)|(?<VBR>VBR$)|(?<VBR>[\[\(].*VBR.*[\]\)]) RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
)",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); private static readonly Regex CodecRegex = new Regex(@"\b(?:
(?<MP3>MPEG Version \d+ Audio, Layer 3)|
private static readonly Regex CodecRegex = new Regex(@"\b(?:(?<x264>x264)|(?<h264>h264)|(?<xvidhd>XvidHD)|(?<xvid>Xvid)|(?<divx>divx))\b", (?<FLAC>flac)|
RegexOptions.Compiled | RegexOptions.IgnoreCase); (?<VBR>VBR|MPEG Version \d+ Audio, Layer 3 VBR$)
)\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
public static QualityModel ParseQuality(string desc, int bitrate, int sampleRate)
{
var result = new QualityModel { Quality = Quality.Unknown };
switch (bitrate)
{
case 192:
result.Quality = Quality.MP3_192;
break;
case 256:
result.Quality = Quality.MP3_256;
break;
case 320:
result.Quality = Quality.MP3_320;
break;
default:
var match = CodecRegex.Match(desc); //TODO: BUG: Figure out why this always fails
if (!match.Success) result.Quality = Quality.Unknown;
if (match.Groups["VBR"].Success) result.Quality = Quality.MP3_VBR;
if (match.Groups["FLAC"].Success) result.Quality = Quality.FLAC;
break;
}
return result;
}
public static QualityModel ParseQuality(string name) public static QualityModel ParseQuality(string name)
{ {
@ -63,22 +93,22 @@ namespace NzbDrone.Core.Parser
switch(bitrate) switch(bitrate)
{ {
case BitRate.B192: case BitRate.B192:
result.Quality = Quality.MP3192; result.Quality = Quality.MP3_192;
break; break;
case BitRate.B256: case BitRate.B256:
result.Quality = Quality.MP3256; result.Quality = Quality.MP3_256;
break; break;
case BitRate.B320: case BitRate.B320:
result.Quality = Quality.MP3320; result.Quality = Quality.MP3_320;
break; break;
case BitRate.B512: case BitRate.B512:
result.Quality = Quality.MP3512; result.Quality = Quality.MP3_512;
break; break;
case BitRate.Flac: case BitRate.FLAC:
result.Quality = Quality.FLAC; result.Quality = Quality.FLAC;
break; break;
case BitRate.VBR: case BitRate.VBR:
result.Quality = Quality.MP3VBR; result.Quality = Quality.MP3_VBR;
break; break;
} }
@ -100,6 +130,17 @@ namespace NzbDrone.Core.Parser
return result; return result;
} }
private static BitRate ParseCodec(string name)
{
var match = BitRateRegex.Match(name);
if (!match.Success) return BitRate.Unknown;
if (match.Groups["FLAC"].Success) return BitRate.FLAC;
if (match.Groups["VBR"].Success) return BitRate.VBR;
return BitRate.Unknown;
}
private static BitRate ParseBitRate(string name) private static BitRate ParseBitRate(string name)
{ {
//var nameWithNoSpaces = Regex.Replace(name, @"\s+", ""); //var nameWithNoSpaces = Regex.Replace(name, @"\s+", "");
@ -110,7 +151,7 @@ namespace NzbDrone.Core.Parser
if (match.Groups["B256"].Success) return BitRate.B256; if (match.Groups["B256"].Success) return BitRate.B256;
if (match.Groups["B320"].Success) return BitRate.B320; if (match.Groups["B320"].Success) return BitRate.B320;
if (match.Groups["B512"].Success) return BitRate.B512; if (match.Groups["B512"].Success) return BitRate.B512;
if (match.Groups["Flac"].Success) return BitRate.Flac; if (match.Groups["FLAC"].Success) return BitRate.FLAC;
if (match.Groups["VBR"].Success) return BitRate.VBR; if (match.Groups["VBR"].Success) return BitRate.VBR;
return BitRate.Unknown; return BitRate.Unknown;
@ -152,7 +193,7 @@ namespace NzbDrone.Core.Parser
B320, B320,
B512, B512,
VBR, VBR,
Flac, FLAC,
Unknown, Unknown,
} }
} }

@ -87,20 +87,20 @@ namespace NzbDrone.Core.Profiles
_logger.Info("Setting up default quality profiles"); _logger.Info("Setting up default quality profiles");
AddDefaultProfile("Any", AddDefaultProfile("Any",
Quality.MP3192, Quality.MP3_192,
Quality.MP3256, Quality.MP3_256,
Quality.MP3320, Quality.MP3_320,
Quality.MP3512, Quality.MP3_512,
Quality.MP3VBR, Quality.MP3_VBR,
Quality.FLAC); Quality.FLAC);
AddDefaultProfile("Lossless", AddDefaultProfile("Lossless",
Quality.FLAC); Quality.FLAC);
AddDefaultProfile("Standard", AddDefaultProfile("Standard",
Quality.MP3192, Quality.MP3_192,
Quality.MP3256, Quality.MP3_256,
Quality.MP3320); Quality.MP3_320);
} }
} }
} }

@ -56,11 +56,11 @@ namespace NzbDrone.Core.Qualities
} }
public static Quality Unknown => new Quality(0, "Unknown"); public static Quality Unknown => new Quality(0, "Unknown");
public static Quality MP3192 => new Quality(1, "MP3-192"); public static Quality MP3_192 => new Quality(1, "MP3-192");
public static Quality MP3VBR => new Quality(2, "MP3-VBR"); public static Quality MP3_VBR => new Quality(2, "MP3-VBR");
public static Quality MP3256 => new Quality(3, "MP3-256"); public static Quality MP3_256 => new Quality(3, "MP3-256");
public static Quality MP3320 => new Quality(4, "MP3-320"); public static Quality MP3_320 => new Quality(4, "MP3-320");
public static Quality MP3512 => new Quality(5, "MP3-512"); public static Quality MP3_512 => new Quality(5, "MP3-512");
public static Quality FLAC => new Quality(6, "FLAC"); public static Quality FLAC => new Quality(6, "FLAC");
static Quality() static Quality()
@ -68,11 +68,11 @@ namespace NzbDrone.Core.Qualities
All = new List<Quality> All = new List<Quality>
{ {
Unknown, Unknown,
MP3192, MP3_192,
MP3VBR, MP3_VBR,
MP3256, MP3_256,
MP3320, MP3_320,
MP3512, MP3_512,
FLAC, FLAC,
}; };
@ -85,11 +85,11 @@ namespace NzbDrone.Core.Qualities
DefaultQualityDefinitions = new HashSet<QualityDefinition> DefaultQualityDefinitions = new HashSet<QualityDefinition>
{ {
new QualityDefinition(Quality.Unknown) { Weight = 1, MinSize = 0, MaxSize = 100 }, new QualityDefinition(Quality.Unknown) { Weight = 1, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.MP3192) { Weight = 2, MinSize = 0, MaxSize = 100 }, new QualityDefinition(Quality.MP3_192) { Weight = 2, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.MP3VBR) { Weight = 3, MinSize = 0, MaxSize = 100 }, new QualityDefinition(Quality.MP3_VBR) { Weight = 3, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.MP3256) { Weight = 4, MinSize = 0, MaxSize = 100 }, new QualityDefinition(Quality.MP3_256) { Weight = 4, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.MP3320) { Weight = 5, MinSize = 0, MaxSize = 100 }, new QualityDefinition(Quality.MP3_320) { Weight = 5, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.MP3512) { Weight = 6, MinSize = 0, MaxSize = 100 }, new QualityDefinition(Quality.MP3_512) { Weight = 6, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.FLAC) { Weight = 7, MinSize = 0, MaxSize = null }, new QualityDefinition(Quality.FLAC) { Weight = 7, MinSize = 0, MaxSize = null },
}; };
} }

@ -9,6 +9,7 @@
<package id="OAuth" version="1.0.3" targetFramework="net40" /> <package id="OAuth" version="1.0.3" targetFramework="net40" />
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" /> <package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
<package id="RestSharp" version="105.2.3" targetFramework="net40" /> <package id="RestSharp" version="105.2.3" targetFramework="net40" />
<package id="taglib" version="2.1.0.0" targetFramework="net40" />
<package id="TinyTwitter" version="1.1.2" targetFramework="net40" /> <package id="TinyTwitter" version="1.1.2" targetFramework="net40" />
<package id="xmlrpcnet" version="2.5.0" targetFramework="net40" /> <package id="xmlrpcnet" version="2.5.0" targetFramework="net40" />
</packages> </packages>

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("NzbDrone.exe")] [assembly: AssemblyTitle("Lidarr.exe")]
[assembly: Guid("C2172AF4-F9A6-4D91-BAEE-C2E4EE680613")] [assembly: Guid("C2172AF4-F9A6-4D91-BAEE-C2E4EE680613")]
[assembly: AssemblyVersion("10.0.0.*")] [assembly: AssemblyVersion("10.0.0.*")]

@ -45,7 +45,7 @@ namespace NzbDrone.Integration.Test.ApiTests
{ {
EnsureNoArtsit("266189", "Alien Ant Farm"); EnsureNoArtsit("266189", "Alien Ant Farm");
var artist = Artist.Lookup("tvdb:266189").Single(); var artist = Artist.Lookup("lidarr:266189").Single();
artist.ProfileId = 1; artist.ProfileId = 1;
@ -57,7 +57,7 @@ namespace NzbDrone.Integration.Test.ApiTests
{ {
EnsureNoArtsit("266189", "Alien Ant Farm"); EnsureNoArtsit("266189", "Alien Ant Farm");
var artist = Artist.Lookup("tvdb:266189").Single(); var artist = Artist.Lookup("lidarr:266189").Single();
artist.ProfileId = 1; artist.ProfileId = 1;
artist.Path = Path.Combine(ArtistRootFolder, artist.Name); artist.Path = Path.Combine(ArtistRootFolder, artist.Name);

@ -42,9 +42,9 @@ namespace NzbDrone.Integration.Test.ApiTests
[Test, Order(1)] [Test, Order(1)]
public void cutoff_should_have_monitored_items() public void cutoff_should_have_monitored_items()
{ {
EnsureProfileCutoff(1, Quality.MP3256); EnsureProfileCutoff(1, Quality.MP3_256);
var artist = EnsureArtist("266189", "The Blacklist", true); var artist = EnsureArtist("266189", "The Blacklist", true);
EnsureTrackFile(artist, 1, 1, Quality.MP3192); EnsureTrackFile(artist, 1, 1, Quality.MP3_192);
var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc"); var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc");
@ -64,9 +64,9 @@ namespace NzbDrone.Integration.Test.ApiTests
[Test, Order(1)] [Test, Order(1)]
public void cutoff_should_not_have_unmonitored_items() public void cutoff_should_not_have_unmonitored_items()
{ {
EnsureProfileCutoff(1, Quality.MP3256); EnsureProfileCutoff(1, Quality.MP3_256);
var artist = EnsureArtist("266189", "The Blacklist", false); var artist = EnsureArtist("266189", "The Blacklist", false);
EnsureTrackFile(artist, 1, 1, Quality.MP3192); EnsureTrackFile(artist, 1, 1, Quality.MP3_192);
var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc"); var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc");
@ -76,9 +76,9 @@ namespace NzbDrone.Integration.Test.ApiTests
[Test, Order(1)] [Test, Order(1)]
public void cutoff_should_have_artist() public void cutoff_should_have_artist()
{ {
EnsureProfileCutoff(1, Quality.MP3256); EnsureProfileCutoff(1, Quality.MP3_256);
var artist = EnsureArtist("266189", "The Blacklist", true); var artist = EnsureArtist("266189", "The Blacklist", true);
EnsureTrackFile(artist, 1, 1, Quality.MP3192); EnsureTrackFile(artist, 1, 1, Quality.MP3_192);
var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc"); var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc");
@ -99,9 +99,9 @@ namespace NzbDrone.Integration.Test.ApiTests
[Test, Order(2)] [Test, Order(2)]
public void cutoff_should_have_unmonitored_items() public void cutoff_should_have_unmonitored_items()
{ {
EnsureProfileCutoff(1, Quality.MP3256); EnsureProfileCutoff(1, Quality.MP3_256);
var artist = EnsureArtist("266189", "The Blacklist", false); var artist = EnsureArtist("266189", "The Blacklist", false);
EnsureTrackFile(artist, 1, 1, Quality.MP3192); EnsureTrackFile(artist, 1, 1, Quality.MP3_192);
var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc", "monitored", "false"); var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc", "monitored", "false");

@ -221,7 +221,7 @@ namespace NzbDrone.Integration.Test
result = Artist.Post(artist); result = Artist.Post(artist);
Commands.WaitAll(); Commands.WaitAll();
WaitForCompletion(() => Episodes.GetEpisodesInSeries(result.Id).Count > 0); WaitForCompletion(() => Tracks.GetTracksInArtist(result.Id).Count > 0);
} }
if (monitored.HasValue) if (monitored.HasValue)

@ -32,16 +32,16 @@ namespace NzbDrone.Test.Common
{ {
AppData = Path.Combine(TestContext.CurrentContext.TestDirectory, "_intg_" + DateTime.Now.Ticks); AppData = Path.Combine(TestContext.CurrentContext.TestDirectory, "_intg_" + DateTime.Now.Ticks);
var nzbdroneConsoleExe = "NzbDrone.Console.exe"; var nzbdroneConsoleExe = "Lidarr.Console.exe";
if (OsInfo.IsNotWindows) if (OsInfo.IsNotWindows)
{ {
nzbdroneConsoleExe = "NzbDrone.exe"; nzbdroneConsoleExe = "Lidarr.exe";
} }
if (BuildInfo.IsDebug) if (BuildInfo.IsDebug)
{ {
Start(Path.Combine(TestContext.CurrentContext.TestDirectory, "..\\..\\..\\..\\..\\_output\\NzbDrone.Console.exe")); Start(Path.Combine(TestContext.CurrentContext.TestDirectory, "..\\..\\..\\..\\..\\_output\\Lidarr.Console.exe"));
} }
else else
{ {

@ -34,7 +34,7 @@ namespace NzbDrone.Update.Test
[Test] [Test]
public void should_call_update_with_correct_path() public void should_call_update_with_correct_path()
{ {
var ProcessPath = @"C:\NzbDrone\nzbdrone.exe".AsOsAgnostic(); var ProcessPath = @"C:\NzbDrone\lidarr.exe".AsOsAgnostic();
Mocker.GetMock<IProcessProvider>().Setup(c => c.GetProcessById(12)) Mocker.GetMock<IProcessProvider>().Setup(c => c.GetProcessById(12))
.Returns(new ProcessInfo() { StartPath = ProcessPath }); .Returns(new ProcessInfo() { StartPath = ProcessPath });

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("NzbDrone.exe")] [assembly: AssemblyTitle("Lidarr.exe")]
[assembly: Guid("67AADCD9-89AA-4D95-8281-3193740E70E5")] [assembly: Guid("67AADCD9-89AA-4D95-8281-3193740E70E5")]
[assembly: AssemblyVersion("10.0.0.*")] [assembly: AssemblyVersion("10.0.0.*")]

@ -20,7 +20,7 @@ namespace ServiceInstall
{ {
if (!File.Exists(NzbDroneExe)) if (!File.Exists(NzbDroneExe))
{ {
Console.WriteLine("Unable to find NzbDrone.Console.exe in the current directory."); Console.WriteLine("Unable to find Lidarr.Console.exe in the current directory.");
return; return;
} }

@ -1,4 +1,4 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
@ -8,7 +8,7 @@ namespace ServiceUninstall
{ {
public static class ServiceHelper public static class ServiceHelper
{ {
private static string NzbDroneExe => Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "NzbDrone.Console.exe"); private static string NzbDroneExe => Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "Lidarr.Console.exe");
private static bool IsAnAdministrator() private static bool IsAnAdministrator()
{ {
@ -20,7 +20,7 @@ namespace ServiceUninstall
{ {
if (!File.Exists(NzbDroneExe)) if (!File.Exists(NzbDroneExe))
{ {
Console.WriteLine("Unable to find NzbDrone.exe in the current directory."); Console.WriteLine("Unable to find Lidarr.exe in the current directory.");
return; return;
} }

@ -61,7 +61,7 @@ var view = Marionette.ItemView.extend({
var defaultProfile = Config.getValue(Config.Keys.DefaultProfileId); var defaultProfile = Config.getValue(Config.Keys.DefaultProfileId);
var defaultRoot = Config.getValue(Config.Keys.DefaultRootFolderId); var defaultRoot = Config.getValue(Config.Keys.DefaultRootFolderId);
var useSeasonFolder = Config.getValueBoolean(Config.Keys.UseSeasonFolder, true); var useAlbumFolder = Config.getValueBoolean(Config.Keys.UseAlbumFolder, true);
var defaultArtistType = Config.getValue(Config.Keys.DefaultSeriesType, 'standard'); var defaultArtistType = Config.getValue(Config.Keys.DefaultSeriesType, 'standard');
var defaultMonitorEpisodes = Config.getValue(Config.Keys.MonitorEpisodes, 'missing'); var defaultMonitorEpisodes = Config.getValue(Config.Keys.MonitorEpisodes, 'missing');
@ -73,7 +73,7 @@ var view = Marionette.ItemView.extend({
this.ui.rootFolder.val(defaultRoot); this.ui.rootFolder.val(defaultRoot);
} }
this.ui.albumFolder.prop('checked', useSeasonFolder); this.ui.albumFolder.prop('checked', useAlbumFolder);
this.ui.artistType.val(defaultArtistType); this.ui.artistType.val(defaultArtistType);
this.ui.monitor.val(defaultMonitorEpisodes); this.ui.monitor.val(defaultMonitorEpisodes);

@ -55,7 +55,7 @@
<div class="input-group"> <div class="input-group">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input type="checkbox" class="x-season-folder"/> <input type="checkbox" class="x-album-folder"/>
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>

@ -17,7 +17,7 @@ module.exports = Marionette.ItemView.extend({
element : this.ui.refresh, element : this.ui.refresh,
command : { command : {
name : 'refreshArtist', name : 'refreshArtist',
seriesId : this.model.get('id') artistId : this.model.get('id')
} }
}); });
}, },
@ -29,7 +29,7 @@ module.exports = Marionette.ItemView.extend({
_refreshArtist : function() { _refreshArtist : function() {
CommandController.Execute('refreshArtist', { CommandController.Execute('refreshArtist', {
name : 'refreshArtist', name : 'refreshArtist',
seriesId : this.model.id artistId : this.model.id
}); });
} }
}); });
Loading…
Cancel
Save