mirror of
https://github.com/Sonarr/Sonarr
synced 2024-12-27 02:07:41 +00:00
Added TvRageProvider and model classes
This commit is contained in:
parent
9428d68667
commit
f00b17ac47
8 changed files with 370 additions and 0 deletions
|
@ -139,6 +139,8 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="ProviderTests\TvRageProviderTests\GetUtcOffsetFixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\TvRageProviderTests\SearchSeriesFixture.cs" />
|
||||||
<Compile Include="QualityTypesTest.cs" />
|
<Compile Include="QualityTypesTest.cs" />
|
||||||
<Compile Include="EpisodeParseResultTest.cs" />
|
<Compile Include="EpisodeParseResultTest.cs" />
|
||||||
<Compile Include="Integeration\ServiceIntegerationFixture.cs" />
|
<Compile Include="Integeration\ServiceIntegerationFixture.cs" />
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
// ReSharper disable RedundantUsingDirective
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Ninject;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using TvdbLib.Data;
|
||||||
|
using TvdbLib.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ProviderTests.TvRageProviderTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class GetUtcOffsetFixture : CoreTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_return_zero_if_timeZone_is_empty()
|
||||||
|
{
|
||||||
|
Mocker.Resolve<TvRageProvider>().GetUtcOffset("").Should().Be(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_zero_if_cannot_be_coverted_to_int()
|
||||||
|
{
|
||||||
|
Mocker.Resolve<TvRageProvider>().GetUtcOffset("adfhadfhdjaf").Should().Be(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("GMT-5", -5)]
|
||||||
|
[TestCase("GMT+0", 0)]
|
||||||
|
[TestCase("GMT+8", 8)]
|
||||||
|
public void should_return_offset_when_not_dst(string timezone, int expected)
|
||||||
|
{
|
||||||
|
Mocker.Resolve<TvRageProvider>().GetUtcOffset(timezone).Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("GMT-5 +DST", -4)]
|
||||||
|
[TestCase("GMT+0 +DST", 1)]
|
||||||
|
[TestCase("GMT+8 +DST", 9)]
|
||||||
|
public void should_return_offset_plus_one_when_dst(string timezone, int expected)
|
||||||
|
{
|
||||||
|
Mocker.Resolve<TvRageProvider>().GetUtcOffset(timezone).Should().Be(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
// ReSharper disable RedundantUsingDirective
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Ninject;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using TvdbLib.Data;
|
||||||
|
using TvdbLib.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ProviderTests.TvRageProviderTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class SearchSeriesFixture : CoreTest
|
||||||
|
{
|
||||||
|
private const string search = "http://services.tvrage.com/feeds/full_search.php?show=";
|
||||||
|
|
||||||
|
private void WithEmptyResults()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<HttpProvider>()
|
||||||
|
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(search)), null))
|
||||||
|
.Returns(new FileStream(@".\Files\TVRage\SearchResults_empty.xml", FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithManyResults()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<HttpProvider>()
|
||||||
|
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(search)), null))
|
||||||
|
.Returns(new FileStream(@".\Files\TVRage\SearchResults_many.xml", FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithOneResult()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<HttpProvider>()
|
||||||
|
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(search)), null))
|
||||||
|
.Returns(new FileStream(@".\Files\TVRage\SearchResults_one.xml", FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_empty_when_no_results_are_found()
|
||||||
|
{
|
||||||
|
WithEmptyResults();
|
||||||
|
Mocker.Resolve<TvRageProvider>().SearchSeries("asdasdasdasdas").Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_have_more_than_one_when_multiple_results_are_returned()
|
||||||
|
{
|
||||||
|
WithManyResults();
|
||||||
|
Mocker.Resolve<TvRageProvider>().SearchSeries("top+gear").Should().NotBeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_have_one_when_only_one_result_is_found()
|
||||||
|
{
|
||||||
|
WithOneResult();
|
||||||
|
Mocker.Resolve<TvRageProvider>().SearchSeries("suits").Should().HaveCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ended_should_not_have_a_value_when_series_has_not_ended()
|
||||||
|
{
|
||||||
|
WithOneResult();
|
||||||
|
Mocker.Resolve<TvRageProvider>().SearchSeries("suits").First().Ended.HasValue.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void started_should_match_series()
|
||||||
|
{
|
||||||
|
WithOneResult();
|
||||||
|
Mocker.Resolve<TvRageProvider>().SearchSeries("suits").First().Started.Should().Be(new DateTime(2011, 6, 23));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
NzbDrone.Core/Model/TvRage/TvRageEpisode.cs
Normal file
17
NzbDrone.Core/Model/TvRage/TvRageEpisode.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Model.TvRage
|
||||||
|
{
|
||||||
|
public class TvRageEpisode
|
||||||
|
{
|
||||||
|
public int EpisodeNumber { get; set; }
|
||||||
|
public int SeasonNumber { get; set; }
|
||||||
|
public string ProductionCode { get; set; }
|
||||||
|
public DateTime AirDate { get; set; }
|
||||||
|
public string Link { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
}
|
||||||
|
}
|
22
NzbDrone.Core/Model/TvRage/TvRageSearchResult.cs
Normal file
22
NzbDrone.Core/Model/TvRage/TvRageSearchResult.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Model.TvRage
|
||||||
|
{
|
||||||
|
public class TvRageSearchResult
|
||||||
|
{
|
||||||
|
public int ShowId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Link { get; set; }
|
||||||
|
public string Country { get; set; }
|
||||||
|
public DateTime Started { get; set; }
|
||||||
|
public DateTime? Ended { get; set; }
|
||||||
|
public int Seasons { get; set; }
|
||||||
|
public string Status { get; set; }
|
||||||
|
public int RunTime { get; set; }
|
||||||
|
public DateTime AirTime { get; set; }
|
||||||
|
public DayOfWeek AirDay { get; set; }
|
||||||
|
}
|
||||||
|
}
|
25
NzbDrone.Core/Model/TvRage/TvRageSeries.cs
Normal file
25
NzbDrone.Core/Model/TvRage/TvRageSeries.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Model.TvRage
|
||||||
|
{
|
||||||
|
public class TvRageSeries
|
||||||
|
{
|
||||||
|
public int ShowId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Link { get; set; }
|
||||||
|
public int Seasons { get; set; }
|
||||||
|
public int Started { get; set; }
|
||||||
|
public DateTime StartDate { get; set; }
|
||||||
|
public DateTime Ended { get; set; }
|
||||||
|
public string OriginCountry { get; set; }
|
||||||
|
public string Status { get; set; }
|
||||||
|
public int RunTime { get; set; }
|
||||||
|
public string Network { get; set; }
|
||||||
|
public DateTime AirTime { get; set; }
|
||||||
|
public DayOfWeek AirDay { get; set; }
|
||||||
|
public int UtcOffset { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -291,6 +291,9 @@
|
||||||
<Compile Include="Model\Sabnzbd\SabQueueItem.cs" />
|
<Compile Include="Model\Sabnzbd\SabQueueItem.cs" />
|
||||||
<Compile Include="Model\Sabnzbd\SabVersionModel.cs" />
|
<Compile Include="Model\Sabnzbd\SabVersionModel.cs" />
|
||||||
<Compile Include="Model\StatsModel.cs" />
|
<Compile Include="Model\StatsModel.cs" />
|
||||||
|
<Compile Include="Model\TvRage\TvRageEpisode.cs" />
|
||||||
|
<Compile Include="Model\TvRage\TvRageSearchResult.cs" />
|
||||||
|
<Compile Include="Model\TvRage\TvRageSeries.cs" />
|
||||||
<Compile Include="Model\Twitter\TwitterAuthorizationModel.cs" />
|
<Compile Include="Model\Twitter\TwitterAuthorizationModel.cs" />
|
||||||
<Compile Include="Model\UpdatePackage.cs" />
|
<Compile Include="Model\UpdatePackage.cs" />
|
||||||
<Compile Include="Model\Xbmc\ActionType.cs" />
|
<Compile Include="Model\Xbmc\ActionType.cs" />
|
||||||
|
@ -343,6 +346,7 @@
|
||||||
<Compile Include="Jobs\RssSyncJob.cs" />
|
<Compile Include="Jobs\RssSyncJob.cs" />
|
||||||
<Compile Include="Jobs\UpdateInfoJob.cs" />
|
<Compile Include="Jobs\UpdateInfoJob.cs" />
|
||||||
<Compile Include="Providers\StatsProvider.cs" />
|
<Compile Include="Providers\StatsProvider.cs" />
|
||||||
|
<Compile Include="Providers\TvRageProvider.cs" />
|
||||||
<Compile Include="Providers\XemCommunicationProvider.cs" />
|
<Compile Include="Providers\XemCommunicationProvider.cs" />
|
||||||
<Compile Include="Providers\XemProvider.cs" />
|
<Compile Include="Providers\XemProvider.cs" />
|
||||||
<Compile Include="Repository\MetadataDefinition.cs" />
|
<Compile Include="Repository\MetadataDefinition.cs" />
|
||||||
|
|
168
NzbDrone.Core/Providers/TvRageProvider.cs
Normal file
168
NzbDrone.Core/Providers/TvRageProvider.cs
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using NLog;
|
||||||
|
using Ninject;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model.TvRage;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Providers
|
||||||
|
{
|
||||||
|
public class TvRageProvider
|
||||||
|
{
|
||||||
|
private readonly HttpProvider _httpProvider;
|
||||||
|
private const string TVRAGE_APIKEY = "NW4v0PSmQIoVmpbASLdD";
|
||||||
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public TvRageProvider(HttpProvider httpProvider)
|
||||||
|
{
|
||||||
|
_httpProvider = httpProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IList<TvRageSearchResult> SearchSeries(string title)
|
||||||
|
{
|
||||||
|
var searchResults = new List<TvRageSearchResult>();
|
||||||
|
|
||||||
|
var xmlStream = _httpProvider.DownloadStream("http://services.tvrage.com/feeds/full_search.php?show=" + title, null);
|
||||||
|
|
||||||
|
var xml = XDocument.Load(xmlStream);
|
||||||
|
var shows = xml.Descendants("Results").Descendants("show");
|
||||||
|
|
||||||
|
foreach (var s in shows)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var show = new TvRageSearchResult();
|
||||||
|
show.ShowId = Int32.Parse(s.Element("showid").Value);
|
||||||
|
show.Name = s.Element("name").Value;
|
||||||
|
show.Link = s.Element("link").Value;
|
||||||
|
show.Country = s.Element("country").Value;
|
||||||
|
|
||||||
|
DateTime started;
|
||||||
|
if (DateTime.TryParse(s.Element("started").Value, out started)) ;
|
||||||
|
show.Started = started;
|
||||||
|
|
||||||
|
DateTime ended;
|
||||||
|
if (DateTime.TryParse(s.Element("ended").Value, out ended)) ;
|
||||||
|
show.Ended = ended;
|
||||||
|
|
||||||
|
if (show.Ended < new DateTime(1900, 1, 1))
|
||||||
|
show.Ended = null;
|
||||||
|
|
||||||
|
show.Seasons = Int32.Parse(s.Element("seasons").Value);
|
||||||
|
show.Status = s.Element("status").Value;
|
||||||
|
show.RunTime = Int32.Parse(s.Element("runtime").Value);
|
||||||
|
show.AirTime = DateTime.Parse(s.Element("airtime").Value);
|
||||||
|
show.AirDay = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), s.Element("airday").Value);
|
||||||
|
|
||||||
|
searchResults.Add(show);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.DebugException("Failed to parse TvRage Search Result. Search Term : " + title, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return searchResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual TvRageSeries GetSeries(int id)
|
||||||
|
{
|
||||||
|
var url = string.Format("http://services.tvrage.com/feeds/showinfo.php?key={0}sid={1}", TVRAGE_APIKEY, id);
|
||||||
|
var xmlStream = _httpProvider.DownloadStream(url, null);
|
||||||
|
var xml = XDocument.Load(xmlStream);
|
||||||
|
var s = xml.Descendants("Showinfo").First();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var show = new TvRageSeries();
|
||||||
|
show.ShowId = Int32.Parse(s.Element("showid").Value);
|
||||||
|
show.Name = s.Element("showname").Value;
|
||||||
|
show.Link = s.Element("showlink").Value;
|
||||||
|
show.Seasons = Int32.Parse(s.Element("seasons").Value);
|
||||||
|
show.Started = Int32.Parse(s.Element("started").Value);
|
||||||
|
|
||||||
|
DateTime startDate;
|
||||||
|
if (DateTime.TryParse(s.Element("startdate").Value, out startDate)) ;
|
||||||
|
show.StartDate = startDate;
|
||||||
|
|
||||||
|
DateTime ended;
|
||||||
|
if (DateTime.TryParse(s.Element("ended").Value, out ended)) ;
|
||||||
|
show.Ended = ended;
|
||||||
|
|
||||||
|
show.OriginCountry = s.Element("origin_country").Value;
|
||||||
|
show.Status = s.Element("status").Value;
|
||||||
|
show.RunTime = Int32.Parse(s.Element("runtime").Value);
|
||||||
|
show.Network = s.Element("network").Value;
|
||||||
|
show.AirTime = DateTime.Parse(s.Element("airtime").Value);
|
||||||
|
show.AirDay = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), s.Element("airday").Value);
|
||||||
|
show.UtcOffset = GetUtcOffset(s.Element("timezone").Value);
|
||||||
|
return show;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.DebugException("Failed to parse ShowInfo for ID: " + id, ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual List<TvRageEpisode> GetEpisodes(int id)
|
||||||
|
{
|
||||||
|
var url = String.Format("http://services.tvrage.com/feeds/episode_list.php?key={0}sid={1}", TVRAGE_APIKEY, id);
|
||||||
|
var xmlStream = _httpProvider.DownloadStream(url, null);
|
||||||
|
var xml = XDocument.Load(xmlStream);
|
||||||
|
var show = xml.Descendants("Show");
|
||||||
|
var seasons = show.Descendants("Season");
|
||||||
|
|
||||||
|
var episodes = new List<TvRageEpisode>();
|
||||||
|
|
||||||
|
foreach (var season in seasons)
|
||||||
|
{
|
||||||
|
var eps = season.Descendants("episode");
|
||||||
|
|
||||||
|
foreach (var e in eps)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var episode = new TvRageEpisode();
|
||||||
|
episode.EpisodeNumber = Int32.Parse(e.Element("epnum").Value);
|
||||||
|
episode.SeasonNumber = Int32.Parse(e.Element("seasonnum").Value);
|
||||||
|
episode.ProductionCode = e.Element("prodnum").Value;
|
||||||
|
episode.AirDate = DateTime.Parse(e.Element("airdate").Value);
|
||||||
|
episode.Link = e.Element("link").Value;
|
||||||
|
episode.Title = e.Element("title").Value;
|
||||||
|
episodes.Add(episode);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.DebugException("Failed to parse TV Rage episode", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return episodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int GetUtcOffset(string timeZone)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrWhiteSpace(timeZone))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var offsetString = timeZone.Substring(3, 2);
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
if (!Int32.TryParse(offsetString, out offset))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (timeZone.IndexOf("+DST", StringComparison.CurrentCultureIgnoreCase) > 0)
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue