fully replaced TVDB with Trakt.tv

pull/4/head
kay.one 11 years ago
parent af3282630f
commit a052a9389e

@ -1,27 +1,24 @@
using System.Linq;
using Nancy;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.QualityType;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Providers;
namespace NzbDrone.Api.Series
{
public class SeriesLookupModule : NzbDroneApiModule
{
private readonly TvDbProxy _tvDbProxy;
private readonly ISearchForNewSeries _searchProxy;
public SeriesLookupModule(TvDbProxy tvDbProxy)
public SeriesLookupModule(ISearchForNewSeries searchProxy)
: base("/Series/lookup")
{
_tvDbProxy = tvDbProxy;
_searchProxy = searchProxy;
Get["/"] = x => GetQualityType();
}
private Response GetQualityType()
{
var tvDbResults = _tvDbProxy.SearchSeries((string)Request.Query.term);
var tvDbResults = _searchProxy.SearchForNewSeries((string)Request.Query.term);
return tvDbResults.AsResponse();
}
}

@ -1,15 +1,39 @@
using System.Text.RegularExpressions;
using System.Linq;
namespace NzbDrone.Common.EnsureThat
{
internal static class StringExtensions
public static class StringExtensions
{
internal static string Inject(this string format, params object[] formattingArgs)
public static string Inject(this string format, params object[] formattingArgs)
{
return string.Format(format, formattingArgs);
}
internal static string Inject(this string format, params string[] formattingArgs)
public static string Inject(this string format, params string[] formattingArgs)
{
return string.Format(format, formattingArgs);
return string.Format(format, formattingArgs.Cast<object>());
}
private static readonly Regex InvalidCharRegex = new Regex(@"[^a-z0-9\s-]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex CollapseSpace = new Regex(@"\s+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static string ToSlug(this string phrase)
{
phrase = phrase.RemoveAccent().ToLower();
phrase = InvalidCharRegex.Replace(phrase, string.Empty);
phrase = CollapseSpace.Replace(phrase, " ").Trim();
phrase = phrase.Replace(" ", "-");
return phrase;
}
public static string RemoveAccent(this string txt)
{
var bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(txt);
return System.Text.Encoding.ASCII.GetString(bytes);
}
}
}

@ -29,7 +29,6 @@ namespace NzbDrone.Common.Eventing
_logger.Debug("{0} <- {1}", message.GetType().Name, handler.GetType().Name);
}
foreach (var handler in _handlers().OfType<IHandleAsync<TEvent>>())
{
var handlerLocal = handler;

@ -137,7 +137,6 @@
<Compile Include="UdpProvider.cs" />
</ItemGroup>
<ItemGroup>
<None Include="EnsureThat\ve-3BAF.tmp" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>

@ -13,7 +13,7 @@ namespace NzbDrone.Core.Test.Datastore
[TestFixture]
public class DatabaseRelationshipFixture : DbTest
{
[Test]
/* [Test]
[Explicit]
public void benchmark()
{
@ -70,7 +70,7 @@ namespace NzbDrone.Core.Test.Datastore
var loadedSeries = Db.Single<Series>();
loadedSeries.Covers.Value.Should().HaveSameCount(covers);
}
}*/
[Test]
public void one_to_one()

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Results>0</Results>

@ -1,420 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Results>
<show>
<showid>6753</showid>
<name>Top Gear</name>
<link>http://www.tvrage.com/Top_Gear</link>
<country>UK</country>
<started>Oct/20/2002</started>
<ended></ended>
<seasons>18</seasons>
<status>Returning Series</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre></genre>
<genre>Automobiles</genre>
<genre>Comedy</genre>
</genres>
<network country="UK">BBC TWO</network>
<airtime>20:00</airtime>
<airday>Sunday</airday>
</show>
<show>
<showid>19321</showid>
<name>Top Gear (1978)</name>
<link>http://www.tvrage.com/shows/id-19321</link>
<country>UK</country>
<started>Jul/13/1978</started>
<ended>Dec/17/2001</ended>
<seasons>24</seasons>
<status>Canceled/Ended</status>
<runtime>30</runtime>
<classification>Reality</classification>
<genres>
<genre>Automobiles</genre>
</genres>
<network country="UK">BBC TWO</network>
<airtime>12:00</airtime>
<airday>Sunday</airday>
<akas>
<aka country="UK">Top Gear Xtra</aka>
</akas>
</show>
<show>
<showid>20568</showid>
<name>Top Gear (US)</name>
<link>http://www.tvrage.com/Top_Gear_US</link>
<country>US</country>
<started>Nov/21/2010</started>
<ended></ended>
<seasons>3</seasons>
<status>Returning Series</status>
<runtime>60</runtime>
<classification>Documentary</classification>
<genres>
<genre>Automobiles</genre>
<genre>Comedy</genre>
</genres>
<network country="US">History Channel</network>
<airtime>21:00</airtime>
<airday>Tuesday</airday>
<akas>
<aka attr="Unofficial Working Title">Top Gear USA</aka>
</akas>
</show>
<show>
<showid>20324</showid>
<name>Top Gear Australia</name>
<link>http://www.tvrage.com/shows/id-20324</link>
<country>AU</country>
<started>Sep/29/2008</started>
<ended></ended>
<seasons>4</seasons>
<status>Returning Series</status>
<runtime>60</runtime>
<classification>Documentary</classification>
<genres>
<genre>Automobiles</genre>
<genre>Comedy</genre>
</genres>
<network country="AU">GEM</network>
<airtime>18:30</airtime>
<airday>Saturday</airday>
</show>
<show>
<showid>20569</showid>
<name>Top Gear Motorsport</name>
<link>http://www.tvrage.com/shows/id-20569</link>
<country>UK</country>
<started>Mar/24/1995</started>
<ended>1998</ended>
<seasons>3</seasons>
<status>Canceled/Ended</status>
<runtime>30</runtime>
<classification>Sports</classification>
<genres>
<genre>Educational</genre>
<genre>Family</genre>
<genre>How To/Do It Yourself</genre>
</genres>
<network country="UK">BBC TWO</network>
<airtime>12:00</airtime>
<airday>Wednesday</airday>
</show>
<show>
<showid>6249</showid>
<name>Top Secret Life of Edgar Briggs</name>
<link>http://www.tvrage.com/shows/id-6249</link>
<country>UK</country>
<started>Sep/15/1974</started>
<ended>Dec/20/1974</ended>
<seasons>1</seasons>
<status>Canceled/Ended</status>
<runtime>30</runtime>
<classification>Scripted</classification>
<genres>
<genre>Comedy</genre>
</genres>
<network country="UK">ITV</network>
<airtime>19:00</airtime>
<airday>Friday</airday>
</show>
<show>
<showid>25253</showid>
<name>Popstar Wesley: Op weg naar de Top</name>
<link>http://www.tvrage.com/shows/id-25253</link>
<country>NL</country>
<started>Feb/06/2010</started>
<ended>Feb/27/2010</ended>
<seasons>1</seasons>
<status>Canceled/Ended</status>
<runtime>15</runtime>
<classification>Reality</classification>
<genres>
<genre>How To/Do It Yourself</genre>
<genre>Music</genre>
<genre>Talent</genre>
</genres>
<network country="NL">SBS 6</network>
<airtime>23:15</airtime>
<airday>Saturday</airday>
</show>
<show>
<showid>19649</showid>
<name>Top Chef: Masters</name>
<link>http://www.tvrage.com/Top_Chef-Masters</link>
<country>US</country>
<started>Jun/10/2009</started>
<ended></ended>
<seasons>4</seasons>
<status>Returning Series</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre>Cooking/Food</genre>
<genre>Family</genre>
<genre>Talent</genre>
</genres>
<network country="US">Bravo</network>
<airtime>22:00</airtime>
<airday>Wednesday</airday>
</show>
<show>
<showid>26212</showid>
<name>Top Chef: Just Desserts</name>
<link>http://www.tvrage.com/Top_Chef-Just_Desserts</link>
<country>US</country>
<started>Sep/15/2010</started>
<ended></ended>
<seasons>2</seasons>
<status>New Series</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre>Celebrities</genre>
<genre>Cooking/Food</genre>
<genre>Educational</genre>
<genre>Family</genre>
<genre>How To/Do It Yourself</genre>
<genre>Talent</genre>
</genres>
<network country="US">Bravo</network>
<airtime>22:00</airtime>
<airday>Wednesday</airday>
</show>
<show>
<showid>11210</showid>
<name>Top Design</name>
<link>http://www.tvrage.com/shows/id-11210</link>
<country>US</country>
<started>Jan/31/2007</started>
<ended>Nov/05/2008</ended>
<seasons>2</seasons>
<status>Canceled/Ended</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre>Celebrities</genre>
<genre>Educational</genre>
<genre>Family</genre>
<genre>Housing/Building</genre>
<genre>How To/Do It Yourself</genre>
</genres>
<network country="US">Bravo</network>
<airtime>22:00</airtime>
<airday>Wednesday</airday>
<akas>
<aka attr="Working Title">Top Decorator</aka>
<aka attr="Working Title">Top Designer</aka>
</akas>
</show>
<show>
<showid>15390</showid>
<name>Air Gear</name>
<link>http://www.tvrage.com/shows/id-15390</link>
<country>AJ</country>
<started>Apr/04/2006</started>
<ended>Sep/26/2006</ended>
<seasons>1</seasons>
<status>Canceled/Ended</status>
<runtime>30</runtime>
<classification>Animation</classification>
<genres>
<genre>Anime</genre>
<genre>Adventure</genre>
<genre>Sci-Fi</genre>
<genre>Tech/Gaming</genre>
</genres>
<network country="JP">TV Tokyo</network>
<airtime>12:00</airtime>
<airday>Wednesday</airday>
</show>
<show>
<showid>30933</showid>
<name>Top Guns</name>
<link>http://www.tvrage.com/shows/id-30933</link>
<country>US</country>
<started>Feb/15/2012</started>
<ended></ended>
<seasons>1</seasons>
<status>New Series</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre>Action</genre>
<genre>Family</genre>
<genre>How To/Do It Yourself</genre>
<genre>Talent</genre>
</genres>
<network country="US">H2 TV</network>
<airtime>22:00</airtime>
<airday>Wednesday</airday>
</show>
<show>
<showid>28150</showid>
<name>Top Chef Canada</name>
<link>http://www.tvrage.com/shows/id-28150</link>
<country>CA</country>
<started>Apr/11/2011</started>
<ended></ended>
<seasons>2</seasons>
<status>New Series</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre>Cooking/Food</genre>
<genre>Family</genre>
<genre>Talent</genre>
</genres>
<network country="CA">Food Network Canada</network>
<airtime>21:00</airtime>
<airday>Monday</airday>
</show>
<show>
<showid>6386</showid>
<name>Top of the Pops Saturday</name>
<link>http://www.tvrage.com/shows/id-6386</link>
<country>UK</country>
<started>Sep/20/2003</started>
<ended>Mar/26/2005</ended>
<seasons>2</seasons>
<status>Canceled/Ended</status>
<runtime>60</runtime>
<classification>Variety</classification>
<genres>
<genre>Children</genre>
</genres>
<network country="UK">BBC One</network>
<airtime>23:00</airtime>
<airday>Saturday</airday>
</show>
<show>
<showid>29633</showid>
<name>Top Secret Recipe</name>
<link>http://www.tvrage.com/shows/id-29633</link>
<country>US</country>
<started>Oct/07/2011</started>
<ended></ended>
<seasons>1</seasons>
<status>New Series</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre>Cooking/Food</genre>
<genre>How To/Do It Yourself</genre>
</genres>
<network country="US">CMT</network>
<airtime>21:00</airtime>
<airday>Thursday</airday>
</show>
<show>
<showid>26650</showid>
<name>The Top 100: NFL's Greatest Players</name>
<link>http://www.tvrage.com/shows/id-26650</link>
<country>US</country>
<started>Sep/03/2010</started>
<ended>Nov/04/2010</ended>
<seasons>1</seasons>
<status>New Series</status>
<runtime>60</runtime>
<classification>Sports</classification>
<genres>
<genre>Sports</genre>
</genres>
<network country="US">NFL Network</network>
<airtime>21:00</airtime>
<airday>Thursday</airday>
</show>
<show>
<showid>7047</showid>
<name>Top of the Pops Reloaded</name>
<link>http://www.tvrage.com/shows/id-7047</link>
<country>UK</country>
<started>Sep/2005</started>
<ended>Mar/2006</ended>
<seasons>2</seasons>
<status>Canceled/Ended</status>
<runtime>45</runtime>
<classification>Variety</classification>
<genres>
<genre>Children</genre>
<genre>Music</genre>
<genre>Sketch/Improv</genre>
</genres>
<network country="UK">CBBC</network>
<airtime>11:00</airtime>
<airday>Saturday</airday>
</show>
<show>
<showid>19475</showid>
<name>Top Model Ghana</name>
<link>http://www.tvrage.com/shows/id-19475</link>
<country>GH</country>
<started>Aug/26/2006</started>
<ended>Oct/16/2006</ended>
<seasons>1</seasons>
<status>Canceled/Ended</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre>Celebrities</genre>
<genre>Family</genre>
<genre>Fashion/Make-up</genre>
<genre>Talent</genre>
<genre>Travel</genre>
</genres>
<network country="GH">GTV</network>
<airtime>21:00</airtime>
<airday>Monday</airday>
<akas>
<aka attr="Alternate title" country="US">Ghana's Next Top Model</aka>
<aka attr="Abbreviated title" country="GH">TMG</aka>
<aka attr="1st Season title" country="GH">Top Model Ghana, Cycle</aka>
</akas>
</show>
<show>
<showid>31823</showid>
<name>Top 100 Video Games of All Time</name>
<link>http://www.tvrage.com/shows/id-31823</link>
<country>US</country>
<started>Jun/11/2012</started>
<ended></ended>
<seasons>1</seasons>
<status>New Series</status>
<runtime>60</runtime>
<classification>Mini-Series</classification>
<genres>
<genre>Family</genre>
<genre>Teens</genre>
</genres>
<network country="US">G4</network>
<airtime>20:00</airtime>
<airday>Weekdays</airday>
</show>
<show>
<showid>25003</showid>
<name>Cantore Stories: On Top of the World</name>
<link>http://www.tvrage.com/Cantore_Stories-On_Top_of_the_World</link>
<country>US</country>
<started>Jan/24/2010</started>
<ended></ended>
<seasons>1</seasons>
<status>New Series</status>
<runtime>60</runtime>
<classification>Reality</classification>
<genres>
<genre>Adventure</genre>
<genre>Educational</genre>
<genre>Family</genre>
<genre>Travel</genre>
</genres>
<network country="US">The Weather Channel</network>
<airtime>22:00</airtime>
<airday>Sunday</airday>
<akas>
<aka attr="Short title" country="US">Cantore Stories</aka>
</akas>
</show>
</Results>

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Results>
<show>
<showid>27518</showid>
<name>Suits</name>
<link>http://www.tvrage.com/Suits</link>
<country>US</country>
<started>Jun/23/2011</started>
<ended></ended>
<seasons>2</seasons>
<status>Returning Series</status>
<runtime>60</runtime>
<classification>Scripted</classification>
<genres>
<genre>Drama</genre>
<genre>Financial/Business</genre>
</genres>
<network country="US">USA</network>
<airtime>22:00</airtime>
<airday>Thursday</airday>
<akas>
<aka attr="Working title" country="US">A Legal Mind</aka>
</akas>
</show>
</Results>

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Showinfo></Showinfo>

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Showinfo>
<showid>29999</showid>
<showname>Anger Management</showname>
<showlink>http://tvrage.com/shows/id-29999</showlink>
<seasons>2</seasons>
<started>2012</started>
<startdate>Jun/28/2012</startdate>
<ended></ended>
<origin_country>US</origin_country>
<status>Returning Series</status>
<classification>Scripted</classification>
<genres>
<genre>Comedy</genre>
</genres>
<runtime>30</runtime>
<network country="US">FX</network>
<airtime>21:30</airtime>
<airday>Thursday</airday>
<timezone>GMT-5 -DST</timezone>
</Showinfo>

@ -5,19 +5,17 @@ using NUnit.Framework;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests
namespace NzbDrone.Core.Test.MetadataSourceTests
{
[TestFixture]
public class TvDbProxyFixture : CoreTest<TvDbProxy>
public class TraktProxyFixture : CoreTest<TraktProxy>
{
[TestCase("The Simpsons")]
[TestCase("Family Guy")]
[TestCase("South Park")]
[TestCase("Franklin & Bash")]
public void successful_search(string title)
{
var result = Subject.SearchSeries(title);
var result = Subject.SearchForNewSeries(title);
result.Should().NotBeEmpty();
result[0].Title.Should().Be(title);
@ -27,14 +25,23 @@ namespace NzbDrone.Core.Test.ProviderTests
[Test]
public void no_search_result()
{
var result = Subject.SearchSeries(Guid.NewGuid().ToString());
var result = Subject.SearchForNewSeries(Guid.NewGuid().ToString());
result.Should().BeEmpty();
}
[Test]
public void should_be_able_to_get_series_detail()
{
var details = Subject.GetSeriesInfo(75978);
details.Should().NotBeNull();
details.Images.Should().NotBeEmpty();
}
[Test]
public void none_unique_season_episode_number()
{
var result = Subject.GetEpisodes(75978);//Family guy
var result = Subject.GetEpisodeInfo(75978);//Family guy
result.GroupBy(e => e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000"))
.Max(e => e.Count()).Should().Be(1);
@ -42,20 +49,13 @@ namespace NzbDrone.Core.Test.ProviderTests
result.Select(c => c.TvDbEpisodeId).Should().OnlyHaveUniqueItems();
}
[Test]
public void should_be_able_to_get_series_detail()
{
var details = Subject.GetSeries(75978);
details.Should().NotBeNull();
details.Covers.Value.Should().NotBeEmpty();
}
[Test]
public void should_be_able_to_get_list_of_episodes()
{
var details = Subject.GetEpisodes(75978);
var details = Subject.GetEpisodeInfo(75978);
details.Should().NotBeEmpty();
}
}
}
}

@ -155,16 +155,12 @@
<Compile Include="MediaFileTests\GhostFileCleanupFixture.cs" />
<Compile Include="MediaFileTests\MediaFileRepositoryFixture.cs" />
<Compile Include="MediaFileTests\EpisodeFileMoverFixture.cs" />
<Compile Include="MetadataSourceTests\TracktProxyFixture.cs" />
<Compile Include="ProviderTests\DownloadClientTests\NzbgetProviderTests\DownloadNzbFixture.cs" />
<Compile Include="ProviderTests\DownloadClientTests\NzbgetProviderTests\QueueFixture.cs" />
<Compile Include="ProviderTests\DownloadProviderTests\ContainsRecentEpisode.cs" />
<Compile Include="RootFolderTests\FreeSpaceOnDrivesFixture.cs" />
<Compile Include="ProviderTests\TvRageMappingProviderTests\FindMatchingTvRageSeriesFixture.cs" />
<Compile Include="ProviderTests\TvRageMappingProviderTests\ProcessResultsFixture.cs" />
<Compile Include="ProviderTests\TvRageProviderTests\GetSeriesFixture.cs" />
<Compile Include="HelperTests\XElementHelperTests\ConvertToDayOfWeekFixture.cs" />
<Compile Include="ProviderTests\TvRageProviderTests\GetUtcOffsetFixture.cs" />
<Compile Include="ProviderTests\TvRageProviderTests\SearchSeriesFixture.cs" />
<Compile Include="Qualities\QualityFixture.cs" />
<Compile Include="EpisodeParseResultTest.cs" />
<Compile Include="JobTests\BacklogSearchJobTest.cs" />
@ -245,7 +241,6 @@
<Compile Include="ProviderTests\DownloadClientTests\SabProviderTests\SabProviderFixture.cs" />
<Compile Include="ProviderTests\SceneMappingProviderTest.cs" />
<Compile Include="TvTests\SeriesProviderTest.cs" />
<Compile Include="ProviderTests\TvDbProxyFixture.cs" />
<Compile Include="XbmcVersionTests.cs" />
</ItemGroup>
<ItemGroup>
@ -355,21 +350,6 @@
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="Files\TvRage\SeriesInfo_empty.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\TvRage\SeriesInfo_one.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\TvRage\SearchResults_one.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\TvRage\SearchResults_many.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\TvRage\SearchResults_empty.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\Xem\Ids.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

@ -1,96 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.ReferenceData;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model.TvRage;
using NzbDrone.Core.Providers;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.ProviderTests.TvRageMappingProviderTests
{
public class FindMatchingTvRageSeriesFixture : TestBase
{
private IList<TvRageSearchResult> _searchResults;
private Series _series;
private Episode _episode;
private TvRageSeries _tvRageSeries;
[SetUp]
public void Setup()
{
_searchResults = Builder<TvRageSearchResult>
.CreateListOfSize(5)
.Build();
_series = Builder<Series>
.CreateNew()
.With(s => s.TvRageId = 0)
.With(s => s.TvRageTitle = null)
.With(s => s.UtcOffset = 0)
.With(s => s.FirstAired = DateTime.Today.AddDays(-180))
.Build();
_episode = Builder<Episode>
.CreateNew()
.With(e => e.AirDate = DateTime.Today.AddDays(-365))
.Build();
_tvRageSeries = Builder<TvRageSeries>
.CreateNew()
.With(s => s.UtcOffset = -8)
.Build();
Mocker.GetMock<IEpisodeService>()
.Setup(s => s.GetEpisode(_series.Id, 1, 1))
.Returns(_episode);
Mocker.GetMock<ISceneMappingService>()
.Setup(s => s.GetCleanName(_series.Id))
.Returns("");
Mocker.GetMock<TvRageProxy>()
.Setup(s => s.SearchSeries(_series.Title))
.Returns(_searchResults);
Mocker.GetMock<TvRageProxy>()
.Setup(s => s.GetSeries(_searchResults.First().ShowId))
.Returns(_tvRageSeries);
}
private void WithMatchingResult()
{
_series.CleanTitle = Parser.NormalizeTitle(_searchResults.First().Name);
}
[Test]
public void should_not_set_tvRage_info_when_result_is_null()
{
var result = Mocker.Resolve<TvRageMappingProvider>()
.FindMatchingTvRageSeries(_series);
result.TvRageId.Should().Be(0);
result.TvRageTitle.Should().Be(null);
result.UtcOffset.Should().Be(0);
}
[Test]
public void should_set_tvRage_info_when_result_is_returned()
{
WithMatchingResult();
var result = Mocker.Resolve<TvRageMappingProvider>()
.FindMatchingTvRageSeries(_series);
result.TvRageId.Should().Be(_searchResults.First().ShowId);
result.TvRageTitle.Should().Be(_searchResults.First().Name);
result.UtcOffset.Should().Be(_tvRageSeries.UtcOffset);
}
}
}

@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model.TvRage;
using NzbDrone.Core.Providers;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.ProviderTests.TvRageMappingProviderTests
{
public class ProcessResultsFixture : TestBase
{
private IList<TvRageSearchResult> _searchResults;
private Series _series;
private Episode _episode;
[SetUp]
public void Setup()
{
_searchResults = Builder<TvRageSearchResult>
.CreateListOfSize(5)
.Build();
_series = Builder<Series>
.CreateNew()
.With(s => s.FirstAired = DateTime.Today.AddDays(-180))
.Build();
_episode = Builder<Episode>
.CreateNew()
.With(e => e.AirDate = DateTime.Today.AddDays(-365))
.Build();
}
[Test]
public void should_return_null_if_no_match_is_found()
{
Mocker.Resolve<TvRageMappingProvider>()
.ProcessResults(_searchResults, _series, "nomatchhere", _episode)
.Should()
.BeNull();
}
[Test]
public void should_return_result_if_series_clean_name_matches()
{
_series.CleanTitle = Parser.NormalizeTitle(_searchResults.First().Name);
Mocker.Resolve<TvRageMappingProvider>()
.ProcessResults(_searchResults, _series, "nomatchhere", _episode)
.Should()
.Be(_searchResults.First());
}
[Test]
public void should_return_result_if_scene_clean_name_matches()
{
Mocker.Resolve<TvRageMappingProvider>()
.ProcessResults(_searchResults, _series, Parser.NormalizeTitle(_searchResults.First().Name), _episode)
.Should()
.Be(_searchResults.First());
}
[Test]
public void should_return_result_if_series_firstAired_matches()
{
_series.FirstAired = _searchResults.Last().Started;
Mocker.Resolve<TvRageMappingProvider>()
.ProcessResults(_searchResults, _series, "nomatchhere", _episode)
.Should()
.Be(_searchResults.Last());
}
[Test]
public void should_return_result_if_episode_firstAired_matches()
{
_episode.AirDate = _searchResults.Last().Started;
Mocker.Resolve<TvRageMappingProvider>()
.ProcessResults(_searchResults, _series, "nomatchhere", _episode)
.Should()
.Be(_searchResults.Last());
}
}
}

@ -1,56 +0,0 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.ProviderTests.TvRageProviderTests
{
[TestFixture]
public class GetSeriesFixture : CoreTest
{
private const string showinfo = "http://services.tvrage.com/feeds/showinfo.php?key=NW4v0PSmQIoVmpbASLdD&sid=";
private void WithEmptyResults()
{
Mocker.GetMock<HttpProvider>()
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(showinfo)), null))
.Returns(OpenRead("Files", "TVRage", "SeriesInfo_empty.xml"));
}
private void WithOneResult()
{
Mocker.GetMock<HttpProvider>()
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(showinfo)), null))
.Returns(OpenRead("Files", "TVRage", "SeriesInfo_one.xml"));
}
[Test]
public void should_be_null_when_no_showinfo_is_returned()
{
WithEmptyResults();
Mocker.Resolve<TvRageProxy>().GetSeries(100).Should().BeNull();
ExceptionVerification.ExpectedWarns(1);
}
[Test]
public void should_return_series_when_showinfo_is_valid()
{
WithOneResult();
var result = Mocker.Resolve<TvRageProxy>().GetSeries(29999);
result.ShowId.Should().Be(29999);
result.Name.Should().Be("Anger Management");
}
}
}

