mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-19 13:10:13 -07:00
Update Music Tests, Added Cases for Should Refresh Artist, Cleanup Skyhook Resources
This commit is contained in:
parent
d10fb92a09
commit
6e4638f7b1
19 changed files with 352 additions and 690 deletions
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
@ -7,7 +7,7 @@ using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.MetadataSource.SkyHook;
|
using NzbDrone.Core.MetadataSource.SkyHook;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Music;
|
||||||
using NzbDrone.Test.Common.Categories;
|
using NzbDrone.Test.Common.Categories;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
||||||
|
@ -22,88 +22,75 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
||||||
UseRealHttp();
|
UseRealHttp();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(75978, "Family Guy")]
|
[TestCase("f59c5520-5f46-4d2c-b2c4-822eabf53419", "Linkin Park")]
|
||||||
[TestCase(83462, "Castle (2009)")]
|
[TestCase("66c662b6-6e2f-4930-8610-912e24c63ed1", "AC/DC")]
|
||||||
[TestCase(266189, "The Blacklist")]
|
public void should_be_able_to_get_artist_detail(string mbId, string name)
|
||||||
public void should_be_able_to_get_series_detail(int tvdbId, string title)
|
|
||||||
{
|
{
|
||||||
var details = Subject.GetSeriesInfo(tvdbId);
|
var details = Subject.GetArtistInfo(mbId);
|
||||||
|
|
||||||
ValidateSeries(details.Item1);
|
ValidateArtist(details.Item1);
|
||||||
ValidateEpisodes(details.Item2);
|
ValidateAlbums(details.Item2);
|
||||||
|
|
||||||
details.Item1.Title.Should().Be(title);
|
details.Item1.Name.Should().Be(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void getting_details_of_invalid_series()
|
public void getting_details_of_invalid_artist()
|
||||||
{
|
{
|
||||||
Assert.Throws<SeriesNotFoundException>(() => Subject.GetSeriesInfo(int.MaxValue));
|
Assert.Throws<ArtistNotFoundException>(() => Subject.GetArtistInfo("aaaaaa-aaa-aaaa-aaaa"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_have_period_at_start_of_title_slug()
|
public void should_not_have_period_at_start_of_name_slug()
|
||||||
{
|
{
|
||||||
var details = Subject.GetSeriesInfo(79099);
|
var details = Subject.GetArtistInfo("f59c5520-5f46-4d2c-b2c4-822eabf53419");
|
||||||
|
|
||||||
details.Item1.TitleSlug.Should().Be("dothack");
|
details.Item1.NameSlug.Should().Be("dothack");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ValidateSeries(Series series)
|
private void ValidateArtist(Artist artist)
|
||||||
{
|
{
|
||||||
series.Should().NotBeNull();
|
artist.Should().NotBeNull();
|
||||||
series.Title.Should().NotBeNullOrWhiteSpace();
|
artist.Name.Should().NotBeNullOrWhiteSpace();
|
||||||
series.CleanTitle.Should().Be(Parser.Parser.CleanSeriesTitle(series.Title));
|
artist.CleanName.Should().Be(Parser.Parser.CleanSeriesTitle(artist.Name));
|
||||||
series.SortTitle.Should().Be(SeriesTitleNormalizer.Normalize(series.Title, series.TvdbId));
|
artist.SortName.Should().Be(Parser.Parser.NormalizeTitle(artist.Name));
|
||||||
series.Overview.Should().NotBeNullOrWhiteSpace();
|
artist.Overview.Should().NotBeNullOrWhiteSpace();
|
||||||
series.AirTime.Should().NotBeNullOrWhiteSpace();
|
artist.Images.Should().NotBeEmpty();
|
||||||
series.FirstAired.Should().HaveValue();
|
artist.NameSlug.Should().NotBeNullOrWhiteSpace();
|
||||||
series.FirstAired.Value.Kind.Should().Be(DateTimeKind.Utc);
|
|
||||||
series.Images.Should().NotBeEmpty();
|
|
||||||
series.ImdbId.Should().NotBeNullOrWhiteSpace();
|
|
||||||
series.Network.Should().NotBeNullOrWhiteSpace();
|
|
||||||
series.Runtime.Should().BeGreaterThan(0);
|
|
||||||
series.TitleSlug.Should().NotBeNullOrWhiteSpace();
|
|
||||||
//series.TvRageId.Should().BeGreaterThan(0);
|
//series.TvRageId.Should().BeGreaterThan(0);
|
||||||
series.TvdbId.Should().BeGreaterThan(0);
|
artist.ForeignArtistId.Should().NotBeNullOrWhiteSpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ValidateEpisodes(List<Episode> episodes)
|
private void ValidateAlbums(List<Album> albums)
|
||||||
{
|
{
|
||||||
episodes.Should().NotBeEmpty();
|
albums.Should().NotBeEmpty();
|
||||||
|
|
||||||
var episodeGroup = episodes.GroupBy(e => e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000"));
|
var episodeGroup = albums.GroupBy(e => e.AlbumType + e.Title);
|
||||||
episodeGroup.Should().OnlyContain(c => c.Count() == 1);
|
episodeGroup.Should().OnlyContain(c => c.Count() == 1);
|
||||||
|
|
||||||
|
|
||||||
episodes.Should().Contain(c => c.SeasonNumber > 0);
|
foreach (var episode in albums)
|
||||||
episodes.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Overview));
|
|
||||||
|
|
||||||
foreach (var episode in episodes)
|
|
||||||
{
|
{
|
||||||
ValidateEpisode(episode);
|
ValidateAlbum(episode);
|
||||||
|
|
||||||
//if atleast one episdoe has title it means parse it working.
|
//if atleast one album has title it means parse it working.
|
||||||
episodes.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Title));
|
albums.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Title));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ValidateEpisode(Episode episode)
|
private void ValidateAlbum(Album album)
|
||||||
{
|
{
|
||||||
episode.Should().NotBeNull();
|
album.Should().NotBeNull();
|
||||||
|
|
||||||
|
album.Title.Should().NotBeNullOrWhiteSpace();
|
||||||
|
album.AlbumType.Should().NotBeNullOrWhiteSpace();
|
||||||
|
|
||||||
//TODO: Is there a better way to validate that episode number or season number is greater than zero?
|
album.Should().NotBeNull();
|
||||||
(episode.EpisodeNumber + episode.SeasonNumber).Should().NotBe(0);
|
|
||||||
|
|
||||||
episode.Should().NotBeNull();
|
if (album.ReleaseDate.HasValue)
|
||||||
|
|
||||||
if (episode.AirDateUtc.HasValue)
|
|
||||||
{
|
{
|
||||||
episode.AirDateUtc.Value.Kind.Should().Be(DateTimeKind.Utc);
|
album.ReleaseDate.Value.Kind.Should().Be(DateTimeKind.Utc);
|
||||||
}
|
}
|
||||||
|
|
||||||
episode.Images.Any(i => i.CoverType == MediaCoverTypes.Screenshot && i.Url.Contains("-940."))
|
|
||||||
.Should()
|
|
||||||
.BeFalse();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
140
src/NzbDrone.Core.Test/MusicTests/RefreshArtistServiceFixture.cs
Normal file
140
src/NzbDrone.Core.Test/MusicTests/RefreshArtistServiceFixture.cs
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.MetadataSource;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Music;
|
||||||
|
using NzbDrone.Core.Music.Commands;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MusicTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class RefreshArtistServiceFixture : CoreTest<RefreshArtistService>
|
||||||
|
{
|
||||||
|
private Artist _artist;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
var season1 = Builder<Album>.CreateNew()
|
||||||
|
.With(s => s.ForeignAlbumId = "1")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_artist = Builder<Artist>.CreateNew()
|
||||||
|
.With(s => s.Albums = new List<Album>
|
||||||
|
{
|
||||||
|
season1
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<IArtistService>()
|
||||||
|
.Setup(s => s.GetArtist(_artist.Id))
|
||||||
|
.Returns(_artist);
|
||||||
|
|
||||||
|
Mocker.GetMock<IProvideArtistInfo>()
|
||||||
|
.Setup(s => s.GetArtistInfo(It.IsAny<string>()))
|
||||||
|
.Callback<string>(p => { throw new ArtistNotFoundException(p); });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenNewArtistInfo(Artist artist)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IProvideArtistInfo>()
|
||||||
|
.Setup(s => s.GetArtistInfo(_artist.ForeignArtistId))
|
||||||
|
.Returns(new Tuple<Artist, List<Album>>(artist, new List<Album>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_monitor_new_albums_automatically()
|
||||||
|
{
|
||||||
|
var newArtistInfo = _artist.JsonClone();
|
||||||
|
newArtistInfo.Albums.Add(Builder<Album>.CreateNew()
|
||||||
|
.With(s => s.ForeignAlbumId = "2")
|
||||||
|
.Build());
|
||||||
|
|
||||||
|
GivenNewArtistInfo(newArtistInfo);
|
||||||
|
|
||||||
|
Subject.Execute(new RefreshArtistCommand(_artist.Id));
|
||||||
|
|
||||||
|
Mocker.GetMock<IArtistService>()
|
||||||
|
.Verify(v => v.UpdateArtist(It.Is<Artist>(s => s.Albums.Count == 2 && s.Albums.Single(season => season.ForeignAlbumId == "2").Monitored == true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_log_error_if_musicbrainz_id_not_found()
|
||||||
|
{
|
||||||
|
Subject.Execute(new RefreshArtistCommand(_artist.Id));
|
||||||
|
|
||||||
|
Mocker.GetMock<IArtistService>()
|
||||||
|
.Verify(v => v.UpdateArtist(It.IsAny<Artist>()), Times.Never());
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedErrors(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_update_if_musicbrainz_id_changed()
|
||||||
|
{
|
||||||
|
var newArtistInfo = _artist.JsonClone();
|
||||||
|
newArtistInfo.ForeignArtistId = _artist.ForeignArtistId + 1;
|
||||||
|
|
||||||
|
GivenNewArtistInfo(newArtistInfo);
|
||||||
|
|
||||||
|
Subject.Execute(new RefreshArtistCommand(_artist.Id));
|
||||||
|
|
||||||
|
Mocker.GetMock<IArtistService>()
|
||||||
|
.Verify(v => v.UpdateArtist(It.Is<Artist>(s => s.ForeignArtistId == newArtistInfo.ForeignArtistId)));
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_throw_if_duplicate_album_is_in_existing_info()
|
||||||
|
{
|
||||||
|
var newArtistInfo = _artist.JsonClone();
|
||||||
|
newArtistInfo.Albums.Add(Builder<Album>.CreateNew()
|
||||||
|
.With(s => s.ForeignAlbumId = "2")
|
||||||
|
.Build());
|
||||||
|
|
||||||
|
_artist.Albums.Add(Builder<Album>.CreateNew()
|
||||||
|
.With(s => s.ForeignAlbumId = "2")
|
||||||
|
.Build());
|
||||||
|
|
||||||
|
_artist.Albums.Add(Builder<Album>.CreateNew()
|
||||||
|
.With(s => s.ForeignAlbumId = "2")
|
||||||
|
.Build());
|
||||||
|
|
||||||
|
GivenNewArtistInfo(newArtistInfo);
|
||||||
|
|
||||||
|
Subject.Execute(new RefreshArtistCommand(_artist.Id));
|
||||||
|
|
||||||
|
Mocker.GetMock<IArtistService>()
|
||||||
|
.Verify(v => v.UpdateArtist(It.Is<Artist>(s => s.Albums.Count == 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_filter_duplicate_albums()
|
||||||
|
{
|
||||||
|
var newArtistInfo = _artist.JsonClone();
|
||||||
|
newArtistInfo.Albums.Add(Builder<Album>.CreateNew()
|
||||||
|
.With(s => s.ForeignAlbumId = "2")
|
||||||
|
.Build());
|
||||||
|
|
||||||
|
newArtistInfo.Albums.Add(Builder<Album>.CreateNew()
|
||||||
|
.With(s => s.ForeignAlbumId = "2")
|
||||||
|
.Build());
|
||||||
|
|
||||||
|
GivenNewArtistInfo(newArtistInfo);
|
||||||
|
|
||||||
|
Subject.Execute(new RefreshArtistCommand(_artist.Id));
|
||||||
|
|
||||||
|
Mocker.GetMock<IArtistService>()
|
||||||
|
.Verify(v => v.UpdateArtist(It.Is<Artist>(s => s.Albums.Count == 2)));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
135
src/NzbDrone.Core.Test/MusicTests/ShouldRefreshArtistFixture.cs
Normal file
135
src/NzbDrone.Core.Test/MusicTests/ShouldRefreshArtistFixture.cs
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Music;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MusicTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ShouldRefreshArtistFixture : TestBase<ShouldRefreshArtist>
|
||||||
|
{
|
||||||
|
private Artist _artist;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_artist = Builder<Artist>.CreateNew()
|
||||||
|
.With(v => v.Status == ArtistStatusType.Continuing)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<IAlbumService>()
|
||||||
|
.Setup(s => s.GetAlbumsByArtist(_artist.Id))
|
||||||
|
.Returns(Builder<Album>.CreateListOfSize(2)
|
||||||
|
.All()
|
||||||
|
.With(e => e.ReleaseDate = DateTime.Today.AddDays(-100))
|
||||||
|
.Build()
|
||||||
|
.ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenArtistIsEnded()
|
||||||
|
{
|
||||||
|
_artist.Status = ArtistStatusType.Ended;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenArtistLastRefreshedMonthsAgo()
|
||||||
|
{
|
||||||
|
_artist.LastInfoSync = DateTime.UtcNow.AddDays(-90);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenArtistLastRefreshedYesterday()
|
||||||
|
{
|
||||||
|
_artist.LastInfoSync = DateTime.UtcNow.AddDays(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenArtistLastRefreshedHalfADayAgo()
|
||||||
|
{
|
||||||
|
_artist.LastInfoSync = DateTime.UtcNow.AddHours(-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenArtistLastRefreshedRecently()
|
||||||
|
{
|
||||||
|
_artist.LastInfoSync = DateTime.UtcNow.AddHours(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenRecentlyAired()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IAlbumService>()
|
||||||
|
.Setup(s => s.GetAlbumsByArtist(_artist.Id))
|
||||||
|
.Returns(Builder<Album>.CreateListOfSize(2)
|
||||||
|
.TheFirst(1)
|
||||||
|
.With(e => e.ReleaseDate = DateTime.Today.AddDays(-7))
|
||||||
|
.TheLast(1)
|
||||||
|
.With(e => e.ReleaseDate = DateTime.Today.AddDays(-100))
|
||||||
|
.Build()
|
||||||
|
.ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_if_running_artist_last_refreshed_more_than_6_hours_ago()
|
||||||
|
{
|
||||||
|
GivenArtistLastRefreshedHalfADayAgo();
|
||||||
|
|
||||||
|
Subject.ShouldRefresh(_artist).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_running_artist_last_refreshed_less_than_6_hours_ago()
|
||||||
|
{
|
||||||
|
GivenArtistLastRefreshedRecently();
|
||||||
|
|
||||||
|
Subject.ShouldRefresh(_artist).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_ended_artist_last_refreshed_yesterday()
|
||||||
|
{
|
||||||
|
GivenArtistIsEnded();
|
||||||
|
GivenArtistLastRefreshedYesterday();
|
||||||
|
|
||||||
|
Subject.ShouldRefresh(_artist).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_if_artist_last_refreshed_more_than_30_days_ago()
|
||||||
|
{
|
||||||
|
GivenArtistIsEnded();
|
||||||
|
GivenArtistLastRefreshedMonthsAgo();
|
||||||
|
|
||||||
|
Subject.ShouldRefresh(_artist).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_if_album_released_in_last_30_days()
|
||||||
|
{
|
||||||
|
GivenArtistIsEnded();
|
||||||
|
GivenArtistLastRefreshedYesterday();
|
||||||
|
|
||||||
|
GivenRecentlyAired();
|
||||||
|
|
||||||
|
Subject.ShouldRefresh(_artist).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_when_recently_refreshed_ended_show_has_not_aired_for_30_days()
|
||||||
|
{
|
||||||
|
GivenArtistIsEnded();
|
||||||
|
GivenArtistLastRefreshedYesterday();
|
||||||
|
|
||||||
|
Subject.ShouldRefresh(_artist).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_when_recently_refreshed_ended_show_aired_in_last_30_days()
|
||||||
|
{
|
||||||
|
GivenArtistIsEnded();
|
||||||
|
GivenArtistLastRefreshedRecently();
|
||||||
|
|
||||||
|
GivenRecentlyAired();
|
||||||
|
|
||||||
|
Subject.ShouldRefresh(_artist).Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -365,13 +365,13 @@
|
||||||
<Compile Include="TvTests\EpisodeRepositoryTests\FindEpisodeFixture.cs" />
|
<Compile Include="TvTests\EpisodeRepositoryTests\FindEpisodeFixture.cs" />
|
||||||
<Compile Include="MusicTests\MoveArtistServiceFixture.cs" />
|
<Compile Include="MusicTests\MoveArtistServiceFixture.cs" />
|
||||||
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />
|
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />
|
||||||
<Compile Include="TvTests\RefreshSeriesServiceFixture.cs" />
|
<Compile Include="MusicTests\RefreshArtistServiceFixture.cs" />
|
||||||
<Compile Include="TvTests\EpisodeMonitoredServiceTests\SetEpisodeMontitoredFixture.cs" />
|
<Compile Include="TvTests\EpisodeMonitoredServiceTests\SetEpisodeMontitoredFixture.cs" />
|
||||||
<Compile Include="TvTests\SeriesRepositoryTests\SeriesRepositoryFixture.cs" />
|
<Compile Include="TvTests\SeriesRepositoryTests\SeriesRepositoryFixture.cs" />
|
||||||
<Compile Include="TvTests\SeriesServiceTests\UpdateMultipleSeriesFixture.cs" />
|
<Compile Include="TvTests\SeriesServiceTests\UpdateMultipleSeriesFixture.cs" />
|
||||||
<Compile Include="TvTests\SeriesServiceTests\UpdateSeriesFixture.cs" />
|
<Compile Include="TvTests\SeriesServiceTests\UpdateSeriesFixture.cs" />
|
||||||
<Compile Include="TvTests\SeriesTitleNormalizerFixture.cs" />
|
<Compile Include="TvTests\SeriesTitleNormalizerFixture.cs" />
|
||||||
<Compile Include="TvTests\ShouldRefreshSeriesFixture.cs" />
|
<Compile Include="MusicTests\ShouldRefreshArtistFixture.cs" />
|
||||||
<Compile Include="UpdateTests\UpdatePackageProviderFixture.cs" />
|
<Compile Include="UpdateTests\UpdatePackageProviderFixture.cs" />
|
||||||
<Compile Include="UpdateTests\UpdateServiceFixture.cs" />
|
<Compile Include="UpdateTests\UpdateServiceFixture.cs" />
|
||||||
<Compile Include="XbmcVersionTests.cs" />
|
<Compile Include="XbmcVersionTests.cs" />
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
|
@ -25,7 +25,7 @@ namespace NzbDrone.Core.Test.TvTests
|
||||||
{
|
{
|
||||||
UseRealHttp();
|
UseRealHttp();
|
||||||
|
|
||||||
_gameOfThrones = Mocker.Resolve<SkyHookProxy>().GetSeriesInfo(121361);//Game of thrones
|
// _gameOfThrones = Mocker.Resolve<SkyHookProxy>().GetSeriesInfo(121361);//Game of thrones
|
||||||
|
|
||||||
// Remove specials.
|
// Remove specials.
|
||||||
_gameOfThrones.Item2.RemoveAll(v => v.SeasonNumber == 0);
|
_gameOfThrones.Item2.RemoveAll(v => v.SeasonNumber == 0);
|
||||||
|
@ -394,4 +394,4 @@ namespace NzbDrone.Core.Test.TvTests
|
||||||
_updatedEpisodes.First().AbsoluteEpisodeNumber.Should().Be(episodes[1].AbsoluteEpisodeNumber);
|
_updatedEpisodes.First().AbsoluteEpisodeNumber.Should().Be(episodes[1].AbsoluteEpisodeNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,184 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using FizzWare.NBuilder;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Core.Exceptions;
|
|
||||||
using NzbDrone.Core.MetadataSource;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Core.Tv.Commands;
|
|
||||||
using NzbDrone.Test.Common;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.TvTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class RefreshSeriesServiceFixture : CoreTest<RefreshSeriesService>
|
|
||||||
{
|
|
||||||
private Series _series;
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
var season1 = Builder<Season>.CreateNew()
|
|
||||||
.With(s => s.SeasonNumber = 1)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_series = Builder<Series>.CreateNew()
|
|
||||||
.With(s => s.Seasons = new List<Season>
|
|
||||||
{
|
|
||||||
season1
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Setup(s => s.GetSeries(_series.Id))
|
|
||||||
.Returns(_series);
|
|
||||||
|
|
||||||
Mocker.GetMock<IProvideSeriesInfo>()
|
|
||||||
.Setup(s => s.GetSeriesInfo(It.IsAny<int>()))
|
|
||||||
.Callback<int>(p => { throw new SeriesNotFoundException(p); });
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenNewSeriesInfo(Series series)
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IProvideSeriesInfo>()
|
|
||||||
.Setup(s => s.GetSeriesInfo(_series.TvdbId))
|
|
||||||
.Returns(new Tuple<Series, List<Episode>>(series, new List<Episode>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_monitor_new_seasons_automatically()
|
|
||||||
{
|
|
||||||
var newSeriesInfo = _series.JsonClone();
|
|
||||||
newSeriesInfo.Seasons.Add(Builder<Season>.CreateNew()
|
|
||||||
.With(s => s.SeasonNumber = 2)
|
|
||||||
.Build());
|
|
||||||
|
|
||||||
GivenNewSeriesInfo(newSeriesInfo);
|
|
||||||
|
|
||||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 2).Monitored == true)));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_monitor_new_special_season_automatically()
|
|
||||||
{
|
|
||||||
var series = _series.JsonClone();
|
|
||||||
series.Seasons.Add(Builder<Season>.CreateNew()
|
|
||||||
.With(s => s.SeasonNumber = 0)
|
|
||||||
.Build());
|
|
||||||
|
|
||||||
GivenNewSeriesInfo(series);
|
|
||||||
|
|
||||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 0).Monitored == false)));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_update_tvrage_id_if_changed()
|
|
||||||
{
|
|
||||||
var newSeriesInfo = _series.JsonClone();
|
|
||||||
newSeriesInfo.TvRageId = _series.TvRageId + 1;
|
|
||||||
|
|
||||||
GivenNewSeriesInfo(newSeriesInfo);
|
|
||||||
|
|
||||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.TvRageId == newSeriesInfo.TvRageId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_update_tvmaze_id_if_changed()
|
|
||||||
{
|
|
||||||
var newSeriesInfo = _series.JsonClone();
|
|
||||||
newSeriesInfo.TvMazeId = _series.TvMazeId + 1;
|
|
||||||
|
|
||||||
GivenNewSeriesInfo(newSeriesInfo);
|
|
||||||
|
|
||||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.TvMazeId == newSeriesInfo.TvMazeId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_log_error_if_tvdb_id_not_found()
|
|
||||||
{
|
|
||||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
|
||||||
|
|
||||||
ExceptionVerification.ExpectedErrors(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_update_if_tvdb_id_changed()
|
|
||||||
{
|
|
||||||
var newSeriesInfo = _series.JsonClone();
|
|
||||||
newSeriesInfo.TvdbId = _series.TvdbId + 1;
|
|
||||||
|
|
||||||
GivenNewSeriesInfo(newSeriesInfo);
|
|
||||||
|
|
||||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.TvdbId == newSeriesInfo.TvdbId)));
|
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_throw_if_duplicate_season_is_in_existing_info()
|
|
||||||
{
|
|
||||||
var newSeriesInfo = _series.JsonClone();
|
|
||||||
newSeriesInfo.Seasons.Add(Builder<Season>.CreateNew()
|
|
||||||
.With(s => s.SeasonNumber = 2)
|
|
||||||
.Build());
|
|
||||||
|
|
||||||
_series.Seasons.Add(Builder<Season>.CreateNew()
|
|
||||||
.With(s => s.SeasonNumber = 2)
|
|
||||||
.Build());
|
|
||||||
|
|
||||||
_series.Seasons.Add(Builder<Season>.CreateNew()
|
|
||||||
.With(s => s.SeasonNumber = 2)
|
|
||||||
.Build());
|
|
||||||
|
|
||||||
GivenNewSeriesInfo(newSeriesInfo);
|
|
||||||
|
|
||||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Seasons.Count == 2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_filter_duplicate_seasons()
|
|
||||||
{
|
|
||||||
var newSeriesInfo = _series.JsonClone();
|
|
||||||
newSeriesInfo.Seasons.Add(Builder<Season>.CreateNew()
|
|
||||||
.With(s => s.SeasonNumber = 2)
|
|
||||||
.Build());
|
|
||||||
|
|
||||||
newSeriesInfo.Seasons.Add(Builder<Season>.CreateNew()
|
|
||||||
.With(s => s.SeasonNumber = 2)
|
|
||||||
.Build());
|
|
||||||
|
|
||||||
GivenNewSeriesInfo(newSeriesInfo);
|
|
||||||
|
|
||||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Seasons.Count == 2)));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using FizzWare.NBuilder;
|
|
||||||
using FluentAssertions;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Test.Common;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.TvTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class ShouldRefreshSeriesFixture : TestBase<ShouldRefreshSeries>
|
|
||||||
{
|
|
||||||
private Series _series;
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
_series = Builder<Series>.CreateNew()
|
|
||||||
.With(v => v.Status == SeriesStatusType.Continuing)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
|
||||||
.Setup(s => s.GetEpisodeBySeries(_series.Id))
|
|
||||||
.Returns(Builder<Episode>.CreateListOfSize(2)
|
|
||||||
.All()
|
|
||||||
.With(e => e.AirDateUtc = DateTime.Today.AddDays(-100))
|
|
||||||
.Build()
|
|
||||||
.ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenSeriesIsEnded()
|
|
||||||
{
|
|
||||||
_series.Status = SeriesStatusType.Ended;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenSeriesLastRefreshedMonthsAgo()
|
|
||||||
{
|
|
||||||
_series.LastInfoSync = DateTime.UtcNow.AddDays(-90);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenSeriesLastRefreshedYesterday()
|
|
||||||
{
|
|
||||||
_series.LastInfoSync = DateTime.UtcNow.AddDays(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenSeriesLastRefreshedHalfADayAgo()
|
|
||||||
{
|
|
||||||
_series.LastInfoSync = DateTime.UtcNow.AddHours(-12);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenSeriesLastRefreshedRecently()
|
|
||||||
{
|
|
||||||
_series.LastInfoSync = DateTime.UtcNow.AddHours(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenRecentlyAired()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
|
||||||
.Setup(s => s.GetEpisodeBySeries(_series.Id))
|
|
||||||
.Returns(Builder<Episode>.CreateListOfSize(2)
|
|
||||||
.TheFirst(1)
|
|
||||||
.With(e => e.AirDateUtc = DateTime.Today.AddDays(-7))
|
|
||||||
.TheLast(1)
|
|
||||||
.With(e => e.AirDateUtc = DateTime.Today.AddDays(-100))
|
|
||||||
.Build()
|
|
||||||
.ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_true_if_running_series_last_refreshed_more_than_6_hours_ago()
|
|
||||||
{
|
|
||||||
GivenSeriesLastRefreshedHalfADayAgo();
|
|
||||||
|
|
||||||
Subject.ShouldRefresh(_series).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_false_if_running_series_last_refreshed_less_than_6_hours_ago()
|
|
||||||
{
|
|
||||||
GivenSeriesLastRefreshedRecently();
|
|
||||||
|
|
||||||
Subject.ShouldRefresh(_series).Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_false_if_ended_series_last_refreshed_yesterday()
|
|
||||||
{
|
|
||||||
GivenSeriesIsEnded();
|
|
||||||
GivenSeriesLastRefreshedYesterday();
|
|
||||||
|
|
||||||
Subject.ShouldRefresh(_series).Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_true_if_series_last_refreshed_more_than_30_days_ago()
|
|
||||||
{
|
|
||||||
GivenSeriesIsEnded();
|
|
||||||
GivenSeriesLastRefreshedMonthsAgo();
|
|
||||||
|
|
||||||
Subject.ShouldRefresh(_series).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_true_if_episode_aired_in_last_30_days()
|
|
||||||
{
|
|
||||||
GivenSeriesIsEnded();
|
|
||||||
GivenSeriesLastRefreshedYesterday();
|
|
||||||
|
|
||||||
GivenRecentlyAired();
|
|
||||||
|
|
||||||
Subject.ShouldRefresh(_series).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_false_when_recently_refreshed_ended_show_has_not_aired_for_30_days()
|
|
||||||
{
|
|
||||||
GivenSeriesIsEnded();
|
|
||||||
GivenSeriesLastRefreshedYesterday();
|
|
||||||
|
|
||||||
Subject.ShouldRefresh(_series).Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_false_when_recently_refreshed_ended_show_aired_in_last_30_days()
|
|
||||||
{
|
|
||||||
GivenSeriesIsEnded();
|
|
||||||
GivenSeriesLastRefreshedRecently();
|
|
||||||
|
|
||||||
GivenRecentlyAired();
|
|
||||||
|
|
||||||
Subject.ShouldRefresh(_series).Should().BeFalse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource
|
|
||||||
{
|
|
||||||
public interface IProvideSeriesInfo
|
|
||||||
{
|
|
||||||
Tuple<Series, List<Episode>> GetSeriesInfo(int tvdbSeriesId);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|
||||||
{
|
|
||||||
public class ArtistInfoResource
|
|
||||||
{
|
|
||||||
public ArtistInfoResource() { }
|
|
||||||
|
|
||||||
public List<string> Genres { get; set; }
|
|
||||||
public string AristUrl { get; set; }
|
|
||||||
public string Overview { get; set; }
|
|
||||||
public string Id { get; set; }
|
|
||||||
public List<ImageResource> Images { get; set; }
|
|
||||||
public string ArtistName { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|
||||||
{
|
|
||||||
public class EpisodeResource
|
|
||||||
{
|
|
||||||
public int SeasonNumber { get; set; }
|
|
||||||
public int EpisodeNumber { get; set; }
|
|
||||||
public int? AbsoluteEpisodeNumber { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public string AirDate { get; set; }
|
|
||||||
public DateTime? AirDateUtc { get; set; }
|
|
||||||
public RatingResource Rating { get; set; }
|
|
||||||
public string Overview { get; set; }
|
|
||||||
public string Image { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
||||||
{
|
{
|
||||||
public class ActorResource
|
public class MemberResource
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Character { get; set; }
|
public string Instrument { get; set; }
|
||||||
public string Image { get; set; }
|
public string Image { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|
||||||
{
|
|
||||||
public class SeasonResource
|
|
||||||
{
|
|
||||||
public SeasonResource()
|
|
||||||
{
|
|
||||||
Images = new List<ImageResource>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int SeasonNumber { get; set; }
|
|
||||||
public List<ImageResource> Images { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|
||||||
{
|
|
||||||
public class ShowResource
|
|
||||||
{
|
|
||||||
public ShowResource()
|
|
||||||
{
|
|
||||||
Actors = new List<ActorResource>();
|
|
||||||
Genres = new List<string>();
|
|
||||||
Images = new List<ImageResource>();
|
|
||||||
Seasons = new List<SeasonResource>();
|
|
||||||
Episodes = new List<EpisodeResource>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int TvdbId { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public string Overview { get; set; }
|
|
||||||
//public string Language { get; set; }
|
|
||||||
public string Slug { get; set; }
|
|
||||||
public string FirstAired { get; set; }
|
|
||||||
public int? TvRageId { get; set; }
|
|
||||||
public int? TvMazeId { get; set; }
|
|
||||||
|
|
||||||
public string Status { get; set; }
|
|
||||||
public int? Runtime { get; set; }
|
|
||||||
public TimeOfDayResource TimeOfDay { get; set; }
|
|
||||||
|
|
||||||
public string Network { get; set; }
|
|
||||||
public string ImdbId { get; set; }
|
|
||||||
|
|
||||||
public List<ActorResource> Actors { get; set; }
|
|
||||||
public List<string> Genres { get; set; }
|
|
||||||
|
|
||||||
public string ContentRating { get; set; }
|
|
||||||
|
|
||||||
public RatingResource Rating { get; set; }
|
|
||||||
|
|
||||||
public List<ImageResource> Images { get; set; }
|
|
||||||
public List<SeasonResource> Seasons { get; set; }
|
|
||||||
public List<EpisodeResource> Episodes { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@ using NzbDrone.Core.Configuration;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook
|
namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
{
|
{
|
||||||
public class SkyHookProxy : IProvideSeriesInfo, IProvideArtistInfo, ISearchForNewArtist
|
public class SkyHookProxy : IProvideArtistInfo, ISearchForNewArtist
|
||||||
{
|
{
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
@ -37,12 +37,6 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Used for Sonarr, not Lidarr")]
|
|
||||||
public Tuple<Series, List<Episode>> GetSeriesInfo(int tvdbSeriesId)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tuple<Artist, List<Album>> GetArtistInfo(string foreignArtistId)
|
public Tuple<Artist, List<Album>> GetArtistInfo(string foreignArtistId)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -191,23 +185,23 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
return artist;
|
return artist;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Actor MapActors(ActorResource arg)
|
private static Member MapMembers(MemberResource arg)
|
||||||
{
|
{
|
||||||
var newActor = new Actor
|
var newMember = new Member
|
||||||
{
|
{
|
||||||
Name = arg.Name,
|
Name = arg.Name,
|
||||||
Character = arg.Character
|
Instrument = arg.Instrument
|
||||||
};
|
};
|
||||||
|
|
||||||
if (arg.Image != null)
|
if (arg.Image != null)
|
||||||
{
|
{
|
||||||
newActor.Images = new List<MediaCover.MediaCover>
|
newMember.Images = new List<MediaCover.MediaCover>
|
||||||
{
|
{
|
||||||
new MediaCover.MediaCover(MediaCoverTypes.Headshot, arg.Image)
|
new MediaCover.MediaCover(MediaCoverTypes.Headshot, arg.Image)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return newActor;
|
return newMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ArtistStatusType MapArtistStatus(string status)
|
private static ArtistStatusType MapArtistStatus(string status)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -11,14 +11,14 @@ namespace NzbDrone.Core.Music
|
||||||
bool ShouldRefresh(Artist artist);
|
bool ShouldRefresh(Artist artist);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CheckIfArtistShouldBeRefreshed : ICheckIfArtistShouldBeRefreshed
|
public class ShouldRefreshArtist : ICheckIfArtistShouldBeRefreshed
|
||||||
{
|
{
|
||||||
private readonly ITrackService _trackService;
|
private readonly IAlbumService _albumService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public CheckIfArtistShouldBeRefreshed(ITrackService trackService, Logger logger)
|
public ShouldRefreshArtist(IAlbumService albumService, Logger logger)
|
||||||
{
|
{
|
||||||
_trackService = trackService;
|
_albumService = albumService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,21 @@ namespace NzbDrone.Core.Music
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//_logger.Trace("Artist {0} ended long ago, should not be refreshed.", artist.Title);
|
if (artist.Status == ArtistStatusType.Continuing)
|
||||||
|
{
|
||||||
|
_logger.Trace("Artist {0} is continuing, should refresh.", artist.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastAlbum = _albumService.GetAlbumsByArtist(artist.Id).OrderByDescending(e => e.ReleaseDate).FirstOrDefault();
|
||||||
|
|
||||||
|
if (lastAlbum != null && lastAlbum.ReleaseDate > DateTime.UtcNow.AddDays(-30))
|
||||||
|
{
|
||||||
|
_logger.Trace("Last album in {0} aired less than 30 days ago, should refresh.", artist.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Trace("Artist {0} ended long ago, should not be refreshed.", artist.Name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -828,18 +828,13 @@
|
||||||
<Compile Include="Messaging\Events\IHandle.cs" />
|
<Compile Include="Messaging\Events\IHandle.cs" />
|
||||||
<Compile Include="Messaging\IProcessMessage.cs" />
|
<Compile Include="Messaging\IProcessMessage.cs" />
|
||||||
<Compile Include="MetadataSource\IProvideArtistInfo.cs" />
|
<Compile Include="MetadataSource\IProvideArtistInfo.cs" />
|
||||||
<Compile Include="MetadataSource\IProvideSeriesInfo.cs" />
|
|
||||||
<Compile Include="MetadataSource\ISearchForNewArtist.cs" />
|
<Compile Include="MetadataSource\ISearchForNewArtist.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ActorResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\MemberResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\AlbumResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\AlbumResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ArtistInfoResource.cs" />
|
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ArtistResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\ArtistResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\LinkResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\LinkResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\EpisodeResource.cs" />
|
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ImageResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\ImageResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\RatingResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\RatingResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\SeasonResource.cs" />
|
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ShowResource.cs" />
|
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\TimeOfDayResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\TimeOfDayResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\TrackResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\TrackResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\SkyHookProxy.cs" />
|
<Compile Include="MetadataSource\SkyHook\SkyHookProxy.cs" />
|
||||||
|
@ -1191,7 +1186,6 @@
|
||||||
<Compile Include="Tv\SeriesTitleNormalizer.cs" />
|
<Compile Include="Tv\SeriesTitleNormalizer.cs" />
|
||||||
<Compile Include="Tv\SeriesTitleSlugValidator.cs" />
|
<Compile Include="Tv\SeriesTitleSlugValidator.cs" />
|
||||||
<Compile Include="Tv\SeriesTypes.cs" />
|
<Compile Include="Tv\SeriesTypes.cs" />
|
||||||
<Compile Include="Tv\ShouldRefreshSeries.cs" />
|
|
||||||
<Compile Include="Update\Commands\ApplicationUpdateCommand.cs" />
|
<Compile Include="Update\Commands\ApplicationUpdateCommand.cs" />
|
||||||
<Compile Include="Update\InstallUpdateService.cs" />
|
<Compile Include="Update\InstallUpdateService.cs" />
|
||||||
<Compile Include="Update\RecentUpdateProvider.cs" />
|
<Compile Include="Update\RecentUpdateProvider.cs" />
|
||||||
|
|
|
@ -16,25 +16,21 @@ namespace NzbDrone.Core.Tv
|
||||||
public interface IAddSeriesService
|
public interface IAddSeriesService
|
||||||
{
|
{
|
||||||
Series AddSeries(Series newSeries);
|
Series AddSeries(Series newSeries);
|
||||||
List<Series> AddSeries(List<Series> newSeries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AddSeriesService : IAddSeriesService
|
public class AddSeriesService : IAddSeriesService
|
||||||
{
|
{
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
private readonly IProvideSeriesInfo _seriesInfo;
|
|
||||||
private readonly IBuildFileNames _fileNameBuilder;
|
private readonly IBuildFileNames _fileNameBuilder;
|
||||||
private readonly IAddSeriesValidator _addSeriesValidator;
|
private readonly IAddSeriesValidator _addSeriesValidator;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public AddSeriesService(ISeriesService seriesService,
|
public AddSeriesService(ISeriesService seriesService,
|
||||||
IProvideSeriesInfo seriesInfo,
|
|
||||||
IBuildFileNames fileNameBuilder,
|
IBuildFileNames fileNameBuilder,
|
||||||
IAddSeriesValidator addSeriesValidator,
|
IAddSeriesValidator addSeriesValidator,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
_seriesInfo = seriesInfo;
|
|
||||||
_fileNameBuilder = fileNameBuilder;
|
_fileNameBuilder = fileNameBuilder;
|
||||||
_addSeriesValidator = addSeriesValidator;
|
_addSeriesValidator = addSeriesValidator;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -44,7 +40,6 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
Ensure.That(newSeries, () => newSeries).IsNotNull();
|
Ensure.That(newSeries, () => newSeries).IsNotNull();
|
||||||
|
|
||||||
newSeries = AddSkyhookData(newSeries);
|
|
||||||
newSeries = SetPropertiesAndValidate(newSeries);
|
newSeries = SetPropertiesAndValidate(newSeries);
|
||||||
|
|
||||||
_logger.Info("Adding Series {0} Path: [{1}]", newSeries, newSeries.Path);
|
_logger.Info("Adding Series {0} Path: [{1}]", newSeries, newSeries.Path);
|
||||||
|
@ -53,50 +48,6 @@ namespace NzbDrone.Core.Tv
|
||||||
return newSeries;
|
return newSeries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Series> AddSeries(List<Series> newSeries)
|
|
||||||
{
|
|
||||||
var added = DateTime.UtcNow;
|
|
||||||
var seriesToAdd = new List<Series>();
|
|
||||||
foreach (var s in newSeries)
|
|
||||||
{
|
|
||||||
// TODO: Verify if adding skyhook data will be slow
|
|
||||||
var series = AddSkyhookData(s);
|
|
||||||
series = SetPropertiesAndValidate(series);
|
|
||||||
series.Added = added;
|
|
||||||
seriesToAdd.Add(series);
|
|
||||||
}
|
|
||||||
return _seriesService.AddSeries(seriesToAdd);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Series AddSkyhookData(Series newSeries)
|
|
||||||
{
|
|
||||||
Tuple<Series, List<Episode>> tuple;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tuple = _seriesInfo.GetSeriesInfo(newSeries.TvdbId);
|
|
||||||
}
|
|
||||||
catch (SeriesNotFoundException)
|
|
||||||
{
|
|
||||||
_logger.Error("tvdbid {1} was not found, it may have been removed from TheTVDB.", newSeries.TvdbId);
|
|
||||||
|
|
||||||
throw new ValidationException(new List<ValidationFailure>
|
|
||||||
{
|
|
||||||
new ValidationFailure("TvdbId", "A series with this ID was not found", newSeries.TvdbId)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var series = tuple.Item1;
|
|
||||||
|
|
||||||
// If seasons were passed in on the new series use them, otherwise use the seasons from Skyhook
|
|
||||||
newSeries.Seasons = newSeries.Seasons != null && newSeries.Seasons.Any() ? newSeries.Seasons : series.Seasons;
|
|
||||||
|
|
||||||
series.ApplyChanges(newSeries);
|
|
||||||
|
|
||||||
return series;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Series SetPropertiesAndValidate(Series newSeries)
|
private Series SetPropertiesAndValidate(Series newSeries)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(newSeries.Path))
|
if (string.IsNullOrWhiteSpace(newSeries.Path))
|
||||||
|
|
|
@ -18,101 +18,28 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
public class RefreshSeriesService : IExecute<RefreshSeriesCommand>
|
public class RefreshSeriesService : IExecute<RefreshSeriesCommand>
|
||||||
{
|
{
|
||||||
private readonly IProvideSeriesInfo _seriesInfo;
|
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
private readonly IRefreshEpisodeService _refreshEpisodeService;
|
private readonly IRefreshEpisodeService _refreshEpisodeService;
|
||||||
private readonly IEventAggregator _eventAggregator;
|
private readonly IEventAggregator _eventAggregator;
|
||||||
private readonly IDailySeriesService _dailySeriesService;
|
private readonly IDailySeriesService _dailySeriesService;
|
||||||
private readonly IDiskScanService _diskScanService;
|
private readonly IDiskScanService _diskScanService;
|
||||||
private readonly ICheckIfSeriesShouldBeRefreshed _checkIfSeriesShouldBeRefreshed;
|
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public RefreshSeriesService(IProvideSeriesInfo seriesInfo,
|
public RefreshSeriesService(ISeriesService seriesService,
|
||||||
ISeriesService seriesService,
|
|
||||||
IRefreshEpisodeService refreshEpisodeService,
|
IRefreshEpisodeService refreshEpisodeService,
|
||||||
IEventAggregator eventAggregator,
|
IEventAggregator eventAggregator,
|
||||||
IDailySeriesService dailySeriesService,
|
IDailySeriesService dailySeriesService,
|
||||||
IDiskScanService diskScanService,
|
IDiskScanService diskScanService,
|
||||||
ICheckIfSeriesShouldBeRefreshed checkIfSeriesShouldBeRefreshed,
|
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_seriesInfo = seriesInfo;
|
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
_refreshEpisodeService = refreshEpisodeService;
|
_refreshEpisodeService = refreshEpisodeService;
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
_dailySeriesService = dailySeriesService;
|
_dailySeriesService = dailySeriesService;
|
||||||
_diskScanService = diskScanService;
|
_diskScanService = diskScanService;
|
||||||
_checkIfSeriesShouldBeRefreshed = checkIfSeriesShouldBeRefreshed;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshSeriesInfo(Series series)
|
|
||||||
{
|
|
||||||
_logger.ProgressInfo("Updating {0}", series.Title);
|
|
||||||
|
|
||||||
Tuple<Series, List<Episode>> tuple;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tuple = _seriesInfo.GetSeriesInfo(series.TvdbId);
|
|
||||||
}
|
|
||||||
catch (SeriesNotFoundException)
|
|
||||||
{
|
|
||||||
_logger.Error("Series '{0}' (tvdbid {1}) was not found, it may have been removed from TheTVDB.", series.Title, series.TvdbId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var seriesInfo = tuple.Item1;
|
|
||||||
|
|
||||||
if (series.TvdbId != seriesInfo.TvdbId)
|
|
||||||
{
|
|
||||||
_logger.Warn("Series '{0}' (tvdbid {1}) was replaced with '{2}' (tvdbid {3}), because the original was a duplicate.", series.Title, series.TvdbId, seriesInfo.Title, seriesInfo.TvdbId);
|
|
||||||
series.TvdbId = seriesInfo.TvdbId;
|
|
||||||
}
|
|
||||||
|
|
||||||
series.Title = seriesInfo.Title;
|
|
||||||
series.TitleSlug = seriesInfo.TitleSlug;
|
|
||||||
series.TvRageId = seriesInfo.TvRageId;
|
|
||||||
series.TvMazeId = seriesInfo.TvMazeId;
|
|
||||||
series.ImdbId = seriesInfo.ImdbId;
|
|
||||||
series.AirTime = seriesInfo.AirTime;
|
|
||||||
series.Overview = seriesInfo.Overview;
|
|
||||||
series.Status = seriesInfo.Status;
|
|
||||||
series.CleanTitle = seriesInfo.CleanTitle;
|
|
||||||
series.SortTitle = seriesInfo.SortTitle;
|
|
||||||
series.LastInfoSync = DateTime.UtcNow;
|
|
||||||
series.Runtime = seriesInfo.Runtime;
|
|
||||||
series.Images = seriesInfo.Images;
|
|
||||||
series.Network = seriesInfo.Network;
|
|
||||||
series.FirstAired = seriesInfo.FirstAired;
|
|
||||||
series.Ratings = seriesInfo.Ratings;
|
|
||||||
series.Actors = seriesInfo.Actors;
|
|
||||||
series.Genres = seriesInfo.Genres;
|
|
||||||
series.Certification = seriesInfo.Certification;
|
|
||||||
|
|
||||||
if (_dailySeriesService.IsDailySeries(series.TvdbId))
|
|
||||||
{
|
|
||||||
series.SeriesType = SeriesTypes.Daily;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
series.Path = new DirectoryInfo(series.Path).FullName;
|
|
||||||
series.Path = series.Path.GetActualCasing();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Warn(e, "Couldn't update series path for " + series.Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
series.Seasons = UpdateSeasons(series, seriesInfo);
|
|
||||||
|
|
||||||
_seriesService.UpdateSeries(series);
|
|
||||||
_refreshEpisodeService.RefreshEpisodeInfo(series, tuple.Item2);
|
|
||||||
|
|
||||||
_logger.Debug("Finished series refresh for {0}", series.Title);
|
|
||||||
_eventAggregator.PublishEvent(new SeriesUpdatedEvent(series));
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Season> UpdateSeasons(Series series, Series seriesInfo)
|
private List<Season> UpdateSeasons(Series series, Series seriesInfo)
|
||||||
{
|
{
|
||||||
|
@ -151,7 +78,6 @@ namespace NzbDrone.Core.Tv
|
||||||
if (message.SeriesId.HasValue)
|
if (message.SeriesId.HasValue)
|
||||||
{
|
{
|
||||||
var series = _seriesService.GetSeries(message.SeriesId.Value);
|
var series = _seriesService.GetSeries(message.SeriesId.Value);
|
||||||
RefreshSeriesInfo(series);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -159,11 +85,11 @@ namespace NzbDrone.Core.Tv
|
||||||
|
|
||||||
foreach (var series in allSeries)
|
foreach (var series in allSeries)
|
||||||
{
|
{
|
||||||
if (message.Trigger == CommandTrigger.Manual || _checkIfSeriesShouldBeRefreshed.ShouldRefresh(series))
|
if (message.Trigger == CommandTrigger.Manual)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RefreshSeriesInfo(series);
|
//RefreshSeriesInfo(series);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using NLog;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Tv
|
|
||||||
{
|
|
||||||
public interface ICheckIfSeriesShouldBeRefreshed
|
|
||||||
{
|
|
||||||
bool ShouldRefresh(Series series);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ShouldRefreshSeries : ICheckIfSeriesShouldBeRefreshed
|
|
||||||
{
|
|
||||||
private readonly IEpisodeService _episodeService;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public ShouldRefreshSeries(IEpisodeService episodeService, Logger logger)
|
|
||||||
{
|
|
||||||
_episodeService = episodeService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShouldRefresh(Series series)
|
|
||||||
{
|
|
||||||
if (series.LastInfoSync < DateTime.UtcNow.AddDays(-30))
|
|
||||||
{
|
|
||||||
_logger.Trace("Series {0} last updated more than 30 days ago, should refresh.", series.Title);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (series.LastInfoSync >= DateTime.UtcNow.AddHours(-6))
|
|
||||||
{
|
|
||||||
_logger.Trace("Series {0} last updated less than 6 hours ago, should not be refreshed.", series.Title);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (series.Status == SeriesStatusType.Continuing)
|
|
||||||
{
|
|
||||||
_logger.Trace("Series {0} is continuing, should refresh.", series.Title);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastEpisode = _episodeService.GetEpisodeBySeries(series.Id).OrderByDescending(e => e.AirDateUtc).FirstOrDefault();
|
|
||||||
|
|
||||||
if (lastEpisode != null && lastEpisode.AirDateUtc > DateTime.UtcNow.AddDays(-30))
|
|
||||||
{
|
|
||||||
_logger.Trace("Last episode in {0} aired less than 30 days ago, should refresh.", series.Title);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.Trace("Series {0} ended long ago, should not be refreshed.", series.Title);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue