/// <summary> /// Extract all the series fields that are available on thetvdb /// <![CDATA[ /// <?xml version="1.0" encoding="UTF-8" ?> /// <Data> /// <Series> /// <id>73739</id> /// <Actors>|Malcolm David Kelley|Jorge Garcia|Maggie Grace|...|</Actors> /// <Airs_DayOfWeek>Thursday</Airs_DayOfWeek> /// <Airs_Time>9:00 PM</Airs_Time> /// <ContentRating>TV-14</ContentRating> /// <FirstAired>2004-09-22</FirstAired> /// <Genre>|Action and Adventure|Drama|Science-Fiction|</Genre> /// <IMDB_ID>tt0411008</IMDB_ID> /// <Language>en</Language> /// <Network>ABC</Network> /// <Overview>After Oceanic Air flight 815...</Overview> /// <Rating>8.9</Rating> /// <Runtime>60</Runtime> /// <SeriesID>24313</SeriesID> /// <SeriesName>Lost</SeriesName> /// <Status>Continuing</Status> /// <banner>graphical/24313-g2.jpg</banner> /// <fanart>fanart/original/73739-1.jpg</fanart> /// <lastupdated>1205694666</lastupdated> /// <zap2it_id>SH672362</zap2it_id> /// </Series> /// /// </Data> /// ]]> /// </summary> /// <param name="data"></param> /// <returns></returns> internal List <TvdbSeriesFields> ExtractSeriesFields(String data) { //Stopwatch watch = new Stopwatch(); //watch.Start(); XDocument xml = XDocument.Parse(data); var allSeries = from series in xml.Descendants("Series") select new { Id = series.Element("id").Value, Actors = series.Element("Actors").Value, Airs_DayOfWeek = series.Element("Airs_DayOfWeek").Value, Airs_Time = series.Element("Airs_Time").Value, ContentRating = series.Element("ContentRating").Value, FirstAired = series.Element("FirstAired").Value, Genre = series.Element("Genre").Value, IMDB_ID = series.Element("IMDB_ID").Value, Language = series.Element("Language").Value, Network = series.Element("Network").Value, Overview = series.Element("Overview").Value, Rating = series.Element("Rating").Value, Runtime = series.Element("Runtime").Value, SeriesID = series.Element("SeriesID").Value, SeriesName = series.Element("SeriesName").Value, Status = series.Element("Status").Value, banner = series.Elements("banner").Count() == 1 ? series.Element("banner").Value : string.Empty, fanart = series.Elements("fanart").Count() == 1 ? series.Element("fanart").Value : string.Empty, poster = series.Elements("poster").Count() == 1 ? series.Element("poster").Value : string.Empty, lastupdated = series.Element("lastupdated").Value, zap2it_id = series.Element("zap2it_id").Value }; List <TvdbSeriesFields> retList = new List <TvdbSeriesFields>(); foreach (var s in allSeries) { int id = Util.Int32Parse(s.Id); if (id == Util.NO_VALUE) { continue; } TvdbSeriesFields series = new TvdbSeriesFields { Id = id, Actors = Util.SplitTvdbString(s.Actors, true), AirsDayOfWeek = Util.GetDayOfWeek(s.Airs_DayOfWeek), AirsTime = s.Airs_Time, ContentRating = s.ContentRating, FirstAired = Util.ParseDateTime(s.FirstAired), Genre = Util.SplitTvdbString(s.Genre, true), ImdbId = s.IMDB_ID, Language = TvDbUtils.ParseLanguage(s.Language), Network = s.Network, Overview = s.Overview, Rating = Util.DoubleParse(s.Rating), Runtime = Util.DoubleParse(s.Runtime), TvDotComId = Util.Int32Parse(s.SeriesID), SeriesName = s.SeriesName, Status = s.Status, BannerPath = s.banner, FanartPath = s.fanart, PosterPath = s.poster, LastUpdated = Util.UnixToDotNet(s.lastupdated), Zap2itId = s.zap2it_id }; retList.Add(series); } //watch.Stop(); //Log.Debug("Extracted " + retList.Count + " series in " + watch.ElapsedMilliseconds + " milliseconds"); return(retList); }
/// <summary> /// Load the give series from cache /// </summary> /// <param name="_seriesId">Id of the series to load</param> /// <returns>Series that has been loaded or null if series doesn't exist</returns> public TvdbSeries LoadSeriesFromCache(int _seriesId) { String seriesRoot = m_rootFolder + Path.DirectorySeparatorChar + _seriesId; if (!Directory.Exists(seriesRoot)) { return(null); } TvdbSeries series = new TvdbSeries(); #region load series in all available languages String[] seriesLanguages = Directory.GetFiles(seriesRoot, "*.xml"); foreach (String l in seriesLanguages) { if (!l.EndsWith("actors.xml") && !l.EndsWith("banners.xml")) { String content = File.ReadAllText(l); List <TvdbSeriesFields> seriesList = m_xmlReader.ExtractSeriesFields(content); if (seriesList != null && seriesList.Count == 1) { TvdbSeriesFields s = seriesList[0]; //Load episodes if (l.EndsWith("full.xml")) { List <TvdbEpisode> epList = m_xmlReader.ExtractEpisodes(content); s.EpisodesLoaded = true; s.Episodes.Clear(); s.Episodes.AddRange(epList); } series.AddLanguage(s); } } } if (series.SeriesTranslations.Count > 0) {//change language of the series to the default language series.SetLanguage(series.SeriesTranslations.Keys.First()); } else {//no series info could be loaded return(null); } if (!series.BannerPath.Equals("")) { series.Banners.Add(new TvdbSeriesBanner(series.Id, series.BannerPath, series.Language, TvdbSeriesBanner.Type.graphical)); } if (!series.PosterPath.Equals("")) { series.Banners.Add(new TvdbPosterBanner(series.Id, series.PosterPath, series.Language)); } if (!series.FanartPath.Equals("")) { series.Banners.Add(new TvdbFanartBanner(series.Id, series.FanartPath, series.Language)); } Regex rex = new Regex("S(\\d+)E(\\d+)"); if (Directory.Exists(seriesRoot + Path.DirectorySeparatorChar + "EpisodeImages")) { String[] episodeFiles = Directory.GetFiles(seriesRoot + Path.DirectorySeparatorChar + "EpisodeImages", "ep_*.jpg"); foreach (String epImageFile in episodeFiles) { try { Match match = rex.Match(epImageFile); int season = Int32.Parse(match.Groups[1].Value); int episode = Int32.Parse(match.Groups[2].Value); foreach (TvdbEpisode e in series.Episodes) { if (e.SeasonNumber == season && e.EpisodeNumber == episode) { if (epImageFile.Contains("thumb")) { e.Banner.LoadThumb(Image.FromFile(epImageFile)); } else { e.Banner.LoadBanner(Image.FromFile(epImageFile)); } break; } } } catch (Exception) { Log.Warn("Couldn't load episode image file " + epImageFile); } } } #endregion #region Banner loading String bannerFile = seriesRoot + Path.DirectorySeparatorChar + "banners.xml"; //load cached banners if (File.Exists(bannerFile)) {//banners have been already loaded List <TvdbBanner> bannerList = m_xmlReader.ExtractBanners(File.ReadAllText(bannerFile)); String[] banners = Directory.GetFiles(seriesRoot, "banner*.jpg"); foreach (String b in banners) { try { int bannerId = Int32.Parse(b.Remove(b.IndexOf(".")).Remove(0, b.LastIndexOf("_") + 1)); foreach (TvdbBanner banner in bannerList) { if (banner.Id == bannerId) { if (b.Contains("thumb") && banner.GetType().BaseType == typeof(TvdbBannerWithThumb)) { ((TvdbBannerWithThumb)banner).LoadThumb(Image.FromFile(b)); } else if (b.Contains("vignette") && banner.GetType() == typeof(TvdbFanartBanner)) { ((TvdbFanartBanner)banner).LoadVignette(Image.FromFile(b)); } else { banner.LoadBanner(Image.FromFile(b)); } } } } catch (Exception) { Log.Warn("Couldn't load image file " + b); } } series.Banners = bannerList; } #endregion #region actor loading //load actor info String actorFile = seriesRoot + Path.DirectorySeparatorChar + "actors.xml"; if (File.Exists(actorFile)) { List <TvdbActor> actorList = m_xmlReader.ExtractActors(File.ReadAllText(actorFile)); String[] banners = Directory.GetFiles(seriesRoot, "actor_*.jpg"); foreach (String b in banners) { try { int actorId = Int32.Parse(b.Remove(b.IndexOf(".")).Remove(0, b.LastIndexOf("_") + 1)); foreach (TvdbActor actor in actorList) { if (actor.Id == actorId) { actor.ActorImage.LoadBanner(Image.FromFile(b)); } } } catch (Exception) { Log.Warn("Couldn't load image file " + b); } } series.TvdbActors = actorList; } #endregion return(series); }
/// <summary> /// Extract all the series fields that are available on thetvdb /// <![CDATA[ /// <?xml version="1.0" encoding="UTF-8" ?> /// <Data> /// <Series> /// <id>73739</id> /// <Actors>|Malcolm David Kelley|Jorge Garcia|Maggie Grace|...|</Actors> /// <Airs_DayOfWeek>Thursday</Airs_DayOfWeek> /// <Airs_Time>9:00 PM</Airs_Time> /// <ContentRating>TV-14</ContentRating> /// <FirstAired>2004-09-22</FirstAired> /// <Genre>|Action and Adventure|Drama|Science-Fiction|</Genre> /// <IMDB_ID>tt0411008</IMDB_ID> /// <Language>en</Language> /// <Network>ABC</Network> /// <Overview>After Oceanic Air flight 815...</Overview> /// <Rating>8.9</Rating> /// <Runtime>60</Runtime> /// <SeriesID>24313</SeriesID> /// <SeriesName>Lost</SeriesName> /// <Status>Continuing</Status> /// <banner>graphical/24313-g2.jpg</banner> /// <fanart>fanart/original/73739-1.jpg</fanart> /// <lastupdated>1205694666</lastupdated> /// <zap2it_id>SH672362</zap2it_id> /// </Series> /// /// </Data> /// ]]> /// </summary> /// <param name="_data"></param> /// <returns></returns> internal List <TvdbSeriesFields> ExtractSeriesFields(String _data) { //Stopwatch watch = new Stopwatch(); //watch.Start(); XDocument xml = XDocument.Parse(_data); var allSeries = from series in xml.Descendants("Series") select new { Id = series.Element("id").Value, Actors = series.Element("Actors").Value, Airs_DayOfWeek = series.Element("Airs_DayOfWeek").Value, Airs_Time = series.Element("Airs_Time").Value, ContentRating = series.Element("ContentRating").Value, FirstAired = series.Element("FirstAired").Value, Genre = series.Element("Genre").Value, IMDB_ID = series.Element("IMDB_ID").Value, Language = series.Element("Language").Value, Network = series.Element("Network").Value, Overview = series.Element("Overview").Value, Rating = series.Element("Rating").Value, Runtime = series.Element("Runtime").Value, SeriesID = series.Element("SeriesID").Value, SeriesName = series.Element("SeriesName").Value, Status = series.Element("Status").Value, banner = series.Element("banner").Value, fanart = series.Element("fanart").Value, poster = series.Element("poster").Value, lastupdated = series.Element("lastupdated").Value, zap2it_id = series.Element("zap2it_id").Value }; List <TvdbSeriesFields> retList = new List <TvdbSeriesFields>(); foreach (var s in allSeries) { TvdbSeriesFields series = new TvdbSeriesFields(); series.Id = Util.Int32Parse(s.Id); series.Actors = Util.SplitTvdbString(s.Actors); series.AirsDayOfWeek = Util.GetDayOfWeek(s.Airs_DayOfWeek); series.AirsTime = s.Airs_Time.Equals("") ? new DateTime(1, 1, 1) : DateTime.Parse(s.Airs_Time.Replace(".", ":")); series.ContentRating = s.ContentRating; series.FirstAired = s.FirstAired.Equals("") ? new DateTime() : DateTime.Parse(s.FirstAired); series.Genre = Util.SplitTvdbString(s.Genre); series.ImdbId = s.IMDB_ID; series.Language = Util.ParseLanguage(s.Language); series.Network = s.Network; series.Overview = s.Overview; series.Rating = Util.DoubleParse(s.Rating); series.Runtime = Util.DoubleParse(s.Runtime); series.TvDotComId = Util.Int32Parse(s.SeriesID); series.SeriesName = s.SeriesName; series.Status = s.Status; series.BannerPath = s.banner; series.FanartPath = s.fanart; series.PosterPath = s.poster; series.LastUpdated = Util.UnixToDotNet(s.lastupdated); series.Zap2itId = s.zap2it_id; if (series.Id != -99) { retList.Add(series); } } //watch.Stop(); //Log.Debug("Extracted " + retList.Count + " series in " + watch.ElapsedMilliseconds + " milliseconds"); return(retList); }
/// <summary> /// Gets the series with the given id either from cache (if it has already been loaded) or from /// the selected tvdb mirror. /// /// To check if this series has already been cached, use the Method IsCached(TvdbSeries _series) /// </summary> /// <param name="_seriesId">id of series</param> /// <param name="_language">language that should be retrieved</param> /// <param name="_full">if true, the full series record will be loaded (series + all episodes), otherwise only the base record will be loaded which contains only series information</param> /// <param name="_loadBanners">if true also loads the paths to the banners</param> /// <returns>Instance of TvdbSeries containing all gained information</returns> public TvdbSeries GetSeries(int _seriesId, TvdbLanguage _language, bool _loadEpisodes, bool _loadActors, bool _loadBanners) { Stopwatch watch = new Stopwatch(); watch.Start(); TvdbSeries series = GetSeriesFromCache(_seriesId); if (series == null) {//load complete series from tvdb series = m_downloader.DownloadSeries(_seriesId, _language, _loadEpisodes, _loadActors, _loadBanners); if (series == null) { return(null); } watch.Stop(); Log.Debug("Loaded series in " + watch.ElapsedMilliseconds + " milliseconds"); series.IsFavorite = m_userInfo == null ? false : CheckIfSeriesFavorite(_seriesId, m_userInfo.UserFavorites); AddSeriesToCache(series); return(series); } else { //some (if not all) information has already been loaded from tvdb at some point -> fill the missing details and return the series if (!_language.Abbriviation.Equals(series.Language.Abbriviation)) { //user wants a different language than the one that has been loaded if (series.GetAvailableLanguages().Contains(_language)) { series.SetLanguage(_language); } else { TvdbSeriesFields newFields = m_downloader.DownloadSeriesFields(_seriesId, _language); if (_loadEpisodes) { List <TvdbEpisode> epList = m_downloader.DownloadEpisodes(_seriesId, _language); if (epList != null) { newFields.Episodes = epList; } } if (newFields != null) { series.AddLanguage(newFields); series.SetLanguage(_language); } else { Log.Warn("Couldn't load new language " + _language.Abbriviation + " for series " + _seriesId); return(null); } } } if (_loadActors && !series.TvdbActorsLoaded) {//user wants actors loaded series.TvdbActors = m_downloader.DownloadActors(_seriesId); } if (_loadEpisodes && !series.EpisodesLoaded) {//user wants the full version but only the basic has been loaded (without episodes series.Episodes = m_downloader.DownloadEpisodes(_seriesId, _language); } if (_loadBanners && !series.BannersLoaded) {//user wants banners loaded but current series hasn't -> Do it baby series.Banners = m_downloader.DownloadBanners(_seriesId); } watch.Stop(); Log.Debug("Loaded series in " + watch.ElapsedMilliseconds + " milliseconds"); return(series); } }