@ -1,48 +0,0 @@

using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.ProviderTests.TvRageProviderTests
{
[TestFixture]
public class GetUtcOffsetFixture : CoreTest
{
[Test]
public void should_return_zero_if_timeZone_is_empty()
{
Mocker.Resolve<TvRageProxy>().GetUtcOffset("").Should().Be(0);
}
[Test]
public void should_return_zero_if_cannot_be_coverted_to_int()
{
Mocker.Resolve<TvRageProxy>().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<TvRageProxy>().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<TvRageProxy>().GetUtcOffset(timezone).Should().Be(expected);
}
}
}

@ -1,80 +0,0 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.ProviderTests.TvRageProviderTests
{
[TestFixture]
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(OpenRead("Files", "TVRage", "SearchResults_empty.xml"));
}
private void WithManyResults()
{
Mocker.GetMock<HttpProvider>()
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(search)), null))
.Returns(OpenRead("Files", "TVRage", "SearchResults_many.xml"));
}
private void WithOneResult()
{
Mocker.GetMock<HttpProvider>()
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(search)), null))
.Returns(OpenRead("Files", "TVRage", "earchResults_one.xml"));
}
[Test]
public void should_be_empty_when_no_results_are_found()
{
WithEmptyResults();
Mocker.Resolve<TvRageProxy>().SearchSeries("asdasdasdasdas").Should().BeEmpty();
}
[Test]
public void should_be_have_more_than_one_when_multiple_results_are_returned()
{
WithManyResults();
Mocker.Resolve<TvRageProxy>().SearchSeries("top+gear").Should().NotBeEmpty();
}
[Test]
public void should_have_one_when_only_one_result_is_found()
{
WithOneResult();
Mocker.Resolve<TvRageProxy>().SearchSeries("suits").Should().HaveCount(1);
}
[Test]
public void ended_should_not_have_a_value_when_series_has_not_ended()
{
WithOneResult();
Mocker.Resolve<TvRageProxy>().SearchSeries("suits").First().Ended.HasValue.Should().BeFalse();
}
[Test]
public void started_should_match_series()
{
WithOneResult();
Mocker.Resolve<TvRageProxy>().SearchSeries("suits").First().Started.Should().Be(new DateTime(2011, 6, 23));
}
}
}

