diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index 4a877241c..5f7698363 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -181,6 +181,9 @@
False
..\packages\Prowlin.0.9.4456.26422\lib\net40\Prowlin.dll
+
+ ..\packages\RestSharp.104.1\lib\net4\RestSharp.dll
+
..\packages\SignalR.Server.0.5.3\lib\net40\SignalR.dll
@@ -587,6 +590,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NzbDrone.Core/Providers/TvDbProvider.cs b/NzbDrone.Core/Providers/TvDbProvider.cs
index c4fb1826f..cbcc748d7 100644
--- a/NzbDrone.Core/Providers/TvDbProvider.cs
+++ b/NzbDrone.Core/Providers/TvDbProvider.cs
@@ -1,12 +1,12 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
-using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Common;
+using NzbDrone.Core.Tvdb;
using TvdbLib;
using TvdbLib.Cache;
using TvdbLib.Data;
+using TvdbLanguage = TvdbLib.Data.TvdbLanguage;
namespace NzbDrone.Core.Providers
{
@@ -14,14 +14,19 @@ namespace NzbDrone.Core.Providers
{
private readonly EnvironmentProvider _environmentProvider;
public const string TVDB_APIKEY = "5D2D188E86E07F4F";
- private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
+
+
private readonly TvdbHandler _handler;
+ private readonly Tvdb.Tvdb _handlerV2;
+
public TvDbProvider(EnvironmentProvider environmentProvider)
{
_environmentProvider = environmentProvider;
_handler = new TvdbHandler(new XmlCacheProvider(_environmentProvider.GetCacheFolder()), TVDB_APIKEY);
+ _handlerV2 = new Tvdb.Tvdb(TVDB_APIKEY);
}
public TvDbProvider()
@@ -29,30 +34,26 @@ namespace NzbDrone.Core.Providers
}
- public virtual IList SearchSeries(string title)
+ public virtual List SearchSeries(string title)
{
- lock (_handler)
+ logger.Debug("Searching TVDB for '{0}'", title);
+
+ if (title.Contains(" & "))
{
- Logger.Debug("Searching TVDB for '{0}'", title);
-
- if(title.Contains(" & "))
- {
- Logger.Debug("Removing ampersand before searching");
- title = title.Replace(" & ", " ");
- }
-
- var result = _handler.SearchSeries(title);
-
- Logger.Debug("Search for '{0}' returned {1} possible results", title, result.Count);
- return result;
+ title = title.Replace(" & ", " ");
}
+
+ var result = _handlerV2.SearchSeries(title);
+
+ logger.Debug("Search for '{0}' returned {1} possible results", title, result.Count);
+ return result;
}
public virtual TvdbSeries GetSeries(int id, bool loadEpisodes, bool loadActors = false)
{
lock (_handler)
{
- Logger.Debug("Fetching SeriesId'{0}' from tvdb", id);
+ logger.Debug("Fetching SeriesId'{0}' from tvdb", id);
var result = _handler.GetSeries(id, TvdbLanguage.DefaultLanguage, loadEpisodes, loadActors, true, true);
//Remove duplicated episodes
diff --git a/NzbDrone.Core/Tvdb/Tvdb.Sync.cs b/NzbDrone.Core/Tvdb/Tvdb.Sync.cs
new file mode 100644
index 000000000..6ea0904d9
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/Tvdb.Sync.cs
@@ -0,0 +1,223 @@
+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 (RestRequest request)
+ where T: new()
+ {
+ return ProcessRequest(BASE_URL, request);
+ }
+
+ private T ProcessRequest (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 resp = client.Execute(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(BuildGetMirrorsRequest());
+ }
+
+ ///
+ /// http://www.thetvdb.com/api/Updates.php?type=none
+ ///
+ ///
+ public TvdbServerTime GetServerTime()
+ {
+ return ProcessRequest(BuildGetServerTimeRequest());
+ }
+
+ ///
+ /// http://www.thetvdb.com/api/{apikey}/languages.xml
+ ///
+ ///
+ public List GetLanguages()
+ {
+ var root = ProcessRequest(BuildGetLanguagesRequest());
+ if(root != null)
+ return root.Languages;
+
+ return null;
+ }
+
+
+ ///
+ /// http://www.thetvdb.com/api/GetSeries.php?seriesname={series}
+ ///
+ ///
+ ///
+ public List SearchSeries(string search)
+ {
+ var root = ProcessRequest(BuildGetSearchSeriesRequest(search));
+ if(root != null)
+ return root.Series;
+
+ return null;
+ }
+
+ ///
+ /// http://thetvdb.com/api/{apikey}/series/79349/en.xml
+ ///
+ ///
+ ///
+ ///
+ ///
+ public TvdbSeriesBase GetSeriesBaseRecord(string XMLMirror, int SeriesId, string Language)
+ {
+ if(string.IsNullOrEmpty(Language))
+ Language = "en";
+
+ var root = ProcessRequest(XMLMirror,
+ BuildGetSeriesBaseRecordRequest(SeriesId, Language));
+ if(root != null)
+ return root.Series;
+
+ return null;
+ }
+
+ public TvdbSeriesBase GetSeriesBaseRecord(string XMLMirror, int SeriesId)
+ {
+ return GetSeriesBaseRecord(XMLMirror, SeriesId, null);
+ }
+
+ ///
+ /// http://thetvdb.com/api/{apikey}/series/79349/all/en.xml
+ ///
+ ///
+ ///
+ ///
+ ///
+ public TvdbSeriesFull GetSeriesFullRecord(string XMLMirror, int SeriesId, string Language)
+ {
+ if(string.IsNullOrEmpty(Language))
+ Language = "en";
+
+ return ProcessRequest(XMLMirror, BuildGetSeriesFullRecordRequest(SeriesId, Language));
+ }
+
+ public TvdbSeriesFull GetSeriesFullRecord(string MirrorPath, int SeriesId)
+ {
+ return GetSeriesFullRecord(MirrorPath, SeriesId, null);
+ }
+
+ ///
+ /// http://thetvdb.com/api/{apikey}/series/79349/banners.xml
+ ///
+ ///
+ ///
+ ///
+ public List GetSeriesBanners(string XMLMirror, int SeriesId)
+ {
+ var root = ProcessRequest(XMLMirror, BuildGetSeriesBannersRequest(SeriesId));
+ if(root != null)
+ return root.Banners;
+
+ return null;
+ }
+
+ ///
+ /// http://thetvdb.com/api/{apikey}/series/79349/actors.xml
+ ///
+ ///
+ ///
+ ///
+ public List GetSeriesActors(string XMLMirror, int SeriesId)
+ {
+ var root = ProcessRequest(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(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(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(XMLMirror, BuildGetUpdatesRequest(Period));
+ }
+
+ public TvdbUpdateItems GetUpdatesSince(string XMLMirror, Int64 LastTime)
+ {
+ return ProcessRequest(XMLMirror, BuildGetUpdatesSinceRequest(LastTime));
+ }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/Tvdb.cs b/NzbDrone.Core/Tvdb/Tvdb.cs
new file mode 100644
index 000000000..4f4fabefc
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/Tvdb.cs
@@ -0,0 +1,205 @@
+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; }
+
+ ///
+ /// String representation of response content
+ ///
+ public string ResponseContent { get; set; }
+
+ ///
+ /// Dictionary of Header values in response
+ /// http://help.themoviedb.org/kb/api/content-versioning
+ ///
+ public Dictionary ResponseHeaders { get; set; }
+
+#if !WINDOWS_PHONE
+ ///
+ /// Proxy to use for requests made. Passed on to underying WebRequest if set.
+ ///
+ public IWebProxy Proxy { get; set; }
+#endif
+
+ ///
+ /// Timeout in milliseconds to use for requests made.
+ ///
+ 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
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbActor.cs b/NzbDrone.Core/Tvdb/TvdbActor.cs
new file mode 100644
index 000000000..c6487e6f6
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbActor.cs
@@ -0,0 +1,36 @@
+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();
+ }
+
+ [XmlElement(ElementName = "Actor")]
+ public List 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; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbAsyncResult.cs b/NzbDrone.Core/Tvdb/TvdbAsyncResult.cs
new file mode 100644
index 000000000..4bb64b31e
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbAsyncResult.cs
@@ -0,0 +1,10 @@
+using System.Linq;
+
+namespace NzbDrone.Core.Tvdb
+{
+ public class TvdbAsyncResult
+ {
+ public T Data { get; set; }
+ public object UserState { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbBanner.cs b/NzbDrone.Core/Tvdb/TvdbBanner.cs
new file mode 100644
index 000000000..b1bc5f22a
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbBanner.cs
@@ -0,0 +1,86 @@
+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();
+ }
+
+ [XmlElement(ElementName = "Banner")]
+ public List 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; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbEpisodes.cs b/NzbDrone.Core/Tvdb/TvdbEpisodes.cs
new file mode 100644
index 000000000..0a960a06f
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbEpisodes.cs
@@ -0,0 +1,132 @@
+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; }
+
+ [XmlIgnore]
+ 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; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbLanguages.cs b/NzbDrone.Core/Tvdb/TvdbLanguages.cs
new file mode 100644
index 000000000..03bf34b3e
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbLanguages.cs
@@ -0,0 +1,30 @@
+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();
+ }
+
+ [XmlElement(ElementName = "Language")]
+ public List Languages { get; set; }
+ }
+
+ public class TvdbLanguage
+ {
+ [XmlElement]
+ public int id { get; set; }
+
+ [XmlElement]
+ public string name { get; set; }
+
+ [XmlElement]
+ public string abbreviation { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbMirrors.cs b/NzbDrone.Core/Tvdb/TvdbMirrors.cs
new file mode 100644
index 000000000..13f0a4a12
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbMirrors.cs
@@ -0,0 +1,40 @@
+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 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; }
+ }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbSeriesBase.cs b/NzbDrone.Core/Tvdb/TvdbSeriesBase.cs
new file mode 100644
index 000000000..dc6290d45
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbSeriesBase.cs
@@ -0,0 +1,131 @@
+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; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbSeriesFull.cs b/NzbDrone.Core/Tvdb/TvdbSeriesFull.cs
new file mode 100644
index 000000000..8f51eef3c
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbSeriesFull.cs
@@ -0,0 +1,21 @@
+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();
+ }
+
+ [XmlElement]
+ public TvdbSeriesBase Series { get; set; }
+
+ [XmlElement(ElementName = "Episode")]
+ public List Episodes { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbSeriesSearch.cs b/NzbDrone.Core/Tvdb/TvdbSeriesSearch.cs
new file mode 100644
index 000000000..cfb13db32
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbSeriesSearch.cs
@@ -0,0 +1,18 @@
+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();
+ }
+
+ [XmlElement(ElementName = "Series")]
+ public List Series { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbSeriesSearchItem.cs b/NzbDrone.Core/Tvdb/TvdbSeriesSearchItem.cs
new file mode 100644
index 000000000..8411416a0
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbSeriesSearchItem.cs
@@ -0,0 +1,50 @@
+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; }
+ }
+}
\ No newline at end of file
diff --git a/NzbDrone.Core/Tvdb/TvdbServerTime.cs b/NzbDrone.Core/Tvdb/TvdbServerTime.cs
new file mode 100644
index 000000000..8bac42dea
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbServerTime.cs
@@ -0,0 +1,13 @@
+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; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbUpdate.cs b/NzbDrone.Core/Tvdb/TvdbUpdate.cs
new file mode 100644
index 000000000..5c4c11aae
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbUpdate.cs
@@ -0,0 +1,86 @@
+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();
+ }
+
+ [XmlAttribute]
+ public Int64 time { get; set; }
+
+ [XmlElement(ElementName = "Series")]
+ public List Series { get; set; }
+
+ [XmlElement(ElementName = "Episode")]
+ public List Episodes { get; set; }
+
+ [XmlElement(ElementName = "Banner")]
+ public List 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
+ {
+ ///
+ /// fanart, poster, season, series, episode, actors
+ ///
+ [XmlElement]
+ public string type { get; set; }
+
+ [XmlElement]
+ public string format { get; set; }
+
+ [XmlElement]
+ public int Series { get; set; }
+
+ ///
+ /// Only appears for season banners
+ ///
+ [XmlElement]
+ public int? SeasonNum { get; set; }
+
+ [XmlElement]
+ public string language { get; set; }
+
+ [XmlElement]
+ public string path { get; set; }
+
+ [XmlElement]
+ public Int64 time { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/Tvdb/TvdbUpdateItems.cs b/NzbDrone.Core/Tvdb/TvdbUpdateItems.cs
new file mode 100644
index 000000000..66ec26fd2
--- /dev/null
+++ b/NzbDrone.Core/Tvdb/TvdbUpdateItems.cs
@@ -0,0 +1,26 @@
+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();
+ Episodes = new List();
+ }
+
+ [XmlElement]
+ public Int64 Time { get; set; }
+
+ [XmlElement(ElementName = "Series")]
+ public List Series { get; set; }
+
+ [XmlElement(ElementName = "Episode")]
+ public List Episodes { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/packages.config b/NzbDrone.Core/packages.config
index b10865175..3eef4794a 100644
--- a/NzbDrone.Core/packages.config
+++ b/NzbDrone.Core/packages.config
@@ -11,6 +11,7 @@
+
diff --git a/NzbDrone.Web/Controllers/AddSeriesController.cs b/NzbDrone.Web/Controllers/AddSeriesController.cs
index 415298dcb..beff7c071 100644
--- a/NzbDrone.Web/Controllers/AddSeriesController.cs
+++ b/NzbDrone.Web/Controllers/AddSeriesController.cs
@@ -91,7 +91,7 @@ namespace NzbDrone.Web.Controllers
if (tvdbResult != null)
{
title = tvdbResult.SeriesName;
- seriesId = tvdbResult.Id;
+ seriesId = tvdbResult.id;
}
result.ExistingSeries.Add(new Tuple(folder, title, seriesId));
@@ -147,33 +147,8 @@ namespace NzbDrone.Web.Controllers
[JsonErrorFilter]
public JsonResult LookupSeries(string term)
{
- try
- {
- var tvDbResults = _tvDbProvider.SearchSeries(term).Select(r => new TvDbSearchResultModel
- {
- Id = r.Id,
- Title = r.SeriesName,
- DisplayedTitle = r.FirstAired.Year > 1900 && !r.SeriesName.EndsWith("(" + r.FirstAired.Year + ")")
- ? string.Format("{0} ({1})", r.SeriesName, r.FirstAired.Year)
- : r.SeriesName,
- Banner = r.Banner.BannerPath,
- Url = String.Format("http://www.thetvdb.com/?tab=series&id={0}", r.Id)
- }).ToList();
- return Json(tvDbResults, JsonRequestBehavior.AllowGet);
- }
-
- catch (TvdbNotAvailableException ex)
- {
- logger.WarnException("Unable to lookup series on TheTVDB", ex);
- return JsonNotificationResult.Info("Lookup Failed", "TheTVDB is not available at this time.");
- }
-
- catch (Exception ex)
- {
- logger.WarnException("Unknown Error when looking up series on TheTVDB", ex);
- return JsonNotificationResult.Info("Lookup Failed", "Unknown error while connecting to TheTVDB");
- }
+ return JsonNotificationResult.Info("Lookup Failed", "Unknown error while connecting to TheTVDB");
}