/// <summary> /// Used to execute custom commands after the conversion process is compelte just before the file is moved to the desination directory /// </summary> /// <param name="prefix">Prefix for reading lines from profile</param> /// <param name="profile">Profile name</param> /// <param name="taskName">Task Name</param> /// <param name="workingPath">Temp working path</param> /// <param name="destinationPath">Destination path for converted file</param> /// <param name="convertedFile">Full path to final converted file</param> /// <param name="sourceFile">Full path to original source file</param> /// <param name="remuxFile">Full path to intermediate remuxed file</param> /// <param name="edlFile">Full path to EDL file</param> /// <param name="srtFile">Full path to SRT file</param> /// <param name="metaData">Video metadata structure for source file</param> /// <param name="jobStatus">ref to JobStatus</param> /// <param name="jobLog">JobLog</param> public CustomCommand(string prefix, string profile, string taskName, string workingPath, string destinationPath, string convertedFile, string sourceFile, string remuxFile, string edlFile, string srtFile, VideoTags metaData, JobStatus jobStatus, Log jobLog) { _profile = profile; _taskName = taskName; _jobLog = jobLog; _jobStatus = jobStatus; _workingPath = workingPath; _destinationPath = destinationPath; _convertedFile = convertedFile; _sourceFile = sourceFile; _remuxFile = remuxFile; _edlFile = edlFile; _srtFile = srtFile; _metaData = metaData; _prefix = prefix; Ini ini = new Ini(GlobalDefs.ProfileFile); commandPath = ini.ReadString(profile, prefix + "Path", "").ToLower().Trim(); commandParameters = ini.ReadString(profile, prefix + "Parameters", ""); hangPeriod = ini.ReadInteger(profile, prefix + "HangPeriod", GlobalDefs.HANG_PERIOD_DETECT); customCommandCritical = ini.ReadBoolean(profile, prefix + "Critical", false); // NOTE: if customCommandCritical is TRUE will need to return false in case it's a failure customCommandUISession = ini.ReadBoolean(profile, prefix + "UISession", false); // Does the custom command need a UI Session (Session 1) with admin privileges customCommandShowWindow = ini.ReadBoolean(profile, prefix + "ShowWindow", true); // Show the window or hide it customCommandExitCodeCheck = ini.ReadBoolean(profile, prefix + "ExitCodeCheck", false); // Don't check for exit code _jobLog.WriteEntry(this, "Custom command parameters read -> " + " \n" + _prefix + "Path = " + commandPath + " \n" + _prefix + "Parameters = " + commandParameters + " \n" + _prefix + "HangPeriod = " + hangPeriod.ToString(System.Globalization.CultureInfo.InvariantCulture) + " \n" + _prefix + "Critical = " + customCommandCritical.ToString() + " \n" + _prefix + "UISession = " + customCommandUISession.ToString() + " \n" + _prefix + "ShowWindow = " + customCommandShowWindow.ToString() + " \n" + _prefix + "ExitCodeCheck = " + customCommandExitCodeCheck.ToString(), Log.LogEntryType.Debug); }
private void TransferVideoTag() { var oldVideoTags = _oldDbContext.VideoTag.Include(t => t.Tag).Include(m => m.Video).ToList(); var newVideoTags = _newDbContext.VideoTags.Include(t => t.Tag).ToList(); var newTags = _newDbContext.Tags.ToList(); var oldTags = _oldDbContext.Tag.ToList(); foreach (var oldVideoTag in oldVideoTags) { var oldTag = oldTags.FirstOrDefault(t => t.Id == oldVideoTag.TagId); var newTag = newTags.FirstOrDefault(t => t.Name == oldTag.Name); var findVideoTag = newVideoTags.FirstOrDefault(mt => mt.Tag.Name == newTag.Name); if (findVideoTag == null) { var video = _newDbContext.Videos.FirstOrDefault(m => oldVideoTag.Video.Title == m.Title); var newVideoTag = new VideoTags() { TagId = newTag.Id, VideoId = video.Id }; _newDbContext.VideoTags.Add(newVideoTag); _newDbContext.SaveChanges(); } } }
public void WriteVideoTags(VideoTags videoTags) { WriteByte((byte)((byte)videoTags.FrameType | (byte)videoTags.CodecId)); if (videoTags.CodecId == CodecId.AvcVideoPacke) { WriteAvcVideoPacke(videoTags.VideoData); } }
static public bool DownloadSeriesDetails(VideoTags videoTags, bool prioritizeMatchDate, bool dontOverwriteTitle, Log jobLog) { if (!DownloadSeriesDetails(prioritizeMatchDate, videoTags, dontOverwriteTitle, jobLog)) // First try to match by Episode Name (by default prioritize match date is false) { return(DownloadSeriesDetails(!prioritizeMatchDate, videoTags, dontOverwriteTitle, jobLog)); // Other try to match by Original Air Date (since multiple shows can be aired on the same date) (by default prioritize match date is false) } else { return(true); // We were successful } }
bool VideoContainsTag(VideoData videoData, VideoTags videoTag) { foreach (var tag in videoData.videoTags) { if (tag == videoTag) { return(true); } } return(false); }
/// <summary> /// Match and download the series information /// </summary> /// <param name="videoTags">Video tags</param> /// <param name="seriesID">TVDB Series ID</param> /// <param name="matchByAirDate">True to match by original broadcast date, 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></returns> private static bool MatchSeriesInformation(VideoTags videoTags, string seriesID, bool matchByAirDate, bool dontOverwriteTitle, Log jobLog) { if (matchByAirDate) // User requested priority // Match by original broadcast date { return(MatchByBroadcastTime(videoTags, seriesID, dontOverwriteTitle, jobLog)); } else { // Match by Episode name return(MatchByEpisodeName(videoTags, seriesID, jobLog)); } }
/// <summary> /// Match and download the series information /// </summary> /// <param name="videoTags">Video tags</param> /// <param name="tvShow">TVDB Series ID</param> /// <param name="matchByAirDate">True to match by original broadcast date, 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></returns> private static bool MatchSeriesInformation(TMDbClient client, VideoTags videoTags, TvShow tvShow, bool matchByAirDate, bool dontOverwriteTitle, Log jobLog) { if (matchByAirDate) // User requested priority // Match by original broadcast date { return(MatchByBroadcastTime(client, videoTags, tvShow, dontOverwriteTitle, jobLog)); } else { // Match by Episode name return(MatchByEpisodeName(client, videoTags, tvShow, jobLog)); } }
public VideoModel Load(Guid id) { Video video = Videos.SingleOrDefault(v => v.Id == id); if (video == null) { return(null); } return(new VideoModel { Video = video, Owner = Users.SingleOrDefault(u => u.Id == video.OwnerId), Channels = Channels.Where(c => ChannelVideos.Where(v => v.VideoId == video.Id).Select(v => v.ChannelId).Contains(c.Id)), Tags = Tags.Where(t => VideoTags.Where(v => v.VideoId == video.Id).Select(v => v.TagId).Contains(t.Id)), Views = Views.Where(v => v.VideoId == video.Id), Reactions = Reactions.Where(r => r.VideoId == video.Id), Favourites = Favourites.Where(f => f.VideoId == video.Id), Comments = Comments.Where(c => c.VideoId == video.Id) }); }
private void customFileRenamePattern_TextChanged(object sender, EventArgs e) { string newFileName = ""; string destinationPath = ""; VideoTags metaData = new VideoTags() { Title = "Title", SubTitle = "Subtitle", Description = "Meta description", Network = "Network", Rating = "PG", MediaCredits = "Credits", Genres = new string[1] { "Genre" }, Season = 1, Episode = 2, BannerFile = "Banner File Path", BannerURL = "Banner URL", imdbId = "IMDBID", tmdbId = "TMDBID", tvdbId = "TVDBID", IsMovie = true, IsSports = true, OriginalBroadcastDateTime = new DateTime(2010, 1, 1), RecordedDateTime = DateTime.Now, SeriesPremiereDate = new DateTime(2000, 1, 1), CopyProtected = true, sageTV = new VideoTags.SageTV { airingDbId = "airingDb", mediaFileDbId = "mediaFileDb" } }; try { MetaData.CustomRename.CustomRenameFilename(customFileRenamePattern.Text, ref newFileName, ref destinationPath, "Original Filename.wtv", metaData, new Log(Log.LogDestination.Null)); customRenamePreview.Text = Path.Combine(destinationPath, newFileName); // Show the Text } catch { customRenamePreview.Text = Localise.GetPhrase("Invalid Filename Pattern"); } }
/// <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); }
/// <summary> /// Replaces a string of user custom parameters from the metadata /// </summary> /// <param name="commandParameters">Original string of user custom Parameters</param> /// <param name="workingPath">Temp working path</param> /// <param name="destinationPath">Destination path for converted file</param> /// <param name="convertedFile">Full path to final converted file</param> /// <param name="sourceFile">Full path to original source file</param> /// <param name="remuxFile">Full path to intermediate remuxed file</param> /// <param name="edlFile">Full path to EDL file</param> /// <param name="srtFile">Full path to SRT file</param> /// <param name="profile">Profile name</param> /// <param name="taskName">Task Name</param> /// <param name="metaData">Video metadata structure for source file</param> /// <param name="jobLog">JobLog</param> /// <returns>Converted string of custom parameters, empty string if there is an error</returns> public static string CustomParamsReplace( string commandParameters, string workingPath, string destinationPath, string convertedFile, string sourceFile, string remuxFile, string edlFile, string srtFile, string profile, string taskName, VideoTags metaData, Log jobLog) { string translatedCommand = ""; if (metaData == null) { metaData = new VideoTags(); // Incase Metadata does not exit, create an empty metadata so it doesn't crash the function } // SRT and EDl files are substitued if they exist otherwise they are "" if (!File.Exists(srtFile)) { srtFile = ""; } if (!File.Exists(edlFile)) { edlFile = ""; } try { char[] commandBytes = commandParameters.ToCharArray(); for (int i = 0; i < commandBytes.Length; i++) { switch (commandBytes[i]) { case '%': string command = ""; while (commandBytes[++i] != '%') { command += commandBytes[i].ToString(System.Globalization.CultureInfo.InvariantCulture).ToLower(); } string format = ""; switch (command) { case "taskname": translatedCommand += (taskName); // Preserve case for parameters break; case "profile": translatedCommand += (profile); // Preserve case for parameters break; case "convertedfile": translatedCommand += (convertedFile); // Preserve case for parameters break; case "sourcefile": translatedCommand += (sourceFile); // Preserve case for parameters break; case "remuxfile": translatedCommand += (remuxFile); // Preserve case for parameters break; case "workingpath": translatedCommand += (workingPath); // Preserve case for parameters break; case "destinationpath": translatedCommand += (destinationPath); // Preserve case for parameters break; case "srtfile": translatedCommand += (srtFile); // Preserve case for parameters break; case "edlfile": translatedCommand += (edlFile); // Preserve case for parameters break; case "originalfilepath": translatedCommand += (Path.GetDirectoryName(sourceFile)); // Preserve case for parameters break; case "originalfilename": translatedCommand += (Path.GetFileNameWithoutExtension(sourceFile)); // Preserve case for parameters break; case "originalext": // Extension of the source file translatedCommand += FilePaths.CleanExt(sourceFile).Replace(".", ""); break; case "convertedext": // Extension of the converted file translatedCommand += FilePaths.CleanExt(convertedFile).Replace(".", ""); break; case "showname": translatedCommand += (metaData.Title); // Preserve case for parameters break; case "genre": translatedCommand += (metaData.Genres != null ? (metaData.Genres.Length > 0 ? metaData.Genres[0] : "") : ""); // Preserve case for parameters break; case "episodename": translatedCommand += (metaData.SubTitle); // Preserve case for parameters break; case "episodedescription": translatedCommand += (metaData.Description); // Preserve case for parameters break; case "network": translatedCommand += (metaData.Network); // Preserve case for parameters break; case "bannerfile": translatedCommand += (metaData.BannerFile); // Preserve case for parameters break; case "bannerurl": translatedCommand += (metaData.BannerURL); // Preserve case for parameters break; case "movieid": translatedCommand += (metaData.tmdbId); // Preserve case for parameters break; case "imdbmovieid": translatedCommand += (metaData.imdbId); // Preserve case for parameters break; case "seriesid": translatedCommand += (metaData.tvdbId); // Preserve case for parameters break; case "season": format = ""; try { if (commandBytes[i + 1] == '#') { while (commandBytes[++i] == '#') { format += "0"; } --i; // adjust for last increment } } catch { } // this is normal incase it doesn't exist translatedCommand += ((metaData.Season == 0 ? "" : metaData.Season.ToString(format))); // Preserve case for parameters break; case "episode": format = ""; try { if (commandBytes[i + 1] == '#') { while (commandBytes[++i] == '#') { format += "0"; } --i; // adjust for last increment } } catch { } // this is normal incase it doesn't exist translatedCommand += ((metaData.Episode == 0 ? "" : metaData.Episode.ToString(format))); // Preserve case for parameters break; case "issport": translatedCommand += (metaData.IsSports.ToString(CultureInfo.InvariantCulture)); // Preserve case for parameters break; case "ismovie": translatedCommand += (metaData.IsMovie.ToString(CultureInfo.InvariantCulture)); // Preserve case for parameters break; case "premiereyear": translatedCommand += ((metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) ? metaData.SeriesPremiereDate.ToLocalTime().ToString("yyyy") : ""); // Preserve case for parameters break; case "premieremonth": translatedCommand += ((metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) ? metaData.SeriesPremiereDate.ToLocalTime().ToString("%M") : ""); // Preserve case for parameters break; case "premieremonthshort": translatedCommand += ((metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) ? metaData.SeriesPremiereDate.ToLocalTime().ToString("MMM") : ""); // Preserve case for parameters, culture sensitive break; case "premieremonthlong": translatedCommand += ((metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) ? metaData.SeriesPremiereDate.ToLocalTime().ToString("MMMM") : ""); // Preserve case for parameters, culture sensitive break; case "premiereday": translatedCommand += ((metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) ? metaData.SeriesPremiereDate.ToLocalTime().ToString("%d") : ""); // Preserve case for parameters break; case "premieredayshort": translatedCommand += ((metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) ? metaData.SeriesPremiereDate.ToLocalTime().ToString("ddd") : ""); // Preserve case for parameters, culture sensitive break; case "premieredaylong": translatedCommand += ((metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) ? metaData.SeriesPremiereDate.ToLocalTime().ToString("dddd") : ""); // Preserve case for parameters, culture sensitive break; case "airyear": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("yyyy") : ""); // Preserve case for parameters break; case "airmonth": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("%M") : ""); // Preserve case for parameters break; case "airmonthshort": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("MMM") : ""); // Preserve case for parameters, culture sensitive break; case "airmonthlong": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("MMMM") : ""); // Preserve case for parameters, culture sensitive break; case "airday": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("%d") : ""); // Preserve case for parameters break; case "airdayshort": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("ddd") : ""); // Preserve case for parameters, culture sensitive break; case "airdaylong": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("dddd") : ""); // Preserve case for parameters, culture sensitive break; case "airhour": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("%h") : ""); // Preserve case for parameters break; case "airhourampm": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("tt") : ""); // Preserve case for parameters break; case "airminute": translatedCommand += ((metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("%m") : ""); // Preserve case for parameters break; case "recordyear": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("yyyy") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("yyyy")); // Preserve case for parameters break; case "recordmonth": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("%M") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("%M")); // Preserve case for parameters break; case "recordmonthshort": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("MMM") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("MMM")); // Preserve case for parameters, culture sensitive break; case "recordmonthlong": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("MMMM") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("MMMM")); // Preserve case for parameters, culture sensitive break; case "recordday": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("%d") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("%d")); // Preserve case for parameters break; case "recorddayshort": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("ddd") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("ddd")); // Preserve case for parameters, culture sensitive break; case "recorddaylong": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("dddd") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("dddd")); // Preserve case for parameters, culture sensitive break; case "recordhour": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("%h") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("%h")); // Preserve case for parameters break; case "recordhourampm": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("tt") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("tt")); // Preserve case for parameters break; case "recordminute": translatedCommand += ((metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) ? metaData.RecordedDateTime.ToLocalTime().ToString("%m") : Util.FileIO.GetFileCreationTime(sourceFile).ToString("%m")); // Preserve case for parameters break; case "rating": // Parental rating translatedCommand += metaData.Rating; break; case "airingdbid": // SageTV Airing DbId translatedCommand += metaData.sageTV.airingDbId; break; case "mediafiledbid": // SageTV MediaFile DbId translatedCommand += metaData.sageTV.mediaFileDbId; break; default: jobLog.WriteEntry(Localise.GetPhrase("Invalid custom command format detected, skipping") + " : " + command, Log.LogEntryType.Warning); // We had an invalid format break; } break; default: translatedCommand += commandBytes[i]; break; } } } catch (Exception e) { jobLog.WriteEntry("Invalid custom params replace. Error " + e.ToString(), Log.LogEntryType.Warning); return(""); // return nothing } return(translatedCommand); }
/// <summary> /// This function is used to create a custom filename and path. /// This function throws an exception if an invalid rename pattern is provided /// </summary> /// <param name="customRenamePattern">The renaming pattern</param> /// <param name="newFileName">Reference to a string that will contain the new custom Filename</param> /// <param name="destinationPath">Reference to a string that will contains the new custom Path</param> /// <param name="sourceVideo">Path to Source Video file</param> /// <param name="metaData">Metadata for the Source Video file</param> /// <param name="jobLog">Log object</param> public static void CustomRenameFilename(string customRenamePattern, ref string newFileName, ref string destinationPath, string sourceVideo, VideoTags metaData, Log jobLog) { char[] renameBytes = customRenamePattern.ToCharArray(); for (int i = 0; i < renameBytes.Length; i++) { switch (renameBytes[i]) { case '%': string command = ""; while (renameBytes[++i] != '%') { command += renameBytes[i].ToString(System.Globalization.CultureInfo.InvariantCulture).ToLower(); } string format = ""; switch (command) { case "premiereyear": // %ad% - premiere Air Year if (metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.SeriesPremiereDate.ToLocalTime().Year.ToString("0000", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find PremiereYear"), Log.LogEntryType.Warning); } break; case "premieremonth": // %ad% - premiere Air Month if (metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.SeriesPremiereDate.ToLocalTime().Month.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find PremiereMonth"), Log.LogEntryType.Warning); } break; case "premieremonthshort": // %ad% - premiere Air Month abbreviation if (metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.SeriesPremiereDate.ToLocalTime().ToString("MMM"); // need to keep it culture sensitive here } else { jobLog.WriteEntry(("Cannot find PremiereMonthShort"), Log.LogEntryType.Warning); } break; case "premieremonthlong": // %ad% - premiere Air Month full name if (metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.SeriesPremiereDate.ToLocalTime().ToString("MMMM"); // need to keep it culture sensitive here } else { jobLog.WriteEntry(("Cannot find PremiereMonthLong"), Log.LogEntryType.Warning); } break; case "premiereday": // %ad% - premiere Air Date if (metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.SeriesPremiereDate.ToLocalTime().Day.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find PremiereDay"), Log.LogEntryType.Warning); } break; case "premieredayshort": // %ad% - premiere Air Day of week abbreviation if (metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.SeriesPremiereDate.ToLocalTime().ToString("ddd"); // need to keep it culture sensitive here } else { jobLog.WriteEntry(("Cannot find PremiereDayShort"), Log.LogEntryType.Warning); } break; case "premieredaylong": // %ad% - premiere Air Day of week full name if (metaData.SeriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.SeriesPremiereDate.ToLocalTime().ToString("dddd"); // need to keep it culture sensitive here } else { jobLog.WriteEntry(("Cannot find PremiereDayLong"), Log.LogEntryType.Warning); } break; case "airyear": // %ad% - original Air Year if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().Year.ToString("0000", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find AirYear"), Log.LogEntryType.Warning); } break; case "airmonth": // %ad% - original Air Month if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().Month.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find AirMonth"), Log.LogEntryType.Warning); } break; case "airmonthshort": // %ad% - original Air Month abbreviation if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("MMM"); // need to keep it culture sensitive here } else { jobLog.WriteEntry(("Cannot find AirMonthShort"), Log.LogEntryType.Warning); } break; case "airmonthlong": // %ad% - original Air Month full name if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("MMMM"); // need to keep it culture sensitive here } else { jobLog.WriteEntry(("Cannot find AirMonthLong"), Log.LogEntryType.Warning); } break; case "airday": // %ad% - original Air Date if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().Day.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find AirDay"), Log.LogEntryType.Warning); } break; case "airdayshort": // %ad% - original Air Day of week abbreviation if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("ddd"); // need to keep it culture sensitive here } else { jobLog.WriteEntry(("Cannot find AirDayShort"), Log.LogEntryType.Warning); } break; case "airdaylong": // %ad% - original Air Day of week full name if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("dddd"); // need to keep it culture sensitive here } else { jobLog.WriteEntry(("Cannot find AirDayLong"), Log.LogEntryType.Warning); } break; case "airhour": // %ad% - original Air Hour if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().Hour.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry("Cannot find AirHour", Log.LogEntryType.Warning); } break; case "airhourampm": // %ad% - original Air Hour AM/PM if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().ToString("tt"); } else { jobLog.WriteEntry("Cannot find AirHourAMPM", Log.LogEntryType.Warning); } break; case "airminute": // %ad% - original Air Minute if (metaData.OriginalBroadcastDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.OriginalBroadcastDateTime.ToLocalTime().Minute.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry("Cannot find AirMinute", Log.LogEntryType.Warning); } break; case "recordyear": // %rd% - Record Year if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().Year.ToString("0000", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find RecordYear using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.Year.ToString("0000", System.Globalization.CultureInfo.InvariantCulture); } } break; case "recordmonth": // %rd% - Record Month if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().Month.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find RecordMonth using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.Month.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } } break; case "recordmonthshort": // %rd% - Record Month abbreviation if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().ToString("MMM"); // Need to keep it culture sensitive } else { jobLog.WriteEntry(("Cannot find RecordMonthShort using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.ToString("MMM"); } } break; case "recordmonthlong": // %rd% - Record Month full name if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().ToString("MMMM"); // Need to keep it culture sensitive } else { jobLog.WriteEntry(("Cannot find RecordMonthLong using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.ToString("MMMM"); } } break; case "recordday": // %rd% - Record Day if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().Day.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find RecordDay using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.Day.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } } break; case "recorddayshort": // %rd% - Record Day of week abbreviation if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().ToString("ddd"); // Keep it culture sensitive } else { jobLog.WriteEntry(("Cannot find RecordDayShort using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.ToString("ddd"); } } break; case "recorddaylong": // %rd% - Record Day of week full name if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().ToString("dddd"); // Keep it culture sensitive } else { jobLog.WriteEntry(("Cannot find RecordDayLong using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.ToString("dddd"); } } break; case "recordhour": // Record Hour if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().Hour.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find RecordHour using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.Hour.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } } break; case "recordhourampm": // Record Hour AM/PM if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().ToString("tt"); } else { jobLog.WriteEntry(("Cannot find RecordHourAMPM using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.ToString("tt"); } } break; case "recordminute": // Record minute if (metaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { newFileName += metaData.RecordedDateTime.ToLocalTime().Minute.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry(("Cannot find RecordMinute using File Creation Date"), Log.LogEntryType.Warning); DateTime dt = Util.FileIO.GetFileCreationTime(sourceVideo); if (dt > GlobalDefs.NO_BROADCAST_TIME) { newFileName += dt.Minute.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } } break; case "originalfilename": // Name of the source file without the extension or path newFileName += Path.GetFileNameWithoutExtension(sourceVideo); break; case "originalext": // Extension of the source file newFileName += FilePaths.CleanExt(sourceVideo).Replace(".", ""); break; case "showname": // %sn% - Showname / title newFileName += metaData.Title; break; case "episodename": // %en% - episode name / subtitle if (!String.IsNullOrEmpty(metaData.SubTitle)) { newFileName += metaData.SubTitle; } else { jobLog.WriteEntry(("Cannot find Episode Name"), Log.LogEntryType.Warning); } break; case "network": // %en% - recorded channel name if (!String.IsNullOrEmpty(metaData.Network)) { newFileName += metaData.Network; } else { jobLog.WriteEntry(("Cannot find Network Channel Name"), Log.LogEntryType.Warning); } break; case "season": // %ss%### - season no format = ""; try { if (renameBytes[i + 1] == '#') { while (renameBytes[++i] == '#') { format += "0"; } --i; // adjust for last increment } } catch { } // this is normal incase it doesn't exist if (metaData.Season != 0) { newFileName += metaData.Season.ToString(format); } else { jobLog.WriteEntry(("Cannot find Season No"), Log.LogEntryType.Warning); } break; case "episode": // %ee%### - episode no format = ""; try { if (renameBytes[i + 1] == '#') { while (renameBytes[++i] == '#') { format += "0"; } --i; // adjust for last increment } } catch { } // this is normal incase it doesn't exist if (metaData.Episode != 0) { newFileName += metaData.Episode.ToString(format); } else { jobLog.WriteEntry(("Cannot find Episode No"), Log.LogEntryType.Warning); } break; case "ismovie": // Special condition allowing for separate renaming if it's a movie or not // FORMAT: %ismovie%<RenamePatternIfTrue,RenamePatternIfFalse> { string truePattern = "", falsePattern = ""; int nestedCount = 0; // number of < found for nested %ismovie%<Movie,%issport%<Sport,TV>,TV> type patterns while (renameBytes[++i] != '<') { ; // Skip until you get a < } while (renameBytes[++i] != ',') // Is it's a movie, rename pattern { truePattern += renameBytes[i].ToString(CultureInfo.InvariantCulture); } while (renameBytes[++i] != '>' || (nestedCount > 0)) // Is it's NOT a movie, rename pattern { if (renameBytes[i].ToString(CultureInfo.InvariantCulture) == "<") { nestedCount++; } if (renameBytes[i].ToString(CultureInfo.InvariantCulture) == ">") // compensate for the nested pattern { nestedCount--; } falsePattern += renameBytes[i].ToString(CultureInfo.InvariantCulture); } // Now parse the rename pattern and we're done if (metaData.IsMovie) { CustomRenameFilename(truePattern, ref newFileName, ref destinationPath, sourceVideo, metaData, jobLog); } else { CustomRenameFilename(falsePattern, ref newFileName, ref destinationPath, sourceVideo, metaData, jobLog); } } break; // We're done case "issport": // Special condition allowing for separate renaming if it's a sports show or not // FORMAT: %issports%<RenamePatternIfTrue,RenamePatternIfFalse> { string truePattern = "", falsePattern = ""; int nestedCount = 0; // number of < found for nested %issport%<Sport,%ismovie%<Movie,TV>,TV> type patterns while (renameBytes[++i] != '<') { ; // Skip until you get a < } while (renameBytes[++i] != ',') // Is it's a sports show, rename pattern { truePattern += renameBytes[i].ToString(CultureInfo.InvariantCulture); } while (renameBytes[++i] != '>' || (nestedCount > 0)) // Is it's NOT a sports show, rename pattern { if (renameBytes[i].ToString(CultureInfo.InvariantCulture) == "<") { nestedCount++; } if (renameBytes[i].ToString(CultureInfo.InvariantCulture) == ">") // compensate for the nested pattern { nestedCount--; } falsePattern += renameBytes[i].ToString(CultureInfo.InvariantCulture); } // Now parse the rename pattern and we're done if (metaData.IsSports) { CustomRenameFilename(truePattern, ref newFileName, ref destinationPath, sourceVideo, metaData, jobLog); } else { CustomRenameFilename(falsePattern, ref newFileName, ref destinationPath, sourceVideo, metaData, jobLog); } } break; // We're done case "rating": // Parental rating if (!String.IsNullOrEmpty(metaData.Rating)) { newFileName += metaData.Rating; } else { jobLog.WriteEntry(("Cannot find Parental Rating"), Log.LogEntryType.Warning); } break; case "airingdbid": // SageTV Airing DbId if (!String.IsNullOrEmpty(metaData.sageTV.airingDbId)) { newFileName += metaData.sageTV.airingDbId; } else { jobLog.WriteEntry(("Cannot find SageTV Airing DbId"), Log.LogEntryType.Warning); } break; case "mediafiledbid": // SageTV MediaFile DbId if (!String.IsNullOrEmpty(metaData.sageTV.mediaFileDbId)) { newFileName += metaData.sageTV.mediaFileDbId; } else { jobLog.WriteEntry(("Cannot find SageTV MediaFile DbId"), Log.LogEntryType.Warning); } break; default: jobLog.WriteEntry(("Invalid file naming format detected, skipping") + " : " + command, Log.LogEntryType.Warning); // We had an invalid format break; } break; case '\\': if (!string.IsNullOrWhiteSpace(destinationPath) && (destinationPath.Substring(destinationPath.Length - 1) != "\\")) // First directory should not start with a '\' and there should not be any consecutive '\' { destinationPath += "\\"; } destinationPath += newFileName; // Don't check for illegal filepaths here, do it in the end newFileName = ""; // reset the new filename break; default: newFileName += renameBytes[i]; // Don't check now for illegal filenames since it could become a filepath, will check in the end break; } } newFileName = Util.FilePaths.RemoveIllegalFilePathAndNameChars(newFileName); // Only accept characters which are not illegal in file paths and file names otherwise ignore }
static public bool DownloadSeriesDetails(VideoTags videoTags, bool prioritizeMatchDate, bool dontOverwriteTitle, Log jobLog) { // The new v3 database is accessed via the TMDbLib API's try { TMDbClient client = new TMDbClient(MCEBUDDY_TMDB_APIKey); List <SearchTv> showSearch = new List <SearchTv>(); // TODO: Add support for multiple language searches if (String.IsNullOrWhiteSpace(videoTags.tmdbId)) // If dont' have a specific movieId specified, look up the show 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(); showSearch = client.SearchTvShowAsync(videoTags.Title.Trim().ToLower(), 0).Result.Results; } else // Title Check { showSearch = client.SearchTvShowAsync(videoTags.Title.Trim().ToLower(), 0).Result.Results; } } else // Specific ID { TvShow showMatch = client.GetTvShowAsync(int.Parse(videoTags.tmdbId)).Result; // We have a specific show to work with // First match by Episode name and then by Original broadcast date (by default prioritize match date is false) if (!MatchSeriesInformation(client, videoTags, showMatch, prioritizeMatchDate, dontOverwriteTitle, jobLog)) { return(MatchSeriesInformation(client, videoTags, showMatch, !prioritizeMatchDate, dontOverwriteTitle, jobLog)); } else { return(true); } } foreach (SearchTv showResult in showSearch) // Cycle through all possible combinations { TvShow show = client.GetTvShowAsync(showResult.Id).Result; string title = videoTags.Title; // Get and match Show name (check both titles and aka values) if (String.Compare(show.Name.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) != 0) // ignore white space and special characters { if (String.Compare(show.OriginalName.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) != 0) // ignore white space and special characters { continue; // No match in name } } // If we got here, then we found a match // First match by Episode name and then by Original broadcast date (by default prioritize match date is false) if (!MatchSeriesInformation(client, videoTags, show, prioritizeMatchDate, dontOverwriteTitle, jobLog)) { if (MatchSeriesInformation(client, videoTags, show, !prioritizeMatchDate, dontOverwriteTitle, jobLog)) { return(true); } // Else we continue looping through the returned series looking for a match if nothing matches } else { return(true); } } jobLog.WriteEntry("No match found on TMDB Series", Log.LogEntryType.Debug); return(false); } catch (Exception e) { jobLog.WriteEntry("Unable to connect to TMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); } }
/// <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 }
/// <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 }
/// <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); } }
/// <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); } }
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); } }
public static bool DownloadSeriesDetails(VideoTags videoTags, bool prioritizeMatchDate, bool dontOverwriteTitle, Log jobLog) { XPathDocument Xp; XPathNavigator Nav; XPathExpression Exp; XPathNodeIterator Itr; // There are no TheTVDB mirrors, so skip that step // ****************** // Get the series ID // ****************** try { if (!String.IsNullOrWhiteSpace(videoTags.imdbId)) // If we have a specific IMDB movieId specified, look up the movie details on TVDB { Xp = new XPathDocument("http://www.thetvdb.com/api/GetSeriesByRemoteID.php?imdbid=" + videoTags.imdbId); } else if (!String.IsNullOrWhiteSpace(videoTags.tvdbId)) // If we have a specific TVDB seriesId specified, look up the series details { // First match by Episode name and then by Original broadcast date (by default prioritize match date is false) if (!MatchSeriesInformation(videoTags, videoTags.tvdbId, prioritizeMatchDate, dontOverwriteTitle, jobLog)) { return(MatchSeriesInformation(videoTags, videoTags.tvdbId, !prioritizeMatchDate, dontOverwriteTitle, jobLog)); } else { return(true); } } else // Generic search by name { Xp = new XPathDocument("http://www.thetvdb.com/api/GetSeries.php?seriesname=" + videoTags.Title); } Nav = Xp.CreateNavigator(); Exp = Nav.Compile("//Data/Series"); Itr = Nav.Select(Exp); } catch (Exception e) { jobLog.WriteEntry("Unable to connect to TVDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); } while (Itr.MoveNext()) // loop through all series returned trying to find a match { string seriesID = XML.GetXMLTagValue("seriesid", Itr.Current.OuterXml); string seriesTitle = XML.GetXMLTagValue("SeriesName", Itr.Current.OuterXml); string[] aliasNames = XML.GetXMLTagValue("AliasNames", Itr.Current.OuterXml).Split('|'); // sometimes the alias matches // 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) && (!aliasNames.Any(s => (String.Compare(s.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0)))) { continue; // Name mismatch } if (String.IsNullOrWhiteSpace(seriesID)) { continue; // can't do anything without seriesID } // First match by Episode name and then by Original broadcast date (by default prioritize match date is false) if (!MatchSeriesInformation(videoTags, seriesID, prioritizeMatchDate, dontOverwriteTitle, jobLog)) { if (MatchSeriesInformation(videoTags, seriesID, !prioritizeMatchDate, dontOverwriteTitle, jobLog)) { return(true); } // Else we continue looping through the returned series looking for a match if nothing matches } else { return(true); } } jobLog.WriteEntry("No match found on TVDB", Log.LogEntryType.Debug); return(false); // no match found }
/// <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); }
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); } }
/// <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); } }
//Creating a new video / tag relation public ActionResult <VideoTags> PostTag(VideoTags newTag) { _context.VideoTags.Add(newTag); _context.SaveChanges(); return(CreatedAtAction("GetSingleTag", new { id = newTag.TagId }, newTag)); }