@ -5,6 +5,7 @@ using System.Linq;
using System.Linq.Expressions;
using Marr.Data;
using Marr.Data.QGen;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Datastore

@ -122,6 +122,7 @@ namespace NzbDrone.Core.Datastore.Migration
.WithColumn("Status").AsInt32().NotNullable()
.WithColumn("Overview").AsString().Nullable()
.WithColumn("AirTime").AsString().Nullable()
.WithColumn("Images").AsString()
.WithColumn("Language").AsString().NotNullable()
.WithColumn("Path").AsString().NotNullable()
.WithColumn("Monitored").AsBoolean().NotNullable()

@ -39,17 +39,13 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
Mapper.Entity<History.History>().RegisterModel("History")
.HasOne<History.History, Episode>(h => h.Episode, h => h.EpisodeId);
.HasOne(h => h.Episode, h => h.EpisodeId);
Mapper.Entity<Series>().RegisterModel("Series")
.Relationships.AutoMapComplexTypeProperties<ILazyLoaded>()
.For(c => c.Covers)
.LazyLoad((db, series) => db.Query<MediaCover.MediaCover>().Where(cover => cover.SeriesId == series.Id).ToList());
Mapper.Entity<Series>().RegisterModel("Series");
Mapper.Entity<Season>().RegisterModel("Seasons");
Mapper.Entity<Episode>().RegisterModel("Episodes");
Mapper.Entity<EpisodeFile>().RegisterModel("EpisodeFiles");
Mapper.Entity<MediaCover.MediaCover>().RegisterModel("MediaCovers");
Mapper.Entity<QualityProfile>().RegisterModel("QualityProfiles").For(q => q.DbAllowed).SetColumnName("Allowed").Ignore(q => q.Allowed);
Mapper.Entity<QualitySize>().RegisterModel("QualitySizes");
@ -63,6 +59,7 @@ namespace NzbDrone.Core.Datastore
MapRepository.Instance.RegisterTypeConverter(typeof(Boolean), new BooleanIntConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(Enum), new EnumIntConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(QualityModel), new EmbeddedDocumentConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(MediaCover.MediaCover), new EmbeddedDocumentConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(Quality), new QualityIntConverter());
}
}

