/// <summary> /// Match the series information by Episode name /// </summary> private static bool MatchByEpisodeName(VideoTags videoTags, string seriesID, Log jobLog) { if (String.IsNullOrWhiteSpace(videoTags.SubTitle)) { jobLog.WriteEntry("No episode name to match", Log.LogEntryType.Debug); return(false); //Nothing to match here } // ************************************** // Get the series and episode information // ************************************** foreach (string lang in THETVDB_SUPPORTED_LANGUAGES) // Cycle through all languages looking for a match since people in different countries/locales could be viewing shows recorded in different languages { jobLog.WriteEntry("Looking for Episode name match on TVDB using language " + lang, Log.LogEntryType.Debug); string queryUrl = "http://www.thetvdb.com/api/" + MCEBUDDY_THETVDB_API_KEY + "/series/" + seriesID + "/all/" + lang + ".xml"; XPathDocument XpS; XPathNavigator NavS; XPathExpression ExpS; XPathNodeIterator ItrS; string overview = ""; string bannerUrl = ""; string imdbID = ""; List <String> genres = new List <string>();; int seasonNo = 0; int episodeNo = 0; string episodeName = ""; string episodeOverview = ""; string network = ""; DateTime premiereDate = GlobalDefs.NO_BROADCAST_TIME; string firstAiredStr = ""; DateTime firstAired = GlobalDefs.NO_BROADCAST_TIME; try { // Get the Series information XpS = new XPathDocument(queryUrl); NavS = XpS.CreateNavigator(); ExpS = NavS.Compile("//Data/Series"); // Series information ItrS = NavS.Select(ExpS); ItrS.MoveNext(); overview = XML.GetXMLTagValue("Overview", ItrS.Current.OuterXml); if (String.IsNullOrWhiteSpace(bannerUrl = XML.GetXMLTagValue("poster", ItrS.Current.OuterXml))) // We get the poster first { if (String.IsNullOrWhiteSpace(bannerUrl = XML.GetXMLTagValue("fanart", ItrS.Current.OuterXml))) // We get the fanart next { bannerUrl = XML.GetXMLTagValue("banner", ItrS.Current.OuterXml); // We get the banner last } } imdbID = XML.GetXMLTagValue("IMDB_ID", ItrS.Current.OuterXml); network = XML.GetXMLTagValue("Network", ItrS.Current.OuterXml); DateTime.TryParse(XML.GetXMLTagValue("FirstAired", ItrS.Current.OuterXml), out premiereDate); string genreValue = XML.GetXMLTagValue("Genre", ItrS.Current.OuterXml); if (!String.IsNullOrWhiteSpace(genreValue)) { foreach (string genre in genreValue.Split('|')) { if (!String.IsNullOrWhiteSpace(genre)) { genres.Add(genre); } } } // Get the episode information XpS = new XPathDocument(queryUrl); NavS = XpS.CreateNavigator(); ExpS = NavS.Compile("//Data/Episode"); // Episode information ItrS = NavS.Select(ExpS); } catch (Exception e) { jobLog.WriteEntry("Unable to nagivate TMDB for language " + lang + "\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); } while (ItrS.MoveNext()) { episodeName = XML.GetXMLTagValue("EpisodeName", ItrS.Current.OuterXml); if (!String.IsNullOrWhiteSpace(episodeName)) { if (String.Compare(videoTags.SubTitle.Trim(), episodeName.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0) // Compare the episode names (case / special characters / whitespace can change very often) { int.TryParse(XML.GetXMLTagValue("SeasonNumber", ItrS.Current.OuterXml), out seasonNo); int.TryParse(XML.GetXMLTagValue("EpisodeNumber", ItrS.Current.OuterXml), out episodeNo); episodeOverview = XML.GetXMLTagValue("Overview", ItrS.Current.OuterXml); // ******************** // Get the banner file // ******************** VideoMetaData.DownloadBannerFile(videoTags, "http://www.thetvdb.com/banners/" + bannerUrl); // Get bannerfile if ((episodeNo != 0) && (videoTags.Episode == 0)) { videoTags.Episode = episodeNo; } if ((seasonNo != 0) && (videoTags.Season == 0)) { videoTags.Season = seasonNo; } if (!String.IsNullOrWhiteSpace(episodeOverview) && String.IsNullOrWhiteSpace(videoTags.Description)) { videoTags.Description = episodeOverview; } else if (!String.IsNullOrWhiteSpace(overview) && (String.IsNullOrWhiteSpace(videoTags.Description))) { videoTags.Description = overview; } if (!String.IsNullOrWhiteSpace(seriesID) && String.IsNullOrWhiteSpace(videoTags.tvdbId)) { videoTags.tvdbId = seriesID; } if (!String.IsNullOrWhiteSpace(imdbID) && String.IsNullOrWhiteSpace(videoTags.imdbId)) { videoTags.imdbId = imdbID; } if (!String.IsNullOrWhiteSpace(network) && String.IsNullOrWhiteSpace(videoTags.Network)) { videoTags.Network = network; } if (premiereDate > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.SeriesPremiereDate <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.SeriesPremiereDate.Date > premiereDate.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use TVDB dates, TVDB Dates are more reliable than video metadata usually { videoTags.SeriesPremiereDate = premiereDate; // TVDB stores time in network (local) timezone } } if (genres.Count > 0) { if (videoTags.Genres != null) { if (videoTags.Genres.Length == 0) { videoTags.Genres = genres.ToArray(); } } else { videoTags.Genres = genres.ToArray(); } } firstAiredStr = XML.GetXMLTagValue("FirstAired", ItrS.Current.OuterXml); if (DateTime.TryParse(firstAiredStr, null, DateTimeStyles.AssumeLocal, out firstAired)) { if (firstAired > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > firstAired.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use TVDB dates, TVDB Dates are more reliable than video metadata usually { videoTags.OriginalBroadcastDateTime = firstAired; // TVDB stores time in network (local) timezone } } } return(true); // Found a match got all the data, we're done here } } } } jobLog.WriteEntry("No match found on TVDB for Episode Name", Log.LogEntryType.Debug); return(false); }
/// <summary> /// Match the series information by Original Broadcast date /// </summary> private static bool MatchByBroadcastTime(VideoTags videoTags, string seriesID, bool dontOverwriteTitle, Log jobLog) { // If we have no original broadcasttime if (videoTags.OriginalBroadcastDateTime <= Globals.GlobalDefs.NO_BROADCAST_TIME) { jobLog.WriteEntry("No original broadcast date time", Log.LogEntryType.Debug); return(false); } // ************************************** // Get the series and episode information // ************************************** string lang = Localise.TwoLetterISO(); if (!((IList <string>)THETVDB_SUPPORTED_LANGUAGES).Contains(lang)) { lang = "en"; } string queryUrl = "http://www.thetvdb.com/api/" + MCEBUDDY_THETVDB_API_KEY + "/series/" + seriesID + "/all/" + lang + ".xml"; XPathDocument XpS; XPathNavigator NavS; XPathExpression ExpS; XPathNodeIterator ItrS; string overview = ""; string seriesName = ""; string bannerUrl = ""; string imdbID = ""; string firstAiredStr = ""; DateTime firstAired = GlobalDefs.NO_BROADCAST_TIME; int seasonNo = 0; int episodeNo = 0; string episodeName = ""; string episodeOverview = ""; string network = ""; DateTime premiereDate = GlobalDefs.NO_BROADCAST_TIME; List <string> genres = new List <string>(); try { // Get the Series information XpS = new XPathDocument(queryUrl); NavS = XpS.CreateNavigator(); ExpS = NavS.Compile("//Data/Series"); // Series information ItrS = NavS.Select(ExpS); ItrS.MoveNext(); seriesName = XML.GetXMLTagValue("SeriesName", ItrS.Current.OuterXml); overview = XML.GetXMLTagValue("Overview", ItrS.Current.OuterXml); if (String.IsNullOrWhiteSpace(bannerUrl = XML.GetXMLTagValue("poster", ItrS.Current.OuterXml))) // We get the poster first { if (String.IsNullOrWhiteSpace(bannerUrl = XML.GetXMLTagValue("fanart", ItrS.Current.OuterXml))) // We get the fanart next { bannerUrl = XML.GetXMLTagValue("banner", ItrS.Current.OuterXml); // We get the banner last } } imdbID = XML.GetXMLTagValue("IMDB_ID", ItrS.Current.OuterXml); network = XML.GetXMLTagValue("Network", ItrS.Current.OuterXml); DateTime.TryParse(XML.GetXMLTagValue("FirstAired", ItrS.Current.OuterXml), out premiereDate); string genreValue = XML.GetXMLTagValue("Genre", ItrS.Current.OuterXml); if (!String.IsNullOrWhiteSpace(genreValue)) { foreach (string genre in genreValue.Split('|')) { if (!String.IsNullOrWhiteSpace(genre)) { genres.Add(genre); } } } // Get the Episode information XpS = new XPathDocument(queryUrl); NavS = XpS.CreateNavigator(); ExpS = NavS.Compile("//Data/Episode"); ItrS = NavS.Select(ExpS); } catch (Exception e) { jobLog.WriteEntry("Unable to navigate TVDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); } while (ItrS.MoveNext()) { firstAiredStr = XML.GetXMLTagValue("FirstAired", ItrS.Current.OuterXml); if (DateTime.TryParse(firstAiredStr, null, DateTimeStyles.AssumeLocal, out firstAired)) { if (firstAired <= GlobalDefs.NO_BROADCAST_TIME) { continue; } // The information is stored on the server using the network timezone // So we assume that the show being converted was recorded locally and is converted locally so the timezones match // Sometimes the timezones get mixed up so we check local time or universal time for a match if ((firstAired.Date == videoTags.OriginalBroadcastDateTime.ToLocalTime().Date) || // TVDB only reports the date not the time (firstAired.Date == videoTags.OriginalBroadcastDateTime.ToUniversalTime().Date)) { episodeName = XML.GetXMLTagValue("EpisodeName", ItrS.Current.OuterXml); if (String.IsNullOrWhiteSpace(episodeName)) { jobLog.WriteEntry("Empty episode name", Log.LogEntryType.Debug); return(false); // WRONG series, if there is no name we're in the incorrect series (probably wrong country) } int.TryParse(XML.GetXMLTagValue("SeasonNumber", ItrS.Current.OuterXml), out seasonNo); int.TryParse(XML.GetXMLTagValue("EpisodeNumber", ItrS.Current.OuterXml), out episodeNo); episodeOverview = XML.GetXMLTagValue("Overview", ItrS.Current.OuterXml); // ******************** // Get the banner file // ******************** VideoMetaData.DownloadBannerFile(videoTags, "http://www.thetvdb.com/banners/" + bannerUrl); // Get bannerfile if ((episodeNo != 0) && (videoTags.Episode == 0)) { videoTags.Episode = episodeNo; } if ((seasonNo != 0) && (videoTags.Season == 0)) { videoTags.Season = seasonNo; } if (!String.IsNullOrWhiteSpace(seriesName) && !dontOverwriteTitle) { videoTags.Title = seriesName; // Overwrite Series name since we matching by broadcast time and the name didn't match earlier so likely an issue with the name } if (!String.IsNullOrWhiteSpace(episodeName)) { videoTags.SubTitle = episodeName; // Overwrite episode name, it didn't match earlier in match by episode name, so it's probably wrong on the metadata } if (!String.IsNullOrWhiteSpace(episodeOverview)) { videoTags.Description = episodeOverview; // Overwrite } else if (!String.IsNullOrWhiteSpace(overview)) { videoTags.Description = overview; // Overwrite } if (!String.IsNullOrWhiteSpace(seriesID) && String.IsNullOrWhiteSpace(videoTags.tvdbId)) { videoTags.tvdbId = seriesID; } if (!String.IsNullOrWhiteSpace(imdbID) && String.IsNullOrWhiteSpace(videoTags.imdbId)) { videoTags.imdbId = imdbID; } if (!String.IsNullOrWhiteSpace(network) && String.IsNullOrWhiteSpace(videoTags.Network)) { videoTags.Network = network; } if (premiereDate > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.SeriesPremiereDate <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.SeriesPremiereDate.Date > premiereDate.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use TVDB dates, TVDB Dates are more reliable than video metadata usually { videoTags.SeriesPremiereDate = premiereDate; // TVDB stores time in network (local) timezone } } if (genres.Count > 0) { if (videoTags.Genres != null) { if (videoTags.Genres.Length == 0) { videoTags.Genres = genres.ToArray(); } } else { videoTags.Genres = genres.ToArray(); } } return(true); // Found a match got all the data, we're done here } } } jobLog.WriteEntry("No match found on TVDB for language " + lang, Log.LogEntryType.Warning); return(false); }