Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <summary>
        /// Supplements details by searching for a series show by title or IMDB ID
        /// Uses MyApiFilms
        /// </summary>
        /// <param name="matchByAirDate">If true, First match by airDate and then by Episode name and vice versa</param>
        /// <param name="videoTags">Video tags information to use and update</param>
        /// <param name="dontOverwriteTitle">True if the title has been manually corrected and not to be overwritten</param>
        /// <param name="offset">Initial search results offset</param>
        /// <returns>True if successful</returns>
        static private bool DownloadSeriesDetails(bool matchByAirDate, VideoTags videoTags, bool dontOverwriteTitle, Log jobLog, int offset = 0)
        {
            try
            {
                if (matchByAirDate && (videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME))
                {
                    jobLog.WriteEntry("Invalud original broadcast date to match on IMDB", Log.LogEntryType.Debug);
                    return(false); // We can only match by airdate if there is something to match against (otherwise we get false positives)
                }
                else if (!matchByAirDate && String.IsNullOrWhiteSpace(videoTags.SubTitle))
                {
                    jobLog.WriteEntry("Invalid episode name to match on IMDB", Log.LogEntryType.Debug);
                    return(false); //Nothing to match here
                }

                jobLog.WriteEntry("Searching IMDB Series with result offset " + offset, Log.LogEntryType.Debug);

                List <MyApiFilms.SearchResults> searchResults = new List <MyApiFilms.SearchResults>();

                if (String.IsNullOrWhiteSpace(videoTags.imdbId)) // If dont' have a specific imdb id specified, look up the series details
                {
                    try
                    {
                        WebClient client = new WebClient();
                        client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");

                        // Look for matching title
                        string response = client.DownloadString(new Uri("http://www.myapifilms.com/imdb?title=" + videoTags.Title + "&format=JSON&aka=1&actors=S&seasons=1&limit=" + MY_API_SEARCH_LIMIT.ToString() + "&offset=" + offset.ToString()));
                        searchResults = JsonConvert.DeserializeObject <List <MyApiFilms.SearchResults> >(response);
                    }
                    catch (Exception e)
                    {
                        jobLog.WriteEntry("Unable to connect to IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                        return(false); // invalid JSON string
                    }
                }
                else
                {
                    // We have a series imdb id to match, use MyApiFilms to get the series details
                    try
                    {
                        WebClient client = new WebClient();
                        client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
                        string response = client.DownloadString(new Uri("http://www.myapifilms.com/imdb?idIMDB=" + videoTags.imdbId + "&format=JSON&seasons=1&actors=S"));
                        searchResults.Add(JsonConvert.DeserializeObject <MyApiFilms.SearchResults>(response));
                    }
                    catch (Exception e)
                    {
                        jobLog.WriteEntry("Unable to connect to IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                        return(false); // invalid JSON string
                    }
                }

                foreach (MyApiFilms.SearchResults show in searchResults) // Cycle through all possible combinations
                {
                    // Get and match the Series name
                    string seriesName = show.title;

                    if (String.IsNullOrWhiteSpace(videoTags.imdbId)) // Match names only if the movie imdb id is not forced, else take what is returned by moviedb
                    {
                        List <MyApiFilms.Aka> akaValues = show.akas; // check AKA names also - Also Known As (for language and localization)
                        string title  = videoTags.Title;
                        bool akaMatch = false;
                        if (akaValues != null) // Check if there are any AKA names to match
                        {
                            akaMatch = show.akas.Any(s => (String.Compare(s.title.Trim(), title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0 ? true : false));
                        }

                        if ((String.Compare(seriesName.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) != 0) && (!akaMatch)) // ignore white space and special characters - check for both, Title and AKA names looking for a match
                        {
                            continue;                                                                                                                                                                  // No match in name or AKA
                        }
                    }
                    else if (!String.IsNullOrWhiteSpace(seriesName) && !dontOverwriteTitle) // make sure there is actually something returned here otherwise use default title
                    {
                        videoTags.Title = seriesName;                                       // Take what is forced for the imdb id
                    }
                    DateTime seriesPremiereDate = GlobalDefs.NO_BROADCAST_TIME;
                    DateTime.TryParseExact(show.releaseDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out seriesPremiereDate);

                    // Look for the right Episode
                    if (show.seasons != null)
                    {
                        foreach (MyApiFilms.Season season in show.seasons)
                        {
                            if (season.episodes != null)
                            {
                                foreach (MyApiFilms.Episode episode in season.episodes)
                                {
                                    // Get the Episode name and match it
                                    string episodeName = episode.title;

                                    // Original broadcast date, some of them have an extra . in the date so get rid of it
                                    DateTime airDate = GlobalDefs.NO_BROADCAST_TIME;
                                    DateTime.TryParseExact(episode.date.Replace(".", "").Trim(), "d MMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out airDate);

                                    if ((!matchByAirDate && (String.Compare(episodeName.Trim(), videoTags.SubTitle.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0)) ||
                                        (matchByAirDate && (videoTags.OriginalBroadcastDateTime.ToLocalTime().Date == airDate.Date)) ||
                                        (matchByAirDate && (videoTags.OriginalBroadcastDateTime.ToUniversalTime().Date == airDate.Date)))
                                    {
                                        // Get Genre's
                                        string[] genres = (show.genres == null ? null : show.genres.ToArray()); // Get Genres

                                        // Get Overview
                                        string episodeOverview = episode.plot;

                                        // Episode
                                        int episodeNo = episode.episode;

                                        // Season
                                        int seasonNo = season.numSeason;

                                        // IMDB Movie Id
                                        string imdbID = show.idIMDB;

                                        // Home free - update all the info where required
                                        if (matchByAirDate) // If we came in matching the Original Air Date - then we overwrite the episode details
                                        {
                                            // TODO: For now we only update subtitle and description if it is missing since IMDB is not upto date on TV series information yet. This needs to be changed and force updated once IMDB is complete
                                            // if (!String.IsNullOrWhiteSpace(episodeName)) videoTags.SubTitle = episodeName; // Overwrite
                                            // if (!String.IsNullOrWhiteSpace(episodeOverview)) videoTags.Description = episodeOverview; // Overwrite
                                            if (!String.IsNullOrWhiteSpace(episodeName) && String.IsNullOrWhiteSpace(videoTags.SubTitle))
                                            {
                                                videoTags.SubTitle = episodeName;
                                            }
                                            if (!String.IsNullOrWhiteSpace(episodeOverview) && String.IsNullOrWhiteSpace(videoTags.Description))
                                            {
                                                videoTags.Description = episodeOverview;
                                            }
                                        }
                                        else // only update what's missing
                                        {
                                            if (!String.IsNullOrWhiteSpace(episodeName) && String.IsNullOrWhiteSpace(videoTags.SubTitle))
                                            {
                                                videoTags.SubTitle = episodeName;
                                            }
                                            if (!String.IsNullOrWhiteSpace(episodeOverview) && String.IsNullOrWhiteSpace(videoTags.Description))
                                            {
                                                videoTags.Description = episodeOverview;
                                            }
                                        }

                                        if ((episodeNo != 0) && (videoTags.Episode == 0))
                                        {
                                            videoTags.Episode = episodeNo;
                                        }
                                        if ((seasonNo != 0) && (videoTags.Season == 0))
                                        {
                                            videoTags.Season = seasonNo;
                                        }
                                        if (!String.IsNullOrWhiteSpace(imdbID) && String.IsNullOrWhiteSpace(videoTags.imdbId))
                                        {
                                            videoTags.imdbId = imdbID;
                                        }
                                        if (seriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME)
                                        {
                                            if ((videoTags.SeriesPremiereDate <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.SeriesPremiereDate.Date > seriesPremiereDate.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 IMDB dates, IMDB Dates are more reliable than video metadata usually
                                            {
                                                videoTags.SeriesPremiereDate = seriesPremiereDate;                                                                               // IMDB stores time in network (local) timezone
                                            }
                                        }
                                        if (airDate > GlobalDefs.NO_BROADCAST_TIME)
                                        {
                                            if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > airDate.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 IMDB dates, IMDB Dates are more reliable than video metadata usually
                                            {
                                                videoTags.OriginalBroadcastDateTime = airDate;                                                                                      // IMDB stores time in network (local) timezone
                                            }
                                        }
                                        if (genres != null)
                                        {
                                            if (genres.Length > 0)
                                            {
                                                if (videoTags.Genres != null)
                                                {
                                                    if (videoTags.Genres.Length == 0)
                                                    {
                                                        videoTags.Genres = genres;
                                                    }
                                                }
                                                else
                                                {
                                                    videoTags.Genres = genres;
                                                }
                                            }
                                        }

                                        if (String.IsNullOrWhiteSpace(videoTags.MediaCredits)) // Get the media credits
                                        {
                                            videoTags.MediaCredits = ((show.actors != null) ? String.Join(";", show.actors.Select(s => s.actorName)) : "");
                                        }

                                        if (String.IsNullOrWhiteSpace(videoTags.Rating)) // Get the ratings
                                        {
                                            videoTags.Rating = show.rated;
                                        }

                                        // Download the banner file
                                        VideoMetaData.DownloadBannerFile(videoTags, show.urlPoster); // Get bannerfile

                                        return(true);                                                // Golden
                                    }
                                }
                            }
                        }
                    }
                }

                // Check if we have reached the limit for the results (currently 10 is the max returned in a single query), if so then check the next set of results
                if (searchResults.Count == MY_API_SEARCH_LIMIT)
                {
                    return(DownloadSeriesDetails(matchByAirDate, videoTags, dontOverwriteTitle, jobLog, offset + MY_API_SEARCH_LIMIT));
                }

                jobLog.WriteEntry("No match found on IMDB Series", Log.LogEntryType.Debug);

                return(false);
            }
            catch (Exception e)
            {
                jobLog.WriteEntry("Unable to initialize IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                return(false);
            }
        }
Example #4
0
        /// <summary>
        /// Download the information about the show from TV.com
        /// </summary>
        /// <param name="matchByAirDate">True to match the Episode by Original AirDate, False to match by Episode Name</param>
        /// <param name="dontOverwriteTitle">True if the title has been manually corrected and not to be overwritten</param>
        /// <returns>True if found a match</returns>
        static private bool DownloadSeriesDetails(bool matchByAirDate, VideoTags videoTags, bool dontOverwriteTitle, Log jobLog)
        {
            HtmlDocument htmlDoc;

            try
            {
                if (matchByAirDate && (videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME))
                {
                    jobLog.WriteEntry("Invalid original broadcast date to match on TV.com", Log.LogEntryType.Debug);
                    return(false); // We can only match by airdate if there is something to match against (otherwise we get false positives)
                }
                else if (!matchByAirDate && String.IsNullOrWhiteSpace(videoTags.SubTitle))
                {
                    jobLog.WriteEntry("Invalid episode name to match on TV.com", Log.LogEntryType.Debug);
                    return(false); //Nothing to match here
                }

                htmlDoc = new HtmlWeb().Load("http://www.tv.com/search?q=" + videoTags.Title);

                // Get the matching shows list
                HtmlNodeCollection nodes = htmlDoc.DocumentNode.SelectNodes("//li[@class='result show']");
                foreach (HtmlNode node in nodes)
                {
                    string seriesTitle = "", seriesLink = "", bannerUrl = "";

                    HtmlDocument subDoc = new HtmlDocument();
                    subDoc.Load(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(node.InnerHtml)));

                    // Get the banner URL
                    HtmlNode urlNode = subDoc.DocumentNode.SelectSingleNode("//div[@class='mask']//img[@src]");
                    if (urlNode != null)
                    {
                        if (urlNode.HasAttributes)
                        {
                            bannerUrl = urlNode.Attributes["src"].Value.Trim(); // URL
                        }
                        else
                        {
                            bannerUrl = ""; // reset each cycle
                        }
                    }
                    else
                    {
                        bannerUrl = ""; // reset each cycle
                    }
                    // Get the series name and link to page
                    HtmlNode subNode = subDoc.DocumentNode.SelectSingleNode("//div[@class='info']//h4//a[@href]");
                    if (subNode != null)
                    {
                        seriesTitle = subNode.InnerText.Trim(); // Get the title of the series

                        // Compare the series title with the title of the recording
                        if (String.Compare(seriesTitle.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0)
                        {
                            HtmlNode subNode1 = subDoc.DocumentNode.SelectSingleNode("//ul[@class='sub_links _inline_navigation']");
                            if (subNode1 != null)
                            {
                                HtmlDocument subDoc1 = new HtmlDocument();
                                subDoc1.Load(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(subNode1.InnerHtml)));
                                HtmlNode subNode2 = subDoc1.DocumentNode.SelectSingleNode("//li//a[@href]");
                                if (subNode2 != null)
                                {
                                    if (subNode2.HasAttributes)
                                    {
                                        seriesLink = subNode2.Attributes["href"].Value; // Get the link for the episodes in the series

                                        // Now the links to the various season pages
                                        HtmlDocument sDoc = new HtmlWeb().Load("http://www.tv.com" + seriesLink);

                                        // Get the premiere date
                                        HtmlNode pNode          = sDoc.DocumentNode.SelectSingleNode("//span[@class='divider']");
                                        int      start          = pNode.InnerText.IndexOf("Premiered") + "Premiered".Length;
                                        int      length         = pNode.InnerText.IndexOf("In") - start;
                                        string   premiereString = pNode.InnerText.Substring(start, length).Trim();
                                        DateTime premiereDate   = GlobalDefs.NO_BROADCAST_TIME;
                                        DateTime.TryParse(premiereString, out premiereDate);

                                        // Get the seasons
                                        HtmlNodeCollection sNodes = sDoc.DocumentNode.SelectNodes("//li[@class='filter ']//a[@href]");
                                        foreach (HtmlNode sNode in sNodes) // go through each season
                                        {
                                            string seasonLink;

                                            // Now extract the link to the season episodes page
                                            if (sNode.HasAttributes)
                                            {
                                                seasonLink = sNode.Attributes["href"].Value; // the href has the link to the season page

                                                // Now the links to the various season pages
                                                HtmlDocument eDoc = new HtmlWeb().Load("http://www.tv.com" + seasonLink);

                                                HtmlNodeCollection eNodes = eDoc.DocumentNode.SelectNodes("//div[@class='no_toggle_wrapper _clearfix']");
                                                foreach (HtmlNode eNode in eNodes) // Now extract the episode names, original air dates and compare
                                                {
                                                    string   episodeName = "", episodeDesc = "";
                                                    DateTime airDate = GlobalDefs.NO_BROADCAST_TIME;
                                                    int      episodeNo = 0, seasonNo = 0;

                                                    HtmlNode     tempNode;
                                                    HtmlDocument tempDoc = new HtmlDocument();
                                                    tempDoc.Load(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(eNode.InnerHtml)));

                                                    // Extract the season number
                                                    tempNode = eDoc.DocumentNode.SelectSingleNode("//li[@class='filter selected']");
                                                    if (tempNode != null)
                                                    {
                                                        if (tempNode.HasAttributes)
                                                        {
                                                            int.TryParse(tempNode.Attributes["data-season"].Value.Trim(), out seasonNo); // Season number
                                                        }
                                                    }
                                                    // Extract the episode name
                                                    tempNode = tempDoc.DocumentNode.SelectSingleNode("//a[@class='title']");
                                                    if (tempNode != null)
                                                    {
                                                        episodeName = tempNode.InnerText.Trim(); // Episode Name
                                                    }
                                                    // Extract the episode number
                                                    tempNode = tempDoc.DocumentNode.SelectSingleNode("//div[@class='ep_info']");
                                                    if (tempNode != null)
                                                    {
                                                        int.TryParse(tempNode.InnerText.Trim().Replace("Episode", ""), out episodeNo); // Episode number
                                                    }
                                                    // Extract the original broadcast date
                                                    tempNode = tempDoc.DocumentNode.SelectSingleNode("//div[@class='date']");
                                                    if (tempNode != null)
                                                    {
                                                        DateTime.TryParse(tempNode.InnerText.Trim(), null, DateTimeStyles.AssumeLocal, out airDate); // Air Date
                                                    }
                                                    // Extract the episode description
                                                    tempNode = tempDoc.DocumentNode.SelectSingleNode("//div[@class='description']");
                                                    if (tempNode != null)
                                                    {
                                                        episodeDesc = tempNode.InnerText.Trim(); // Episode description
                                                    }
                                                    // Now match and store - match either episode name or air date
                                                    // 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 ((!matchByAirDate && (String.Compare(episodeName.Trim(), videoTags.SubTitle.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0)) ||
                                                        (matchByAirDate && (videoTags.OriginalBroadcastDateTime.ToLocalTime().Date == airDate.Date)) ||
                                                        (matchByAirDate && (videoTags.OriginalBroadcastDateTime.ToUniversalTime().Date == airDate.Date)))
                                                    {
                                                        // Home free - update all the info where required
                                                        if (matchByAirDate) // If we came in matching the Original Air Date - then we overwrite the episode details
                                                        {
                                                            if (!String.IsNullOrWhiteSpace(episodeName))
                                                            {
                                                                videoTags.SubTitle = episodeName;                                          // Overwrite
                                                            }
                                                            if (!String.IsNullOrWhiteSpace(episodeDesc))
                                                            {
                                                                videoTags.Description = episodeDesc;                                          // Overwrite
                                                            }
                                                        }
                                                        else // only update what's missing
                                                        {
                                                            if (!String.IsNullOrWhiteSpace(episodeName) && String.IsNullOrWhiteSpace(videoTags.SubTitle))
                                                            {
                                                                videoTags.SubTitle = episodeName;
                                                            }
                                                            if (!String.IsNullOrWhiteSpace(episodeDesc) && String.IsNullOrWhiteSpace(videoTags.Description))
                                                            {
                                                                videoTags.Description = episodeDesc;
                                                            }
                                                        }
                                                        if ((episodeNo != 0) && (videoTags.Episode == 0))
                                                        {
                                                            videoTags.Episode = episodeNo;
                                                        }
                                                        if ((seasonNo != 0) && (videoTags.Season == 0))
                                                        {
                                                            videoTags.Season = seasonNo;
                                                        }
                                                        if (airDate > GlobalDefs.NO_BROADCAST_TIME)
                                                        {
                                                            if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > airDate.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 TV dates, TV Dates are more reliable than video metadata usually
                                                            {
                                                                videoTags.OriginalBroadcastDateTime = airDate;                                                                                      // TV stores time in network (local) timezone
                                                            }
                                                        }
                                                        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 IMDB dates, IMDB Dates are more reliable than video metadata usually
                                                            {
                                                                videoTags.SeriesPremiereDate = premiereDate;                                                                               // IMDB stores time in network (local) timezone
                                                            }
                                                        }
                                                        VideoMetaData.DownloadBannerFile(videoTags, bannerUrl); // Get bannerfile

                                                        // All Good now
                                                        return(true);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                jobLog.WriteEntry("No match found on TV.com", Log.LogEntryType.Debug);

                return(false);
            }
            catch (Exception e)
            {
                jobLog.WriteEntry("Unable to connect to TV.com\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                return(false);
            }
        }
Example #5
0
        /// <summary>
        /// Supplements details by searching for a movie by title or IMDB ID
        /// Uses MyApiFilms
        /// </summary>
        /// <param name="videoTags">Video tags information to use and update</param>
        /// <param name="dontOverwriteTitle">True if the title has been manually corrected and not to be overwritten</param>
        /// <param name="offset">Initial search results offset</param>
        /// <returns></returns>
        static public bool DownloadMovieDetails(VideoTags videoTags, bool dontOverwriteTitle, Log jobLog, int offset = 0)
        {
            try
            {
                jobLog.WriteEntry("Searching IMDB Movie with result offset " + offset, Log.LogEntryType.Debug);

                List <MyApiFilms.SearchResults> searchResults = new List <MyApiFilms.SearchResults>();

                if (String.IsNullOrWhiteSpace(videoTags.imdbId)) // If dont' have a specific movieId specified, look up the movie details
                {
                    try
                    {
                        WebClient client = new WebClient();
                        client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");

                        // Look for matching title
                        string response = client.DownloadString(new Uri("http://www.myapifilms.com/imdb?title=" + videoTags.Title + "&format=JSON&aka=1&actors=S&limit=" + MY_API_SEARCH_LIMIT.ToString() + "&offset=" + offset.ToString()));
                        searchResults = JsonConvert.DeserializeObject <List <MyApiFilms.SearchResults> >(response);
                    }
                    catch (Exception e)
                    {
                        jobLog.WriteEntry("Unable to connect to IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                        return(false); // invalid JSON string
                    }
                }
                else
                {
                    // We have a series imdb id to match, use MyApiFilms to get the series details
                    try
                    {
                        WebClient client = new WebClient();
                        client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
                        string response = client.DownloadString(new Uri("http://www.myapifilms.com/imdb?idIMDB=" + videoTags.imdbId + "&format=JSON&actors=S"));
                        searchResults.Add(JsonConvert.DeserializeObject <MyApiFilms.SearchResults>(response));
                    }
                    catch (Exception e)
                    {
                        jobLog.WriteEntry("Unable to connect to IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                        return(false); // invalid JSON string
                    }
                }

                foreach (MyApiFilms.SearchResults movie in searchResults) // Cycle through all possible combinations
                {
                    // Get and match Movie name
                    string movieName = movie.title;
                    if (String.IsNullOrWhiteSpace(videoTags.imdbId))  // Match names only if the movie imdb id is not forced, else take what is returned by moviedb
                    {
                        List <MyApiFilms.Aka> akaValues = movie.akas; // check AKA names also - Also Known As (for language and localization)
                        string title    = videoTags.Title;
                        bool   akaMatch = false;
                        if (akaValues != null) // Check if there are any AKA names to match
                        {
                            akaMatch = movie.akas.Any(s => (String.Compare(s.title.Trim(), title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0 ? true : false));
                        }

                        if ((String.Compare(movieName.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) != 0) && (!akaMatch)) // ignore white space and special characters - check for both, Title and AKA names looking for a match
                        {
                            continue;                                                                                                                                                                 // No match in name or AKA
                        }
                        // Match year if available
                        if (videoTags.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) // If we have a time, we can try to narrow the search parameters
                        {
                            // 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
                            DateTime dt = videoTags.OriginalBroadcastDateTime.ToLocalTime();
                            if (movie.year.Trim() != dt.Year.ToString())
                            {
                                continue;
                            }
                        }

                        videoTags.imdbId = movie.idIMDB;                                   // since IMDB movie is not forced, get it here
                    }
                    else if (!String.IsNullOrWhiteSpace(movieName) && !dontOverwriteTitle) // make sure there is actually something returned here otherwise use default title
                    {
                        videoTags.Title = movieName;                                       // Take what is forced for the imdb movie id
                    }
                    videoTags.IsMovie = true;

                    // Get Overview
                    string overview = movie.simplePlot;
                    if (!String.IsNullOrWhiteSpace(overview) && String.IsNullOrWhiteSpace(videoTags.Description))
                    {
                        videoTags.Description = overview;
                    }

                    // Get original release date
                    DateTime releaseDate = GlobalDefs.NO_BROADCAST_TIME;
                    string   released    = movie.releaseDate;
                    if (DateTime.TryParseExact(released, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out releaseDate))
                    {
                        if (releaseDate > GlobalDefs.NO_BROADCAST_TIME)
                        {
                            if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > releaseDate.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 IMDB dates, IMDB Dates are more reliable than video metadata usually
                            {
                                videoTags.OriginalBroadcastDateTime = releaseDate;                                                                                      // IMDB stores time in network (local) timezone
                            }
                        }
                    }

                    string[] genres = (movie.genres == null ? null : movie.genres.ToArray()); // Get Genres
                    if (genres != null)
                    {
                        if (genres.Length > 0)
                        {
                            if (videoTags.Genres != null)
                            {
                                if (videoTags.Genres.Length == 0)
                                {
                                    videoTags.Genres = genres;
                                }
                            }
                            else
                            {
                                videoTags.Genres = genres;
                            }
                        }
                    }

                    if (String.IsNullOrWhiteSpace(videoTags.MediaCredits)) // Get the media credits
                    {
                        videoTags.MediaCredits = ((movie.actors != null) ? String.Join(";", movie.actors.Select(s => s.actorName)) : "");
                    }

                    if (String.IsNullOrWhiteSpace(videoTags.Rating)) // Get the ratings
                    {
                        videoTags.Rating = movie.rated;
                    }

                    // Download the banner file
                    VideoMetaData.DownloadBannerFile(videoTags, movie.urlPoster); // Get bannerfile

                    return(true);                                                 // We found it, get out home free
                }

                // Check if we have reached the limit for the results (currently 10 is the max returned in a single query), if so then check the next set of results
                if (searchResults.Count == MY_API_SEARCH_LIMIT)
                {
                    return(DownloadMovieDetails(videoTags, dontOverwriteTitle, jobLog, offset + MY_API_SEARCH_LIMIT));
                }

                jobLog.WriteEntry("No match found on IMDB", Log.LogEntryType.Debug);
                return(false);
            }
            catch (Exception e)
            {
                jobLog.WriteEntry("Unable to initialize IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                return(false);
            }
        }
Example #6
0
        private const int MY_API_SEARCH_LIMIT = 10; // Max number of results that can be returned in a single search

        /// <summary>
        /// Downloads the information for a movie or series episode (no matching) given the IMDB ID for the movie or episode (not show)
        /// Uses OMDBApi
        /// </summary>
        /// <param name="videoTags">Video Tags structure with the IMDB ID</param>
        /// <returns>True if successful</returns>
        static public bool BootStrapByIMDBId(VideoTags videoTags, Log jobLog)
        {
            try
            {
                OMDBApi.SearchResult result = new OMDBApi.SearchResult();

                if (String.IsNullOrWhiteSpace(videoTags.imdbId)) // do we have a valid ID to begin with
                {
                    return(false);
                }

                try
                {
                    WebClient client = new WebClient();
                    client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
                    string response = client.DownloadString(new Uri("http://www.omdbapi.com/?i=" + videoTags.imdbId + "&r=json"));

                    result = JsonConvert.DeserializeObject <OMDBApi.SearchResult>(response);
                }
                catch (Exception e)
                {
                    jobLog.WriteEntry("Unable to bootstrap from IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                    return(false); // invalid JSON string
                }

                if (String.IsNullOrWhiteSpace(result.Title)) // Check if got a valid result
                {
                    jobLog.WriteEntry("Unable to boot strap, IMDB returned empty Title", Log.LogEntryType.Debug);
                    return(false);
                }

                // Check if it's a movie
                if (result.Type.ToLower().Contains("movie"))
                {
                    videoTags.Title = result.Title; // Take what is forced for the imdb movie id

                    videoTags.IsMovie = true;

                    // Get Overview
                    string overview = result.Plot;
                    if (!String.IsNullOrWhiteSpace(overview) && String.IsNullOrWhiteSpace(videoTags.Description))
                    {
                        videoTags.Description = overview;
                    }

                    // Get original release date
                    DateTime releaseDate = GlobalDefs.NO_BROADCAST_TIME;
                    if (DateTime.TryParseExact(result.Released, "dd MMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out releaseDate))
                    {
                        if (releaseDate > GlobalDefs.NO_BROADCAST_TIME)
                        {
                            if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > releaseDate.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 IMDB dates, IMDB Dates are more reliable than video metadata usually
                            {
                                videoTags.OriginalBroadcastDateTime = releaseDate;                                                                                      // IMDB stores time in network (local) timezone
                            }
                        }
                    }

                    string[] genres = result.Genre.Split(','); // Get Genres
                    if (genres != null)
                    {
                        if (genres.Length > 0)
                        {
                            if (videoTags.Genres != null)
                            {
                                if (videoTags.Genres.Length == 0)
                                {
                                    videoTags.Genres = genres;
                                }
                            }
                            else
                            {
                                videoTags.Genres = genres;
                            }
                        }
                    }

                    // Download the banner file
                    VideoMetaData.DownloadBannerFile(videoTags, result.Poster); // Get bannerfile

                    return(true);                                               // We found it, get out home free
                }
                else // Process as a series
                {
                    DateTime seriesPremiereDate = GlobalDefs.NO_BROADCAST_TIME;
                    DateTime.TryParseExact(result.Released, "dd MMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out seriesPremiereDate);

                    string   episodeName     = result.Title;            // Title here is the episode name since we are forcing a IMDB ID leading directly to a episode (the Showname is taken from the filename or metadata)
                    string   bannerUrl       = result.Poster;           // Get Poster URL
                    string[] genres          = result.Genre.Split(','); // Get Genres
                    string   episodeOverview = result.Plot;             // Get Overview

                    if (!String.IsNullOrWhiteSpace(episodeName) && String.IsNullOrWhiteSpace(videoTags.SubTitle))
                    {
                        videoTags.SubTitle = episodeName;
                    }
                    if (!String.IsNullOrWhiteSpace(episodeOverview) && String.IsNullOrWhiteSpace(videoTags.Description))
                    {
                        videoTags.Description = episodeOverview;
                    }
                    else if (!String.IsNullOrWhiteSpace(episodeOverview) && (String.IsNullOrWhiteSpace(videoTags.Description)))
                    {
                        videoTags.Description = episodeOverview;
                    }
                    if (seriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME)
                    {
                        if ((videoTags.SeriesPremiereDate <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.SeriesPremiereDate.Date > seriesPremiereDate.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 IMDB dates, IMDB Dates are more reliable than video metadata usually
                        {
                            videoTags.SeriesPremiereDate = seriesPremiereDate;                                                                               // IMDB stores time in network (local) timezone
                        }
                    }
                    if (genres != null)
                    {
                        if (genres.Length > 0)
                        {
                            if (videoTags.Genres != null)
                            {
                                if (videoTags.Genres.Length == 0)
                                {
                                    videoTags.Genres = genres;
                                }
                            }
                            else
                            {
                                videoTags.Genres = genres;
                            }
                        }
                    }

                    // Check if it's a sport series
                    if (videoTags.Genres != null)
                    {
                        if (videoTags.Genres.Length > 0)
                        {
                            if (videoTags.Genres.Contains("sport", StringComparer.OrdinalIgnoreCase))
                            {
                                videoTags.IsSports = true;
                            }
                        }
                    }

                    // Download the banner file
                    VideoMetaData.DownloadBannerFile(videoTags, bannerUrl); // Get bannerfile

                    return(true);                                           // Golden
                }
            }
            catch (Exception e)
            {
                jobLog.WriteEntry("Unable to use IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                return(false);
            }
        }
Example #7
0
        /// <summary>
        /// Match the series information by Episode name
        /// </summary>
        private static bool MatchByEpisodeName(TMDbClient client, VideoTags videoTags, TvShow tvShow, Log jobLog)
        {
            if (String.IsNullOrWhiteSpace(videoTags.SubTitle))
            {
                jobLog.WriteEntry("Invalid episode name to match", Log.LogEntryType.Debug);
                return(false); //Nothing to match here
            }


            // Cycle through all Seasons and Episodes looking for a match
            for (int sNo = 0; sNo <= tvShow.NumberOfSeasons; sNo++)
            {
                TvSeason season = client.GetTvSeasonAsync(tvShow.Id, sNo).Result;
                if (season == null || season.Episodes == null)
                {
                    continue;
                }

                for (int eNo = 0; eNo <= season.Episodes.Count; eNo++)
                {
                    TvEpisode episode = client.GetTvEpisodeAsync(tvShow.Id, sNo, eNo).Result;
                    if (episode == null)
                    {
                        continue;
                    }

                    string episodeName = episode.Name;

                    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 episodeNo          = episode.EpisodeNumber;
                            int seasonNo           = season.SeasonNumber;
                            string episodeOverview = episode.Overview;
                            string overview        = season.Overview;
                            string tvdbID          = (episode.ExternalIds != null ? (episode.ExternalIds.TvdbId != null ? episode.ExternalIds.TvdbId.ToString() : "") : "");
                            string imdbID          = (episode.ExternalIds != null ? episode.ExternalIds.ImdbId : "");
                            string tmdbID          = (tvShow.Id != 0 ? tvShow.Id.ToString() : "");
                            string network         = (tvShow.Networks != null ? String.Join(";", tvShow.Networks.Select(s => s.Name)) : "");
                            DateTime premiereDate  = GlobalDefs.NO_BROADCAST_TIME;
                            if (tvShow.FirstAirDate != null)
                            {
                                premiereDate = (DateTime)tvShow.FirstAirDate;
                            }
                            List <string> genres = (tvShow.Genres != null ? tvShow.Genres.Select(s => s.Name).ToList() : new List <string>());
                            DateTime firstAired  = (DateTime)(episode.AirDate != null ? episode.AirDate : GlobalDefs.NO_BROADCAST_TIME);
                            string mediaCredits  = (tvShow.Credits != null ? ((tvShow.Credits.Cast != null) ? String.Join(";", tvShow.Credits.Cast.Select(s => s.Name)) : "") : "");

                            client.GetConfig();                                                                                            // First we need to get the config
                            VideoMetaData.DownloadBannerFile(videoTags, client.GetImageUrl("original", tvShow.PosterPath).OriginalString); // 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(tvdbID) && String.IsNullOrWhiteSpace(videoTags.tvdbId))
                            {
                                videoTags.tvdbId = tvdbID;
                            }
                            if (!String.IsNullOrWhiteSpace(imdbID) && String.IsNullOrWhiteSpace(videoTags.imdbId))
                            {
                                videoTags.imdbId = imdbID;
                            }
                            if (!String.IsNullOrWhiteSpace(tmdbID) && String.IsNullOrWhiteSpace(videoTags.tmdbId))
                            {
                                videoTags.tmdbId = tmdbID;
                            }
                            if (!String.IsNullOrWhiteSpace(network) && String.IsNullOrWhiteSpace(videoTags.Network))
                            {
                                videoTags.Network = network;
                            }
                            if (!String.IsNullOrWhiteSpace(mediaCredits) && String.IsNullOrWhiteSpace(videoTags.MediaCredits))
                            {
                                videoTags.MediaCredits = mediaCredits;
                            }
                            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();
                                }
                            }

                            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 by episode name on TMDB", Log.LogEntryType.Debug);

            return(false); // nothing matches
        }
Example #8
0
        static public bool DownloadMovieDetails(VideoTags videoTags, bool dontOverwriteTitle, Log jobLog)
        {
            // The new v3 database is accessed via the TMDbLib API's
            try
            {
                TMDbClient client = new TMDbClient(MCEBUDDY_TMDB_APIKey);
                // List<SearchMovie> movieSearch = new List<SearchMovie>();
                SearchContainer <SearchMovie> movieSearch = new SearchContainer <SearchMovie>();
                Movie movieMatch = null;

                // TODO: Add support for multiple language searches
                if (String.IsNullOrWhiteSpace(videoTags.imdbId))                            // If dont' have a specific movieId specified, look up the movie details
                {
                    if (videoTags.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) // Release date narrow down
                    {
                        // 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
                        DateTime dt = videoTags.OriginalBroadcastDateTime.ToLocalTime();
                        movieSearch = client.SearchMovieAsync(videoTags.Title.Trim().ToLower(), 0, true, dt.Year).Result;
                    }
                    else // Title Check
                    {
                        movieSearch = client.SearchMovieAsync(videoTags.Title.Trim().ToLower(), 0, true, 0).Result;
                    }
                }
                else // Specific ID
                {
                    movieMatch = client.GetMovieAsync(videoTags.imdbId).Result; // We have a specific movie to work with
                }

                if (movieMatch == null)                                      // If we haven't forced a movie match
                {
                    foreach (SearchMovie movieResult in movieSearch.Results) // Cycle through all possible combinations
                    {
                        Movie movie = client.GetMovieAsync(movieResult.Id).Result;
                        List <AlternativeTitle> akaValues = null;
                        if (movie.AlternativeTitles != null)
                        {
                            akaValues = movie.AlternativeTitles.Titles;
                        }
                        bool   akaMatch = false;
                        string title    = videoTags.Title;
                        if (akaValues != null) // Check if there are any AKA names to match
                        {
                            akaMatch = akaValues.Any(s => (String.Compare(s.Title.Trim(), title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0 ? true : false));
                        }

                        // Get and match Movie name (check both titles and aka values)
                        if (String.Compare(movie.Title.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) != 0)             // ignore white space and special characters
                        {
                            if (String.Compare(movie.OriginalTitle.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) != 0) // ignore white space and special characters
                            {
                                if (!akaMatch)                                                                                                                                                     // check for aka value matches
                                {
                                    continue;                                                                                                                                                      // No match in name
                                }
                            }
                        }
                        // If we got here, then we found a match
                        movieMatch = movie;
                        break; // We are done here
                    }
                }

                if (movieMatch != null)                                                      // We have a match
                {
                    if (!String.IsNullOrWhiteSpace(videoTags.imdbId) && !dontOverwriteTitle) // Match names only if the movie imdb id is not forced, else take what is returned by moviedb
                    {
                        videoTags.Title = movieMatch.Title;                                  // Take what is forced for the imdb movie id
                    }
                    // Get Movie Id
                    videoTags.tmdbId = movieMatch.Id.ToString();

                    videoTags.IsMovie = true; // this is a movie

                    // Get Overview
                    string overview = movieMatch.Overview;
                    if (!String.IsNullOrWhiteSpace(overview) && String.IsNullOrWhiteSpace(videoTags.Description))
                    {
                        videoTags.Description = overview;
                    }

                    // Get original release date
                    if (movieMatch.ReleaseDate != null)
                    {
                        DateTime releaseDate = (DateTime)movieMatch.ReleaseDate;
                        if (releaseDate > GlobalDefs.NO_BROADCAST_TIME)
                        {
                            if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > releaseDate.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 MovieDB dates, MovieDB Dates are more reliable than video metadata usually
                            {
                                videoTags.OriginalBroadcastDateTime = releaseDate;                                                                                      // MovieDB stores time in network (local) timezone
                            }
                        }
                    }

                    // Get Genres
                    List <string> genres = new List <string>();
                    foreach (Genre genre in movieMatch.Genres)
                    {
                        genres.Add(genre.Name);
                    }
                    if (genres.Count > 0)
                    {
                        if (videoTags.Genres != null)
                        {
                            if (videoTags.Genres.Length == 0)
                            {
                                videoTags.Genres = genres.ToArray();
                            }
                        }
                        else
                        {
                            videoTags.Genres = genres.ToArray();
                        }
                    }

                    // Download the banner file
                    client.GetConfig();                                                                                                // First we need to get the config
                    VideoMetaData.DownloadBannerFile(videoTags, client.GetImageUrl("original", movieMatch.PosterPath).OriginalString); // Get bannerfile

                    return(true);                                                                                                      // home free, we're good
                }

                jobLog.WriteEntry("No match found in TMDB", Log.LogEntryType.Debug);

                return(false);
            }
            catch (Exception e)
            {
                jobLog.WriteEntry("Unable to connect to TMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning);
                return(false);
            }
        }
Example #9
0
        /// <summary>
        /// Match the series information by Original Broadcast date
        /// </summary>
        private static bool MatchByBroadcastTime(TMDbClient client, VideoTags videoTags, TvShow tvShow, bool dontOverwriteTitle, Log jobLog)
        {
            if (videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME)
            {
                jobLog.WriteEntry("Invalid original broadcast date to match", Log.LogEntryType.Debug);
                return(false); //Nothing to match here
            }


            // Cycle through all Seasons and Episodes looking for a match
            for (int sNo = 0; sNo <= tvShow.NumberOfSeasons; sNo++)
            {
                TvSeason season = client.GetTvSeason(tvShow.Id, sNo);
                if (season == null || season.Episodes == null)
                {
                    continue;
                }

                for (int eNo = 0; eNo <= season.Episodes.Count; eNo++)
                {
                    TvEpisode episode = client.GetTvEpisode(tvShow.Id, sNo, eNo);
                    if (episode == null)
                    {
                        continue;
                    }

                    string episodeName = episode.Name;

                    if (!String.IsNullOrWhiteSpace(episodeName))
                    {
                        DateTime firstAired = episode.AirDate;
                        if (firstAired == null || firstAired <= GlobalDefs.NO_BROADCAST_TIME)
                        {
                            continue;
                        }

                        if ((firstAired.Date == videoTags.OriginalBroadcastDateTime.ToLocalTime().Date) || // TMDB only reports the date not the time
                            (firstAired.Date == videoTags.OriginalBroadcastDateTime.ToUniversalTime().Date))
                        {
                            int episodeNo          = episode.EpisodeNumber;
                            int seasonNo           = season.SeasonNumber;
                            string episodeOverview = episode.Overview;
                            string overview        = season.Overview;
                            string tvdbID          = (episode.ExternalIds != null ? (episode.ExternalIds.TvdbId != null ? episode.ExternalIds.TvdbId.ToString() : "") : "");
                            string imdbID          = (episode.ExternalIds != null ? episode.ExternalIds.ImdbId : "");
                            string tmdbID          = (tvShow.Id != 0 ? tvShow.Id.ToString() : "");
                            string network         = (tvShow.Networks != null ? String.Join(";", tvShow.Networks.Select(s => s.Name)) : "");
                            DateTime premiereDate  = GlobalDefs.NO_BROADCAST_TIME;
                            if (tvShow.FirstAirDate != null)
                            {
                                premiereDate = (DateTime)tvShow.FirstAirDate;
                            }
                            List <string> genres = (tvShow.Genres != null ? tvShow.Genres.Select(s => s.Name).ToList() : new List <string>());
                            string mediaCredits  = (tvShow.Credits != null ? ((tvShow.Credits.Cast != null) ? String.Join(";", tvShow.Credits.Cast.Select(s => s.Name)) : "") : "");
                            string seriesName    = tvShow.Name;

                            client.GetConfig();                                                                                            // First we need to get the config
                            VideoMetaData.DownloadBannerFile(videoTags, client.GetImageUrl("original", tvShow.PosterPath).OriginalString); // Get bannerfile

                            // TODO: At what point do we go from supplementing to being primary?
                            // Since TVDB is primary we only supplement data
                            if ((episodeNo != 0) && (videoTags.Episode == 0))
                            {
                                videoTags.Episode = episodeNo;
                            }
                            if ((seasonNo != 0) && (videoTags.Season == 0))
                            {
                                videoTags.Season = seasonNo;
                            }
                            if (!String.IsNullOrWhiteSpace(seriesName) && String.IsNullOrWhiteSpace(videoTags.Title) && !dontOverwriteTitle)
                            {
                                videoTags.Title = seriesName;
                            }
                            if (!String.IsNullOrWhiteSpace(episodeName) && String.IsNullOrWhiteSpace(videoTags.SubTitle))
                            {
                                videoTags.SubTitle = episodeName;
                            }
                            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(tvdbID) && String.IsNullOrWhiteSpace(videoTags.tvdbId))
                            {
                                videoTags.tvdbId = tvdbID;
                            }
                            if (!String.IsNullOrWhiteSpace(imdbID) && String.IsNullOrWhiteSpace(videoTags.imdbId))
                            {
                                videoTags.imdbId = imdbID;
                            }
                            if (!String.IsNullOrWhiteSpace(tmdbID) && String.IsNullOrWhiteSpace(videoTags.tmdbId))
                            {
                                videoTags.tmdbId = tmdbID;
                            }
                            if (!String.IsNullOrWhiteSpace(network) && String.IsNullOrWhiteSpace(videoTags.Network))
                            {
                                videoTags.Network = network;
                            }
                            if (!String.IsNullOrWhiteSpace(mediaCredits) && String.IsNullOrWhiteSpace(videoTags.MediaCredits))
                            {
                                videoTags.MediaCredits = mediaCredits;
                            }
                            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 for broadcast date on TMDB", Log.LogEntryType.Debug);

            return(false); // nothing matches
        }