@ -1,4 +1,3 @@
using System.Linq;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.MediaCover
@ -11,10 +10,9 @@ namespace NzbDrone.Core.MediaCover
Fanart = 2
}
public class MediaCover : ModelBase
public class MediaCover : IEmbeddedDocument
{
public MediaCoverTypes CoverType { get; set; }
public string Url { get; set; }
public int SeriesId { get; set; }
}
}

@ -37,7 +37,7 @@ namespace NzbDrone.Core.MediaCover
private void EnsureCovers(Series series)
{
foreach (var cover in series.Covers.Value)
foreach (var cover in series.Images)
{
var fileName = GetCoverPath(series.Id, cover.CoverType);
if (!_diskProvider.FileExists(fileName))

@ -0,0 +1,10 @@
using System.Collections.Generic;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MetadataSource
{
public interface IProvideEpisodeInfo
{
IList<Episode> GetEpisodeInfo(int tvDbSeriesId);
}
}

@ -0,0 +1,9 @@
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MetadataSource
{
public interface IProvideSeriesInfo
{
Series GetSeriesInfo(int tvDbSeriesId);
}
}

@ -0,0 +1,10 @@
using System.Collections.Generic;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MetadataSource
{
public interface ISearchForNewSeries
{
List<Series> SearchForNewSeries(string title);
}
}

@ -0,0 +1,8 @@
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class Actor
{
public string name { get; set; }
public string character { get; set; }
}
}

@ -0,0 +1,18 @@
using System;
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class Episode
{
public int season { get; set; }
public int episode { get; set; }
public int number { get; set; }
public int tvdb_id { get; set; }
public string title { get; set; }
public string overview { get; set; }
public DateTime? first_aired { get; set; }
public string url { get; set; }
public string screen { get; set; }
public Ratings ratings { get; set; }
}
}

@ -0,0 +1,9 @@
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class Images
{
public string poster { get; set; }
public string fanart { get; set; }
public string banner { get; set; }
}
}

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class People
{
public List<Actor> actors { get; set; }
}
}

@ -0,0 +1,10 @@
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class Ratings
{
public int percentage { get; set; }
public int votes { get; set; }
public int loved { get; set; }
public int hated { get; set; }
}
}

@ -0,0 +1,12 @@
using System.Collections.Generic;
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class Season
{
public int season { get; set; }
public List<Episode> episodes { get; set; }
public string url { get; set; }
public string poster { get; set; }
}
}

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class Show
{
public string title { get; set; }
public int year { get; set; }
public string url { get; set; }
public DateTime? first_aired { get; set; }
public string country { get; set; }
public string overview { get; set; }
public int runtime { get; set; }
public string status { get; set; }
public string network { get; set; }
public string air_day { get; set; }
public string air_time { get; set; }
public string certification { get; set; }
public string imdb_id { get; set; }
public int tvdb_id { get; set; }
public int tvrage_id { get; set; }
public int last_updated { get; set; }
public string poster { get; set; }
public Images images { get; set; }
public List<TopWatcher> top_watchers { get; set; }
public List<TopEpisode> top_episodes { get; set; }
public Ratings ratings { get; set; }
public Stats stats { get; set; }
public People people { get; set; }
public List<string> genres { get; set; }
public List<Season> seasons { get; set; }
}
}

@ -0,0 +1,14 @@
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class Stats
{
public int watchers { get; set; }
public int plays { get; set; }
public int scrobbles { get; set; }
public int scrobbles_unique { get; set; }
public int checkins { get; set; }
public int checkins_unique { get; set; }
public int collection { get; set; }
public int collection_unique { get; set; }
}
}

@ -0,0 +1,12 @@
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class TopEpisode
{
public int plays { get; set; }
public int season { get; set; }
public int number { get; set; }
public string title { get; set; }
public string url { get; set; }
public int first_aired { get; set; }
}
}

@ -0,0 +1,17 @@
namespace NzbDrone.Core.MetadataSource.Trakt
{
public class TopWatcher
{
public int plays { get; set; }
public string username { get; set; }
public bool @protected { get; set; }
public object full_name { get; set; }
public object gender { get; set; }
public string age { get; set; }
public object location { get; set; }
public object about { get; set; }
public int joined { get; set; }
public string avatar { get; set; }
public string url { get; set; }
}
}

@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource.Trakt;
using NzbDrone.Core.Tv;
using RestSharp;
using NzbDrone.Common.EnsureThat;
using Episode = NzbDrone.Core.Tv.Episode;
namespace NzbDrone.Core.MetadataSource
{
public class TraktProxy : ISearchForNewSeries, IProvideSeriesInfo, IProvideEpisodeInfo
{
public List<Series> SearchForNewSeries(string title)
{
var client = BuildClient("search", "shows");
var restRequest = new RestRequest(title.ToSlug().Replace("-", "+"));
var response = client.Execute<List<Show>>(restRequest);
return response.Data.Select(MapSeries).ToList();
}
public Series GetSeriesInfo(int tvDbSeriesId)
{
var client = BuildClient("show", "summary");
var restRequest = new RestRequest(tvDbSeriesId.ToString());
var response = client.Execute<Show>(restRequest);
return MapSeries(response.Data);
}
public IList<Episode> GetEpisodeInfo(int tvDbSeriesId)
{
var client = BuildClient("show", "summary");
var restRequest = new RestRequest(tvDbSeriesId.ToString() + "/extended");
var response = client.Execute<Show>(restRequest);
return response.Data.seasons.SelectMany(c => c.episodes).Select(MapEpisode).ToList();
}
private static IRestClient BuildClient(string resource, string method)
{
return new RestClient(string.Format("http://api.trakt.tv/{0}/{1}.json/6fc98f83c6a02decd17eb7e13d00e89c", resource, method));
}
private static Series MapSeries(Show show)
{
var series = new Series();
series.TvDbId = show.tvdb_id;
series.TvRageId = show.tvrage_id;
series.Title = show.title;
series.FirstAired = show.first_aired;
series.Overview = show.overview;
series.Runtime = show.runtime;
series.Network = show.network;
series.AirTime = show.air_time;
series.Images.Add(new MediaCover.MediaCover { CoverType = MediaCoverTypes.Banner, Url = show.images.banner });
series.Images.Add(new MediaCover.MediaCover { CoverType = MediaCoverTypes.Poster, Url = show.images.poster });
series.Images.Add(new MediaCover.MediaCover { CoverType = MediaCoverTypes.Fanart, Url = show.images.fanart });
return series;
}
private static Episode MapEpisode(Trakt.Episode traktEpisode)
{
var episode = new Episode();
episode.Overview = traktEpisode.overview;
episode.SeasonNumber = traktEpisode.season;
episode.EpisodeNumber = traktEpisode.episode;
episode.EpisodeNumber = traktEpisode.number;
episode.TvDbEpisodeId = traktEpisode.tvdb_id;
episode.Title = traktEpisode.title;
episode.AirDate = traktEpisode.first_aired;
return episode;
}
}
}

@ -1,160 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
using NzbDrone.Common;
namespace NzbDrone.Core.MetadataSource
{
public class TvDbProxy
{
public const string TVDB_APIKEY = "5D2D188E86E07F4F";
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly Tvdb.Tvdb _handlerV2;
public TvDbProxy()
{
_handlerV2 = new Tvdb.Tvdb(TVDB_APIKEY);
}
public virtual List<Series> SearchSeries(string title)
{
logger.Debug("Searching TVDB for '{0}'", title);
if (title.Contains(" & "))
{
title = title.Replace(" & ", " ");
}
var searchResult = _handlerV2.SearchSeries(title).Select(tvdbSeriesSearchItem => new Series
{
TvDbId = tvdbSeriesSearchItem.seriesid,
Title = tvdbSeriesSearchItem.SeriesName,
FirstAired = tvdbSeriesSearchItem.FirstAired,
Overview = tvdbSeriesSearchItem.Overview
}).ToList();
logger.Debug("Search for '{0}' returned {1} possible results", title, searchResult.Count);
return searchResult;
}
public virtual Series GetSeries(int tvDbSeriesId)
{
var tvDbSeries = _handlerV2.GetSeriesBaseRecord("http://thetvdb.com", tvDbSeriesId);
var series = new Series();
series.Title = tvDbSeries.SeriesName;
series.AirTime = CleanAirsTime(tvDbSeries.Airs_Time);
series.Overview = tvDbSeries.Overview;
series.Status = tvDbSeries.Status == "Continuing" ? SeriesStatusType.Continuing : SeriesStatusType.Ended;
series.Language = tvDbSeries.Language ?? string.Empty;
series.CleanTitle = Parser.NormalizeTitle(tvDbSeries.SeriesName);
series.LastInfoSync = DateTime.Now;
if (tvDbSeries.Runtime.HasValue)
{
series.Runtime = Convert.ToInt32(tvDbSeries.Runtime);
}
if (!string.IsNullOrWhiteSpace(tvDbSeries.banner))
{
series.Covers.Value.Add(new MediaCover.MediaCover { CoverType = MediaCoverTypes.Banner, Url = tvDbSeries.banner, SeriesId = series.Id });
}
if (!string.IsNullOrWhiteSpace(tvDbSeries.fanart))
{
series.Covers.Value.Add(new MediaCover.MediaCover { CoverType = MediaCoverTypes.Fanart, Url = tvDbSeries.fanart, SeriesId = series.Id });
}
if (!string.IsNullOrWhiteSpace(tvDbSeries.poster))
{
series.Covers.Value.Add(new MediaCover.MediaCover { CoverType = MediaCoverTypes.Poster, Url = tvDbSeries.poster, SeriesId = series.Id });
}
series.Network = tvDbSeries.Network;
if (tvDbSeries.FirstAired.HasValue && tvDbSeries.FirstAired.Value.Year > 1900)
{
series.FirstAired = tvDbSeries.FirstAired.Value.Date;
}
else
{
series.FirstAired = null;
}
return series;
}
public virtual IList<Episode> GetEpisodes(int tvDbSeriesId)
{
var seriesRecord = _handlerV2.GetSeriesFullRecord("http://thetvdb.com", tvDbSeriesId);
var tvdbEpisodes = seriesRecord.Episodes.OrderByDescending(e => e.FirstAired).ThenByDescending(e => e.EpisodeName)
.GroupBy(e => e.seriesid.ToString("000000") + e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000"))
.Select(e => e.First());
var episodes = new List<Episode>();
foreach (var tvDbEpisode in tvdbEpisodes)
{
var episode = new Episode();
episode.TvDbEpisodeId = tvDbEpisode.id;
episode.EpisodeNumber = tvDbEpisode.EpisodeNumber;
episode.SeasonNumber = tvDbEpisode.SeasonNumber;
episode.AbsoluteEpisodeNumber = tvDbEpisode.absolute_number.ParseInt32();
episode.Title = tvDbEpisode.EpisodeName;
episode.Overview = tvDbEpisode.Overview;
if (tvDbEpisode.FirstAired.Year > 1900)
{
episode.AirDate = tvDbEpisode.FirstAired.Date;
}
else
{
episode.AirDate = null;
}
episodes.Add(episode);
}
return episodes;
}
/// <summary>
/// Cleans up the AirsTime Component from TheTVDB since it can be garbage that comes in.
/// </summary>
/// <param name = "rawTime">The TVDB AirsTime</param>
/// <returns>String that contains the AirTimes</returns>
private static readonly Regex timeRegex = new Regex(@"^(?<time>\d+:?\d*)\W*(?<meridiem>am|pm)?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static string CleanAirsTime(string rawTime)
{
var match = timeRegex.Match(rawTime);
var time = match.Groups["time"].Value;
var meridiem = match.Groups["meridiem"].Value;
//Lets assume that a string that doesn't contain a Merideim is aired at night... So we'll add it
if (String.IsNullOrEmpty(meridiem))
meridiem = "PM";
DateTime dateTime;
if (String.IsNullOrEmpty(time) || !DateTime.TryParse(time + " " + meridiem.ToUpper(), out dateTime))
return String.Empty;
return dateTime.ToString("hh:mm tt");
}
}
}

@ -1,71 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Providers;
using NzbDrone.Core.ReferenceData;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model.TvRage;
namespace NzbDrone.Core.MetadataSource
{
public class TvRageMappingProvider
{
private readonly ISceneMappingService _sceneMappingService;
private readonly TvRageProxy _tvRageProxy;
private readonly IEpisodeService _episodeService;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public TvRageMappingProvider(ISceneMappingService sceneMappingService,
TvRageProxy tvRageProxy, IEpisodeService episodeService)
{
_sceneMappingService = sceneMappingService;
_tvRageProxy = tvRageProxy;
_episodeService = episodeService;
}
public TvRageMappingProvider()
{
}
public Series FindMatchingTvRageSeries(Series series)
{
var firstEpisode = _episodeService.GetEpisode(series.Id, 1, 1);
var cleanName = _sceneMappingService.GetCleanName(series.Id);
var results = _tvRageProxy.SearchSeries(series.Title);
var result = ProcessResults(results, series, cleanName, firstEpisode);
if (result != null)
{
logger.Trace("TV Rage: {0} matches TVDB: {1}", result.Name, series.Title);
series.TvRageId = result.ShowId;
series.TvRageTitle = result.Name;
series.UtcOffset = _tvRageProxy.GetSeries(result.ShowId).UtcOffset;
}
return series;
}
public TvRageSearchResult ProcessResults(IList<TvRageSearchResult> searchResults, Series series, string sceneCleanName, Episode firstEpisode)
{
foreach (var result in searchResults)
{
if (Parser.NormalizeTitle(result.Name).Equals(series.CleanTitle))
return result;
if (!String.IsNullOrWhiteSpace(sceneCleanName) && Parser.NormalizeTitle(result.Name).Equals(sceneCleanName))
return result;
if (series.FirstAired.HasValue && result.Started == series.FirstAired.Value)
return result;
if (firstEpisode != null && firstEpisode.AirDate.HasValue && result.Started == firstEpisode.AirDate.Value)
return result;
}
return null;
}
}
}

@ -1,166 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Helpers;
using NzbDrone.Core.Model.TvRage;
namespace NzbDrone.Core.MetadataSource
{
public class TvRageProxy
{
private readonly HttpProvider _httpProvider;
private const string TVRAGE_APIKEY = "NW4v0PSmQIoVmpbASLdD";
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public TvRageProxy(HttpProvider httpProvider)
{
_httpProvider = httpProvider;
}
public TvRageProxy()
{
}
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 = s.Element("showid").ConvertTo<Int32>();
show.Name = s.Element("name").Value;
show.Link = s.Element("link").Value;
show.Country = s.Element("country").Value;
show.Started = s.Element("started").ConvertTo<DateTime>();
show.Ended = s.Element("ended").ConvertTo<DateTime>();
if (show.Ended < new DateTime(1900, 1, 1))
show.Ended = null;
show.Seasons = s.Element("seasons").ConvertTo<Int32>();
show.Status = s.Element("status").Value;
show.RunTime = s.Element("seasons").ConvertTo<Int32>();
show.AirTime = s.Element("airtime").ConvertTo<DateTime>();
show.AirDay = s.Element("airday").ConvertToDayOfWeek();
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
{
if(s.Element("showid") == null)
{
logger.Warn("TvRage did not return valid series info for id: {0}", id);
return null;
}
var show = new TvRageSeries();
show.ShowId = s.Element("showid").ConvertTo<Int32>();
show.Name = s.Element("showname").Value;
show.Link = s.Element("showlink").Value;
show.Seasons = s.Element("seasons").ConvertTo<Int32>();
show.Started = s.Element("started").ConvertTo<Int32>();
show.StartDate = s.Element("startdate").ConvertTo<DateTime>();
show.Ended = s.Element("ended").ConvertTo<DateTime>();
show.OriginCountry = s.Element("origin_country").Value;
show.Status = s.Element("status").Value;
show.RunTime = s.Element("runtime").ConvertTo<Int32>();
show.Network = s.Element("network").Value;
show.AirTime = s.Element("airtime").ConvertTo<DateTime>();
show.AirDay = s.Element("airday").ConvertToDayOfWeek();
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 = e.Element("epnum").ConvertTo<Int32>();
episode.SeasonNumber = e.Element("seasonnum").ConvertTo<Int32>();
episode.ProductionCode = e.Element("prodnum").Value;
episode.AirDate = e.Element("airdate").ConvertTo<DateTime>();
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;
}
}
}

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

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

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

@ -274,6 +274,20 @@
<Compile Include="MediaFiles\Events\EpisodeFileDeletedEvent.cs" />
<Compile Include="MediaFiles\GhostFileCleanupService.cs" />
<Compile Include="MediaFiles\MediaFileRepository.cs" />
<Compile Include="MetadataSource\IProvideEpisodeInfo.cs" />
<Compile Include="MetadataSource\IProvideSeriesInfo.cs" />
<Compile Include="MetadataSource\ISearchForNewSeries.cs" />
<Compile Include="MetadataSource\TraktProxy.cs" />
<Compile Include="MetadataSource\Trakt\Actor.cs" />
<Compile Include="MetadataSource\Trakt\Episode.cs" />
<Compile Include="MetadataSource\Trakt\Images.cs" />
<Compile Include="MetadataSource\Trakt\People.cs" />
<Compile Include="MetadataSource\Trakt\Ratings.cs" />
<Compile Include="MetadataSource\Trakt\Season.cs" />
<Compile Include="MetadataSource\Trakt\Show.cs" />
<Compile Include="MetadataSource\Trakt\Stats.cs" />
<Compile Include="MetadataSource\Trakt\TopEpisode.cs" />
<Compile Include="MetadataSource\Trakt\TopWatcher.cs" />
<Compile Include="Organizer\EpisodeSortingType.cs" />
<Compile Include="Organizer\FileNameBuilder.cs" />
<Compile Include="Model\DownloadClientType.cs" />
@ -322,9 +336,6 @@
<Compile Include="Download\Clients\Sabnzbd\SabQueueItem.cs" />
<Compile Include="Download\Clients\Sabnzbd\SabVersionModel.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\UpdatePackage.cs" />
<Compile Include="Model\Xbmc\ActionType.cs" />
@ -356,8 +367,6 @@
<Compile Include="Model\Xbmc\TvShowResponse.cs" />
<Compile Include="Model\Xbmc\TvShow.cs" />
<Compile Include="Model\Xbmc\VersionResult.cs" />
<Compile Include="MetadataSource\TvRageMappingProvider.cs" />
<Compile Include="MetadataSource\TvRageProxy.cs" />
<Compile Include="Providers\XemCommunicationProvider.cs" />
<Compile Include="Providers\XemProvider.cs" />
<Compile Include="Qualities\Quality.cs" />
@ -481,9 +490,6 @@
<Compile Include="Providers\SmtpProvider.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="MetadataSource\TvDbProxy.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\TwitterProvider.cs">
<SubType>Code</SubType>
</Compile>
@ -519,21 +525,6 @@
<Compile Include="ReferenceData\SceneMapping.cs" />
<Compile Include="Tv\Series.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tvdb\Tvdb.cs" />
<Compile Include="Tvdb\Tvdb.Sync.cs" />
<Compile Include="Tvdb\TvdbActor.cs" />
<Compile Include="Tvdb\TvdbAsyncResult.cs" />
<Compile Include="Tvdb\TvdbBanner.cs" />
<Compile Include="Tvdb\TvdbEpisodes.cs" />
<Compile Include="Tvdb\TvdbLanguages.cs" />
<Compile Include="Tvdb\TvdbMirrors.cs" />
<Compile Include="Tvdb\TvdbSeriesBase.cs" />
<Compile Include="Tvdb\TvdbSeriesFull.cs" />
<Compile Include="Tvdb\TvdbSeriesSearch.cs" />
<Compile Include="Tvdb\TvdbSeriesSearchItem.cs" />
<Compile Include="Tvdb\TvdbServerTime.cs" />
<Compile Include="Tvdb\TvdbUpdate.cs" />
<Compile Include="Tvdb\TvdbUpdateItems.cs" />
<Compile Include="Tv\SeriesStatusType.cs" />
</ItemGroup>
<ItemGroup>

@ -46,16 +46,16 @@ namespace NzbDrone.Core.Tv
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly TvDbProxy _tvDbProxy;
private readonly IProvideEpisodeInfo _episodeInfoProxy;
private readonly ISeasonRepository _seasonRepository;
private readonly IEpisodeRepository _episodeRepository;
private readonly IEventAggregator _eventAggregator;
private readonly IConfigService _configService;
private readonly Logger _logger;
public EpisodeService(TvDbProxy tvDbProxyProxy, ISeasonRepository seasonRepository, IEpisodeRepository episodeRepository, IEventAggregator eventAggregator, IConfigService configService, Logger logger)
public EpisodeService(IProvideEpisodeInfo episodeInfoProxy, ISeasonRepository seasonRepository, IEpisodeRepository episodeRepository, IEventAggregator eventAggregator, IConfigService configService, Logger logger)
{
_tvDbProxy = tvDbProxyProxy;
_episodeInfoProxy = episodeInfoProxy;
_seasonRepository = seasonRepository;
_episodeRepository = episodeRepository;
_eventAggregator = eventAggregator;
@ -193,7 +193,7 @@ namespace NzbDrone.Core.Tv
var successCount = 0;
var failCount = 0;
var tvdbEpisodes = _tvDbProxy.GetEpisodes(series.TvDbId);
var tvdbEpisodes = _episodeInfoProxy.GetEpisodeInfo(series.TvDbId);
var seriesEpisodes = GetEpisodeBySeries(series.Id);
var updateList = new List<Episode>();

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.MetadataSource.Trakt;
using NzbDrone.Core.Model;
using NzbDrone.Core.Qualities;
@ -17,7 +19,7 @@ namespace NzbDrone.Core.Tv
{
public Series()
{
Covers = new LazyList<MediaCover.MediaCover>();
Images =new List<MediaCover.MediaCover>();
}
public int TvDbId { get; set; }
@ -34,7 +36,7 @@ namespace NzbDrone.Core.Tv
public DateTime? LastInfoSync { get; set; }
public DateTime? LastDiskSync { get; set; }
public int Runtime { get; set; }
public LazyList<MediaCover.MediaCover> Covers { get; set; }
public List<MediaCover.MediaCover> Images { get; set; }
public SeriesTypes SeriesType { get; set; }
public BacklogSettingType BacklogSetting { get; set; }
public string Network { get; set; }

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using NzbDrone.Core.Datastore;
@ -12,6 +11,7 @@ namespace NzbDrone.Core.Tv
Series GetByTitle(string cleanTitle);
Series FindByTvdbId(int tvdbId);
void SetSeriesType(int seriesId, SeriesTypes seriesTypes);
void SetTvRageId(int seriesId, int tvRageId);
}
public class SeriesRepository : BasicRepository<Series>, ISeriesRepository
@ -45,5 +45,10 @@ namespace NzbDrone.Core.Tv
{
SetFields(new Series { Id = seriesId, SeriesType = seriesType }, s => s.SeriesType);
}
public void SetTvRageId(int seriesId, int tvRageId)
{
SetFields(new Series { Id = seriesId, TvRageId = tvRageId }, s => s.TvRageId);
}
}
}

@ -30,8 +30,7 @@ namespace NzbDrone.Core.Tv
{
private readonly ISeriesRepository _seriesRepository;
private readonly IConfigService _configService;
private readonly TvDbProxy _tvDbProxy;
private readonly TvRageMappingProvider _tvRageMappingProvider;
private readonly IProvideSeriesInfo _seriesInfoProxy;
private readonly IEventAggregator _eventAggregator;
private readonly IQualityProfileService _qualityProfileService;
private readonly Logger _logger;
@ -40,14 +39,13 @@ namespace NzbDrone.Core.Tv
private readonly ISceneMappingService _sceneNameMappingService;
public SeriesService(ISeriesRepository seriesRepository, IConfigService configServiceService,
TvDbProxy tvDbProxyProxy, ISceneMappingService sceneNameMappingService,
TvRageMappingProvider tvRageMappingProvider, IEventAggregator eventAggregator, IQualityProfileService qualityProfileService, Logger logger)
IProvideSeriesInfo seriesInfoProxy, ISceneMappingService sceneNameMappingService,
IEventAggregator eventAggregator, IQualityProfileService qualityProfileService, Logger logger)
{
_seriesRepository = seriesRepository;
_configService = configServiceService;
_tvDbProxy = tvDbProxyProxy;
_seriesInfoProxy = seriesInfoProxy;
_sceneNameMappingService = sceneNameMappingService;
_tvRageMappingProvider = tvRageMappingProvider;
_eventAggregator = eventAggregator;
_qualityProfileService = qualityProfileService;
_logger = logger;
@ -63,7 +61,7 @@ namespace NzbDrone.Core.Tv
public Series UpdateSeriesInfo(int seriesId)
{
var series = _seriesRepository.Get(seriesId);
var tvDbSeries = _tvDbProxy.GetSeries(series.TvDbId);
var tvDbSeries = _seriesInfoProxy.GetSeriesInfo(series.TvDbId);
series.Title = tvDbSeries.Title;
series.AirTime = tvDbSeries.AirTime;
@ -73,23 +71,9 @@ namespace NzbDrone.Core.Tv
series.CleanTitle = tvDbSeries.CleanTitle;
series.LastInfoSync = DateTime.Now;
series.Runtime = tvDbSeries.Runtime;
series.Covers = tvDbSeries.Covers;
series.Images = tvDbSeries.Images;
series.Network = tvDbSeries.Network;
series.FirstAired = tvDbSeries.FirstAired;
try
{
if (series.TvRageId == 0)
{
series = _tvRageMappingProvider.FindMatchingTvRageSeries(series);
}
}
catch (Exception ex)
{
_logger.ErrorException("Error getting TvRage information for series: " + series.Title, ex);
}
_seriesRepository.Update(series);
_eventAggregator.Publish(new SeriesUpdatedEvent(series));
@ -164,6 +148,11 @@ namespace NzbDrone.Core.Tv
}
public void SetTvRageId(int seriesId, int tvRageId)
{
_seriesRepository.SetTvRageId(seriesId, tvRageId);
}
public Series FindByTvdbId(int tvdbId)
{
return _seriesRepository.FindByTvdbId(tvdbId);

@ -1,223 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using RestSharp;
using RestSharp.Deserializers;
namespace NzbDrone.Core.Tvdb
{
public partial class Tvdb
{
private T ProcessRequest <T>(RestRequest request)
where T: new()
{
return ProcessRequest<T>(BASE_URL, request);
}
private T ProcessRequest <T>(string url, RestRequest request)
where T: new()
{
var client = new RestClient(url);
client.AddHandler("text/xml", new DotNetXmlDeserializer());
if(Timeout.HasValue)
client.Timeout = Timeout.Value;
#if !WINDOWS_PHONE
if(Proxy != null)
client.Proxy = Proxy;
#endif
Error = null;
//var resp = client.Execute(request);
IRestResponse<T> resp = client.Execute<T>(request);
ResponseContent = resp.Content;
ResponseHeaders = resp.Headers.ToDictionary(k => k.Name, v => v.Value);
if(resp.ResponseStatus == ResponseStatus.Completed)
{
return resp.Data;
// Manual deserialization
//TextReader r = new StringReader(resp.Content);
//XmlSerializer s = new XmlSerializer(typeof(T));
//return (T)s.Deserialize(r);
}
else
{
if(resp.ErrorException != null)
throw resp.ErrorException;
else
Error = resp.ErrorMessage;
}
return default(T);
}
public TvdbMirrors GetMirrors()
{
return ProcessRequest<TvdbMirrors>(BuildGetMirrorsRequest());
}
/// <summary>
/// http://www.thetvdb.com/api/Updates.php?type=none
/// </summary>
/// <returns></returns>
public TvdbServerTime GetServerTime()
{
return ProcessRequest<TvdbServerTime>(BuildGetServerTimeRequest());
}
/// <summary>
/// http://www.thetvdb.com/api/{apikey}/languages.xml
/// </summary>
/// <returns></returns>
public List<TvdbLanguage> GetLanguages()
{
var root = ProcessRequest<TvdbLanguagesRoot>(BuildGetLanguagesRequest());
if(root != null)
return root.Languages;
return null;
}
/// <summary>
/// http://www.thetvdb.com/api/GetSeries.php?seriesname={series}
/// </summary>
/// <param name="search"></param>
/// <returns></returns>
public List<TvdbSeriesSearchItem> SearchSeries(string search)
{
var root = ProcessRequest<TvdbSeriesSearchRoot>(BuildGetSearchSeriesRequest(search));
if(root != null)
return root.Series;
return null;
}
/// <summary>
/// http://thetvdb.com/api/{apikey}/series/79349/en.xml
/// </summary>
/// <param name="XMLMirror"></param>
/// <param name="SeriesId"></param>
/// <param name="Language"></param>
/// <returns></returns>
public TvdbSeriesBase GetSeriesBaseRecord(string XMLMirror, int SeriesId, string Language)
{
if(string.IsNullOrEmpty(Language))
Language = "en";
var root = ProcessRequest<TvdbSeriesRecordRoot>(XMLMirror,
BuildGetSeriesBaseRecordRequest(SeriesId, Language));
if(root != null)
return root.Series;
return null;
}
public TvdbSeriesBase GetSeriesBaseRecord(string XMLMirror, int SeriesId)
{
return GetSeriesBaseRecord(XMLMirror, SeriesId, null);
}
/// <summary>
/// http://thetvdb.com/api/{apikey}/series/79349/all/en.xml
/// </summary>
/// <param name="XMLMirror"></param>
/// <param name="SeriesId"></param>
/// <param name="Language"></param>
/// <returns></returns>
public TvdbSeriesFull GetSeriesFullRecord(string XMLMirror, int SeriesId, string Language)
{
if(string.IsNullOrEmpty(Language))
Language = "en";
return ProcessRequest<TvdbSeriesFull>(XMLMirror, BuildGetSeriesFullRecordRequest(SeriesId, Language));
}
public TvdbSeriesFull GetSeriesFullRecord(string MirrorPath, int SeriesId)
{
return GetSeriesFullRecord(MirrorPath, SeriesId, null);
}
/// <summary>
/// http://thetvdb.com/api/{apikey}/series/79349/banners.xml
/// </summary>
/// <param name="XMLMirror"></param>
/// <param name="SeriesId"></param>
/// <returns></returns>
public List<TvdbBanner> GetSeriesBanners(string XMLMirror, int SeriesId)
{
var root = ProcessRequest<TvdbBannerRoot>(XMLMirror, BuildGetSeriesBannersRequest(SeriesId));
if(root != null)
return root.Banners;
return null;
}
/// <summary>
/// http://thetvdb.com/api/{apikey}/series/79349/actors.xml
/// </summary>
/// <param name="XMLMirror"></param>
/// <param name="SeriesId"></param>
/// <returns></returns>
public List<TvdbActor> GetSeriesActors(string XMLMirror, int SeriesId)
{
var root = ProcessRequest<TvdbActorRoot>(XMLMirror, BuildGetSeriesActorsRequest(SeriesId));
if(root != null)
return root.Actors;
return null;
}
public TvdbEpisode GetEpisode(string XMLMirror, int EpisodeId, string Language)
{
if(string.IsNullOrEmpty(Language))
Language = "en";
var root = ProcessRequest<TvdbEpisodeRoot>(XMLMirror, BuildGetEpisodeRequest(EpisodeId, Language));
if(root != null)
return root.Episode;
return null;
}
public TvdbEpisode GetEpisode(string XMLMirror, int EpisodeId)
{
return GetEpisode(XMLMirror, EpisodeId, null);
}
public TvdbEpisode GetSeriesEpisode(string XMLMirror, int SeriesId, int SeasonNum, int EpisodeNum,
string Language)
{
if(string.IsNullOrEmpty(Language))
Language = "en";
var root = ProcessRequest<TvdbEpisodeRoot>(XMLMirror,
BuildGetSeriesEpisodeRequest(SeriesId, SeasonNum, EpisodeNum,
Language));
if(root != null)
return root.Episode;
return null;
}
public TvdbEpisode GetSeriesEpisode(string XMLMirror, int SeriesId, int SeasonNum, int EpisodeNum)
{
return GetSeriesEpisode(XMLMirror, SeriesId, SeasonNum, EpisodeNum, null);
}
public TvdbUpdates GetUpdates(string XMLMirror, TvdbUpdatePeriod Period)
{
return ProcessRequest<TvdbUpdates>(XMLMirror, BuildGetUpdatesRequest(Period));
}
public TvdbUpdateItems GetUpdatesSince(string XMLMirror, Int64 LastTime)
{
return ProcessRequest<TvdbUpdateItems>(XMLMirror, BuildGetUpdatesSinceRequest(LastTime));
}
}
}

@ -1,205 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using RestSharp;
namespace NzbDrone.Core.Tvdb
{
public partial class Tvdb
{
private const string BASE_URL = "http://www.thetvdb.com/api";
public string ApiKey { get; set; }
public string Error { get; set; }
/// <summary>
/// String representation of response content
/// </summary>
public string ResponseContent { get; set; }
/// <summary>
/// Dictionary of Header values in response
/// http://help.themoviedb.org/kb/api/content-versioning
/// </summary>
public Dictionary<string, object> ResponseHeaders { get; set; }
#if !WINDOWS_PHONE
/// <summary>
/// Proxy to use for requests made. Passed on to underying WebRequest if set.
/// </summary>
public IWebProxy Proxy { get; set; }
#endif
/// <summary>
/// Timeout in milliseconds to use for requests made.
/// </summary>
public int? Timeout { get; set; }
public Tvdb(string apiKey)
{
ApiKey = apiKey;
Error = null;
Timeout = null;
}
#region Helper methods
public static string GetImageUrl(string BannerMirror, string filename)
{
return string.Format("{0}/banners/{1}", BannerMirror, filename);
}
#if !WINDOWS_PHONE
public static byte[] GetImage(string BannerMirror, string filename)
{
return GetImage(GetImageUrl(BannerMirror, filename));
}
public static byte[] GetImage(string url)
{
return new WebClient().DownloadData(url);
}
#endif
#endregion
#region Build Requests
private RestRequest BuildGetMirrorsRequest(object UserState = null)
{
var request = new RestRequest("{apikey}/mirrors.xml", Method.GET);
request.AddUrlSegment("apikey", ApiKey);
if(UserState != null)
request.UserState = UserState;
return request;
}
private static RestRequest BuildGetServerTimeRequest(object UserState = null)
{
var request = new RestRequest("Updates.php", Method.GET);
request.AddParameter("type", "none");
if(UserState != null)
request.UserState = UserState;
return request;
}
private RestRequest BuildGetLanguagesRequest(object UserState = null)
{
var request = new RestRequest("{apikey}/languages.xml", Method.GET);
request.AddUrlSegment("apikey", ApiKey);
if(UserState != null)
request.UserState = UserState;
return request;
}
private static RestRequest BuildGetSearchSeriesRequest(string search, object UserState = null)
{
var request = new RestRequest("GetSeries.php", Method.GET);
request.AddParameter("seriesname", search);
if(UserState != null)
request.UserState = UserState;
return request;
}
private RestRequest BuildGetSeriesBaseRecordRequest(int SeriesId, string Language, object UserState = null)
{
var request = new RestRequest("api/{apikey}/series/{id}/{lang}.xml");
request.AddUrlSegment("apikey", ApiKey);
request.AddUrlSegment("id", SeriesId.ToString());
request.AddUrlSegment("lang", Language);
if(UserState != null)
request.UserState = UserState;
return request;
}
private RestRequest BuildGetSeriesFullRecordRequest(int SeriesId, string Language, object UserState = null)
{
var request = new RestRequest("api/{apikey}/series/{id}/all/{lang}.xml");
request.AddUrlSegment("apikey", ApiKey);
request.AddUrlSegment("id", SeriesId.ToString());
request.AddUrlSegment("lang", Language);
if(UserState != null)
request.UserState = UserState;
return request;
}
private RestRequest BuildGetSeriesBannersRequest(int SeriesId, object UserState = null)
{
var request = new RestRequest("api/{apikey}/series/{id}/banners.xml");
request.AddUrlSegment("apikey", ApiKey);
request.AddUrlSegment("id", SeriesId.ToString());
if(UserState != null)
request.UserState = UserState;
return request;
}
private RestRequest BuildGetSeriesActorsRequest(int SeriesId, object UserState = null)
{
var request = new RestRequest("api/{apikey}/series/{id}/actors.xml");
request.AddUrlSegment("apikey", ApiKey);
request.AddUrlSegment("id", SeriesId.ToString());
if(UserState != null)
request.UserState = UserState;
return request;
}
private RestRequest BuildGetEpisodeRequest(int EpisodeId, string Language, object UserState = null)
{
var request = new RestRequest("api/{apikey}/episodes/{id}/{lang}.xml");
request.AddUrlSegment("apikey", ApiKey);
request.AddUrlSegment("id", EpisodeId.ToString());
request.AddUrlSegment("lang", Language);
if(UserState != null)
request.UserState = UserState;
return request;
}
private RestRequest BuildGetSeriesEpisodeRequest(int SeriesId, int SeasonNum, int EpisodeNum, string Language,
object UserState = null)
{
var request = new RestRequest("api/{apikey}/series/{id}/default/{season}/{episode}/{lang}.xml");
request.AddUrlSegment("apikey", ApiKey);
request.AddUrlSegment("id", SeriesId.ToString());
request.AddUrlSegment("season", SeasonNum.ToString());
request.AddUrlSegment("episode", EpisodeNum.ToString());
request.AddUrlSegment("lang", Language);
if(UserState != null)
request.UserState = UserState;
return request;
}
private RestRequest BuildGetUpdatesRequest(TvdbUpdatePeriod Period, object UserState = null)
{
var request = new RestRequest("api/{apikey}/updates/updates_{period}.xml");
request.AddUrlSegment("apikey", ApiKey);
request.AddUrlSegment("period", Period.ToString());
if(UserState != null)
request.UserState = UserState;
return request;
}
private static RestRequest BuildGetUpdatesSinceRequest(Int64 LastTime, object UserState = null)
{
var request = new RestRequest("api/Updates.php?type=all&time={time}");
request.AddUrlSegment("time", LastTime.ToString());
if(UserState != null)
request.UserState = UserState;
return request;
}
#endregion
}
}

@ -1,36 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Actors")]
public class TvdbActorRoot
{
public TvdbActorRoot()
{
Actors = new List<TvdbActor>();
}
[XmlElement(ElementName = "Actor")]
public List<TvdbActor> Actors { get; set; }
}
public class TvdbActor
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public string Image { get; set; }
[XmlElement]
public string Name { get; set; }
[XmlElement]
public string Role { get; set; }
[XmlElement]
public int SortOrder { get; set; }
}
}

@ -1,10 +0,0 @@
using System.Linq;
namespace NzbDrone.Core.Tvdb
{
public class TvdbAsyncResult <T>
{
public T Data { get; set; }
public object UserState { get; set; }
}
}

@ -1,86 +0,0 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Banners")]
public class TvdbBannerRoot
{
public TvdbBannerRoot()
{
Banners = new List<TvdbBanner>();
}
[XmlElement(ElementName = "Banner")]
public List<TvdbBanner> Banners { get; set; }
}
public class TvdbBanner
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public string BannerPath { get; set; }
[XmlElement]
public string BannerType { get; set; }
[XmlElement]
public string BannerType2 { get; set; }
[XmlElement]
public string Colors { get; set; }
[XmlElement]
public string Language { get; set; }
[XmlElement("Rating")]
public string RatingString
{
get { return Rating.HasValue ? Rating.Value.ToString() : null; }
set
{
double d;
if(double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out d))
Rating = d;
else
Rating = null;
}
}
[XmlIgnore]
public double? Rating { get; set; }
[XmlElement]
public int? RatingCount { get; set; }
[XmlElement(ElementName = "SeriesName")]
public string SeriesNameString
{
get { return SeriesName.HasValue ? SeriesName.Value.ToString() : null; }
set
{
bool b;
if(bool.TryParse(value, out b))
SeriesName = b;
else
SeriesName = null;
}
}
[XmlIgnore]
public bool? SeriesName { get; set; }
[XmlElement]
public string ThumbnailPath { get; set; }
[XmlElement]
public string VignettePath { get; set; }
[XmlElement]
public string Season { get; set; }
}
}

@ -1,132 +0,0 @@
using System;
using System.Globalization;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Data")]
public class TvdbEpisodeRoot
{
[XmlElement]
public TvdbEpisode Episode { get; set; }
}
public class TvdbEpisode
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public string Combined_episodenumber { get; set; }
[XmlElement]
public string Combined_season { get; set; }
[XmlElement]
public string DVD_chapter { get; set; }
[XmlElement]
public string DVD_discid { get; set; }
[XmlElement]
public string DVD_episodenumber { get; set; }
[XmlElement]
public string DVD_season { get; set; }
[XmlElement]
public string Director { get; set; }
[XmlElement(ElementName = "EpImgFlag")]
public string EpImgFlagString
{
get { return EpImgFlag.HasValue ? EpImgFlag.Value.ToString() : null; }
set
{
int i;
if(int.TryParse(value, out i))
EpImgFlag = i;
else
EpImgFlag = null;
}
}
[XmlIgnore]
public int? EpImgFlag { get; set; }
[XmlElement]
public string EpisodeName { get; set; }
[XmlElement]
public int EpisodeNumber { get; set; }
[XmlElement]
public DateTime FirstAired { get; set; }
[XmlElement]
public string GuestStars { get; set; }
[XmlElement]
public string IMDB_ID { get; set; }
[XmlElement]
public string Language { get; set; }
[XmlElement]
public string Overview { get; set; }
[XmlElement]
public string ProductionCode { get; set; }
[XmlElement("Rating")]
public string RatingString
{
get { return Rating.HasValue ? Rating.Value.ToString() : null; }
set
{
double d;
if(double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out d))
Rating = d;
else
Rating = null;
}
}
[XmlIgnore]
public double? Rating { get; set; }
[XmlElement]
public int? RatingCount { get; set; }
[XmlElement]
public int SeasonNumber { get; set; }
[XmlElement]
public string Writer { get; set; }
[XmlElement]
public string absolute_number { get; set; }
[XmlElement]
public string airsafter_season { get; set; }
[XmlElement]
public string airsbefore_episode { get; set; }
[XmlElement]
public string airsbefore_season { get; set; }
[XmlElement]
public string filename { get; set; }
[XmlElement]
public Int64 lastupdated { get; set; }
[XmlElement]
public int? seasonid { get; set; }
[XmlElement]
public int seriesid { get; set; }
}
}

@ -1,30 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Languages")]
public class TvdbLanguagesRoot
{
public TvdbLanguagesRoot()
{
Languages = new List<TvdbLanguage>();
}
[XmlElement(ElementName = "Language")]
public List<TvdbLanguage> Languages { get; set; }
}
public class TvdbLanguage
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public string name { get; set; }
[XmlElement]
public string abbreviation { get; set; }
}
}

@ -1,40 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Mirrors")]
public class TvdbMirrors
{
[XmlElement(ElementName = "Mirror")]
public List<TvdbMirror> Mirrors { get; set; }
}
public class TvdbMirror
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public string mirrorpath { get; set; }
[XmlElement]
public int typemask { get; set; }
public bool IsXMLMirror
{
get { return (typemask & 1) != 0; }
}
public bool IsBannerMirror
{
get { return (typemask & 2) != 0; }
}
public bool IsZipMirror
{
get { return (typemask & 4) != 0; }
}
}
}

@ -1,131 +0,0 @@
using System;
using System.Globalization;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Data")]
public class TvdbSeriesRecordRoot
{
[XmlElement]
public TvdbSeriesBase Series { get; set; }
}
public class TvdbSeriesBase
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public string Actors { get; set; }
[XmlElement]
public string Airs_DayOfWeek { get; set; }
[XmlElement]
public string Airs_Time { get; set; }
[XmlElement]
public string ContentRating { get; set; }
[XmlElement(ElementName = "FirstAired")]
public string FirstAiredString
{
get { return FirstAired.HasValue ? FirstAired.Value.ToString("yyyy-MM-dd") : null; }
set
{
DateTime d;
if(DateTime.TryParse(value, out d))
FirstAired = d;
else
FirstAired = null;
}
}
[XmlIgnore]
public DateTime? FirstAired { get; set; }
[XmlElement]
public string Genre { get; set; }
[XmlElement]
public string IMDB_ID { get; set; }
[XmlElement]
public string Language { get; set; }
[XmlElement]
public string Network { get; set; }
[XmlElement]
public string Overview { get; set; }
[XmlElement("Rating")]
public string RatingString
{
get { return Rating.HasValue ? Rating.Value.ToString() : null; }
set
{
double d;
if(double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out d))
Rating = d;
else
Rating = null;
}
}
[XmlIgnore]
public double? Rating { get; set; }
[XmlElement]
public int? RatingCount { get; set; }
[XmlElement]
public int? Runtime { get; set; }
[XmlElement]
public string SeriesIDString
{
get { return SeriesID.HasValue ? SeriesID.Value.ToString() : null; }
set
{
int i;
if(int.TryParse(value, out i))
SeriesID = i;
else
SeriesID = null;
}
}
[XmlIgnore]
public int? SeriesID { get; set; }
[XmlElement]
public string SeriesName { get; set; }
[XmlElement]
public string Status { get; set; }
[XmlElement]
public string added { get; set; }
[XmlElement]
public string addedBy { get; set; }
[XmlElement]
public string banner { get; set; }
[XmlElement]
public string fanart { get; set; }
[XmlElement]
public Int64 lastupdated { get; set; }
[XmlElement]
public string poster { get; set; }
[XmlElement]
public string zap2it_id { get; set; }
}
}

@ -1,21 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Data")]
public class TvdbSeriesFull
{
public TvdbSeriesFull()
{
Episodes = new List<TvdbEpisode>();
}
[XmlElement]
public TvdbSeriesBase Series { get; set; }
[XmlElement(ElementName = "Episode")]
public List<TvdbEpisode> Episodes { get; set; }
}
}

@ -1,18 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Data")]
public class TvdbSeriesSearchRoot
{
public TvdbSeriesSearchRoot()
{
Series = new List<TvdbSeriesSearchItem>();
}
[XmlElement(ElementName = "Series")]
public List<TvdbSeriesSearchItem> Series { get; set; }
}
}

@ -1,50 +0,0 @@
using System;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
public class TvdbSeriesSearchItem
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public int seriesid { get; set; }
[XmlElement]
public string language { get; set; }
[XmlElement]
public string SeriesName { get; set; }
[XmlElement]
public string banner { get; set; }
[XmlElement]
public string Overview { get; set; }
[XmlElement(ElementName = "FirstAired")]
public string FirstAiredString
{
get { return FirstAired.HasValue ? FirstAired.Value.ToString("yyyy-MM-dd") : null; }
set
{
DateTime d;
if(DateTime.TryParse(value, out d))
FirstAired = d;
else
FirstAired = null;
}
}
[XmlIgnore]
public DateTime? FirstAired { get; set; }
[XmlElement]
public string IMDB_ID { get; set; }
[XmlElement]
public string zap2it_id { get; set; }
}
}

@ -1,13 +0,0 @@
using System;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Items")]
public class TvdbServerTime
{
[XmlElement]
public Int64 Time { get; set; }
}
}

@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
public enum TvdbUpdatePeriod
{
day,
week,
month
};
[XmlRoot(ElementName = "Data")]
public class TvdbUpdates
{
public TvdbUpdates()
{
Series = new List<TvdbUpdateSeries>();
}
[XmlAttribute]
public Int64 time { get; set; }
[XmlElement(ElementName = "Series")]
public List<TvdbUpdateSeries> Series { get; set; }
[XmlElement(ElementName = "Episode")]
public List<TvdbUpdateEpisode> Episodes { get; set; }
[XmlElement(ElementName = "Banner")]
public List<TvdbUpdateBanner> Banners { get; set; }
}
public class TvdbUpdateSeries
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public Int64 time { get; set; }
}
public class TvdbUpdateEpisode
{
[XmlElement]
public int id { get; set; }
[XmlElement]
public int Series { get; set; }
[XmlElement]
public Int64 time { get; set; }
}
public class TvdbUpdateBanner
{
/// <summary>
/// fanart, poster, season, series, episode, actors
/// </summary>
[XmlElement]
public string type { get; set; }
[XmlElement]
public string format { get; set; }
[XmlElement]
public int Series { get; set; }
/// <summary>
/// Only appears for season banners
/// </summary>
[XmlElement]
public int? SeasonNum { get; set; }
[XmlElement]
public string language { get; set; }
[XmlElement]
public string path { get; set; }
[XmlElement]
public Int64 time { get; set; }
}
}

@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace NzbDrone.Core.Tvdb
{
[XmlRoot(ElementName = "Items")]
public class TvdbUpdateItems
{
public TvdbUpdateItems()
{
Series = new List<int>();
Episodes = new List<int>();
}
[XmlElement]
public Int64 Time { get; set; }
[XmlElement(ElementName = "Series")]
public List<int> Series { get; set; }
[XmlElement(ElementName = "Episode")]
public List<int> Episodes { get; set; }
}
}

@ -4,6 +4,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToReturnStatement/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertNullableToShortForm/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FunctionRecursiveOnAllPaths/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FPARAMETER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Position/@EntryValue">BOTH_SIDES</s:String>

Loading…
Cancel
Save