public override void Fetch() { var movie = Item as IMovie; Debug.Assert(movie != null); string mfile = XmlLocation(); string location = Path.GetDirectoryName(mfile); if (File.Exists(mfile)) { DateTime modTime = new FileInfo(mfile).LastWriteTimeUtc; lastWriteTime = modTime; myMovieFile = mfile; XmlDocument doc = new XmlDocument(); doc.Load(mfile); string s = doc.SafeGetString("Title/LocalTitle"); if ((s == null) || (s == "")) s = doc.SafeGetString("Title/OriginalTitle"); movie.Name = s; movie.SortName = doc.SafeGetString("Title/SortTitle"); movie.Overview = doc.SafeGetString("Title/Description"); if (movie.Overview != null) movie.Overview = movie.Overview.Replace("\n\n", "\n"); movie.TagLine = doc.SafeGetString("Title/TagLine"); movie.Plot = doc.SafeGetString("Title/Plot"); //if added date is in xml override the file/folder date - this isn't gonna work cuz it's already filled in... DateTime added = DateTime.MinValue; DateTime.TryParse(doc.SafeGetString("Title/Added"), out added); if (added > DateTime.MinValue) movie.DateCreated = added; string front = doc.SafeGetString("Title/Covers/Front"); if ((front != null) && (front.Length > 0)) { front = Path.Combine(location, front); if (File.Exists(front)) Item.PrimaryImagePath = front; } if (string.IsNullOrEmpty(movie.DisplayMediaType)) { movie.DisplayMediaType = doc.SafeGetString("Title/Type", ""); switch (movie.DisplayMediaType.ToLower()) { case "blu-ray": movie.DisplayMediaType = MediaType.BluRay.ToString(); break; case "dvd": movie.DisplayMediaType = MediaType.DVD.ToString(); break; case "hd dvd": movie.DisplayMediaType = MediaType.HDDVD.ToString(); break; case "": movie.DisplayMediaType = null; break; } } if (movie.ProductionYear == null) { int y = doc.SafeGetInt32("Title/ProductionYear", 0); if (y > 1850) movie.ProductionYear = y; } if (movie.ImdbRating == null) { float i = doc.SafeGetSingle("Title/IMDBrating", (float)-1, (float)10); if (i >= 0) movie.ImdbRating = i; } if (movie.ImdbID == null) { if (!string.IsNullOrEmpty(doc.SafeGetString("Title/IMDB"))) { movie.ImdbID = doc.SafeGetString("Title/IMDB"); } else { movie.ImdbID = doc.SafeGetString("Title/IMDbId"); } } if (movie.TmdbID == null) { movie.TmdbID = doc.SafeGetString("Title/TMDbId"); } foreach (XmlNode node in doc.SelectNodes("Title/Persons/Person[Type='Actor']")) { try { if (movie.Actors == null) movie.Actors = new List<Actor>(); var name = node.SelectSingleNode("Name").InnerText; var role = node.SafeGetString("Role", ""); var actor = new Actor() { Name = name, Role = role }; movie.Actors.Add(actor); } catch { // fall through i dont care, one less actor } } foreach (XmlNode node in doc.SelectNodes("Title/Persons/Person[Type='Director']")) { try { if (movie.Directors == null) movie.Directors = new List<string>(); movie.Directors.Add(node.SelectSingleNode("Name").InnerText); } catch { // fall through i dont care, one less director } } foreach (XmlNode node in doc.SelectNodes("Title/Genres/Genre")) { try { if (movie.Genres == null) movie.Genres = new List<string>(); movie.Genres.Add(node.InnerText); } catch { // fall through i dont care, one less genre } } foreach (XmlNode node in doc.SelectNodes("Title/Studios/Studio")) { try { if (movie.Studios == null) movie.Studios = new List<string>(); movie.Studios.Add(node.InnerText); //movie.Studios.Add(new Studio { Name = node.InnerText }); } catch { // fall through i dont care, one less actor } } if (movie.TrailerPath == null) movie.TrailerPath = doc.SafeGetString("Title/LocalTrailer/URL"); if (movie.MpaaRating == null) movie.MpaaRating = doc.SafeGetString("Title/MPAARating"); if (movie.MpaaRating == null) { int i = doc.SafeGetInt32("Title/ParentalRating/Value", (int)7); switch (i) { case -1: movie.MpaaRating = "NR"; break; case 0: movie.MpaaRating = "UR"; break; case 1: movie.MpaaRating = "G"; break; case 3: movie.MpaaRating = "PG"; break; case 4: movie.MpaaRating = "PG-13"; break; case 5: movie.MpaaRating = "NC-17"; break; case 6: movie.MpaaRating = "R"; break; default: movie.MpaaRating = null; break; } } //if there is a custom rating - use it (if not rating will be filled with MPAARating) if (movie.CustomRating == null) movie.CustomRating = doc.SafeGetString("Title/CustomRating"); if (movie.CustomPIN == null) movie.CustomPIN = doc.SafeGetString("Title/CustomPIN"); if (movie.AspectRatio == null) movie.AspectRatio = doc.SafeGetString("Title/AspectRatio"); //MetaBrowser Custom MediaInfo Support if (movie.MediaInfo == null) movie.MediaInfo = new MediaInfoData(); //we need to decode metabrowser strings to format and profile string audio = doc.SafeGetString("Title/MediaInfo/Audio/Codec", ""); if (audio != "") { switch (audio.ToLower()) { case "dts-es": case "dts-es matrix": case "dts-es discrete": movie.MediaInfo.OverrideData.AudioFormat = "DTS"; movie.MediaInfo.OverrideData.AudioProfile = "ES"; break; case "dts-hd hra": case "dts-hd high resolution": movie.MediaInfo.OverrideData.AudioFormat = "DTS"; movie.MediaInfo.OverrideData.AudioProfile = "HRA"; break; case "dts-hd ma": case "dts-hd master": movie.MediaInfo.OverrideData.AudioFormat = "DTS"; movie.MediaInfo.OverrideData.AudioProfile = "MA"; break; case "dolby digital": case "dolby digital surround ex": case "dolby surround": movie.MediaInfo.OverrideData.AudioFormat = "AC-3"; break; case "dolby digital plus": movie.MediaInfo.OverrideData.AudioFormat = "E-AC-3"; break; case "dolby truehd": movie.MediaInfo.OverrideData.AudioFormat = "AC-3"; movie.MediaInfo.OverrideData.AudioProfile = "TrueHD"; break; case "mp2": movie.MediaInfo.OverrideData.AudioFormat = "MPEG Audio"; movie.MediaInfo.OverrideData.AudioProfile = "Layer 2"; break; case "other": break; default: movie.MediaInfo.OverrideData.AudioFormat = audio; break; } } movie.MediaInfo.OverrideData.AudioStreamCount = doc.SelectNodes("Title/MediaInfo/Audio/Codec[text() != '']").Count; movie.MediaInfo.OverrideData.AudioChannelCount = doc.SafeGetString("Title/MediaInfo/Audio/Channels", ""); movie.MediaInfo.OverrideData.AudioBitRate = doc.SafeGetInt32("Title/MediaInfo/Audio/BitRate"); string video = doc.SafeGetString("Title/MediaInfo/Video/Codec", ""); if (video != "") { switch (video.ToLower()) { case "sorenson h.263": movie.MediaInfo.OverrideData.VideoCodec = "Sorenson H263"; break; case "h.262": movie.MediaInfo.OverrideData.VideoCodec = "MPEG-2 Video"; break; case "h.264": movie.MediaInfo.OverrideData.VideoCodec = "AVC"; break; default: movie.MediaInfo.OverrideData.VideoCodec = video; break; } } movie.MediaInfo.OverrideData.VideoBitRate = doc.SafeGetInt32("Title/MediaInfo/Video/BitRate"); movie.MediaInfo.OverrideData.Height = doc.SafeGetInt32("Title/MediaInfo/Video/Height"); movie.MediaInfo.OverrideData.Width = doc.SafeGetInt32("Title/MediaInfo/Video/Width"); movie.MediaInfo.OverrideData.ScanType = doc.SafeGetString("Title/MediaInfo/Video/ScanType", ""); movie.MediaInfo.OverrideData.VideoFPS = doc.SafeGetString("Title/MediaInfo/Video/FrameRate", ""); int rt = doc.SafeGetInt32("Title/MediaInfo/Video/Duration", 0); if (rt > 0) movie.MediaInfo.OverrideData.RunTime = rt; else movie.MediaInfo.OverrideData.RunTime = doc.SafeGetInt32("Title/RunningTime", 0); if (movie.MediaInfo.RunTime > 0) movie.RunningTime = movie.MediaInfo.RunTime; XmlNodeList nodes = doc.SelectNodes("Title/MediaInfo/Audio/Language"); List<string> Langs = new List<string>(); foreach (XmlNode node in nodes) { string m = node.InnerText; if (!string.IsNullOrEmpty(m)) Langs.Add(m); } if (Langs.Count > 1) { movie.MediaInfo.OverrideData.AudioLanguages = String.Join(" / ", Langs.ToArray()); } else { movie.MediaInfo.OverrideData.AudioLanguages = doc.SafeGetString("Title/MediaInfo/Audio/Language", ""); } nodes = doc.SelectNodes("Title/MediaInfo/Subtitle/Language"); List<string> Subs = new List<string>(); foreach (XmlNode node in nodes) { string n = node.InnerText; if (!string.IsNullOrEmpty(n)) Subs.Add(n); } if (Subs.Count > 1) { movie.MediaInfo.OverrideData.Subtitles = String.Join(" / ", Subs.ToArray()); } else { movie.MediaInfo.OverrideData.Subtitles = doc.SafeGetString("Title/MediaInfo/Subtitle/Language", ""); } } }
/// <summary> /// Fetches the episode data. /// </summary> /// <param name="seriesXml">The series XML.</param> /// <param name="episode">The episode.</param> /// <param name="seriesId">The series id.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> private async Task<ProviderRefreshStatus> FetchEpisodeData(XmlDocument seriesXml, Episode episode, string seriesId, CancellationToken cancellationToken) { var status = ProviderRefreshStatus.Success; if (episode.IndexNumber == null) { return status; } var seasonNumber = episode.ParentIndexNumber ?? TVUtils.GetSeasonNumberFromEpisodeFile(episode.Path); if (seasonNumber == null) { return status; } var usingAbsoluteData = false; var episodeNode = seriesXml.SelectSingleNode("//Episode[EpisodeNumber='" + episode.IndexNumber.Value + "'][SeasonNumber='" + seasonNumber.Value + "']"); if (episodeNode == null) { if (seasonNumber.Value == 1) { episodeNode = seriesXml.SelectSingleNode("//Episode[absolute_number='" + episode.IndexNumber.Value + "']"); usingAbsoluteData = true; } } // If still null, nothing we can do if (episodeNode == null) { return status; } IEnumerable<XmlDocument> extraEpisodesNode = new XmlDocument[] { }; if (episode.IndexNumberEnd.HasValue) { var seriesXDocument = XDocument.Load(new XmlNodeReader(seriesXml)); if (usingAbsoluteData) { extraEpisodesNode = seriesXDocument.Descendants("Episode") .Where( x => int.Parse(x.Element("absolute_number").Value) > episode.IndexNumber && int.Parse(x.Element("absolute_number").Value) <= episode.IndexNumberEnd.Value).OrderBy(x => x.Element("absolute_number").Value).Select(x => x.ToXmlDocument()); } else { var all = seriesXDocument.Descendants("Episode").Where(x => int.Parse(x.Element("SeasonNumber").Value) == seasonNumber.Value); var xElements = all.Where(x => int.Parse(x.Element("EpisodeNumber").Value) > episode.IndexNumber && int.Parse(x.Element("EpisodeNumber").Value) <= episode.IndexNumberEnd.Value); extraEpisodesNode = xElements.OrderBy(x => x.Element("EpisodeNumber").Value).Select(x => x.ToXmlDocument()); } } var doc = new XmlDocument(); doc.LoadXml(episodeNode.OuterXml); if (!episode.HasImage(ImageType.Primary)) { var p = doc.SafeGetString("//filename"); if (p != null) { try { var url = TVUtils.BannerUrl + p; await _providerManager.SaveImage(episode, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Primary, null, cancellationToken) .ConfigureAwait(false); } catch (HttpException) { status = ProviderRefreshStatus.CompletedWithErrors; } } } if (!episode.LockedFields.Contains(MetadataFields.Overview)) { var extraOverview = extraEpisodesNode.Aggregate("", (current, xmlDocument) => current + ("\r\n\r\n" + xmlDocument.SafeGetString("//Overview"))); episode.Overview = doc.SafeGetString("//Overview") + extraOverview; } if (usingAbsoluteData) episode.IndexNumber = doc.SafeGetInt32("//absolute_number", -1); if (episode.IndexNumber < 0) episode.IndexNumber = doc.SafeGetInt32("//EpisodeNumber"); if (!episode.LockedFields.Contains(MetadataFields.Name)) { var extraNames = extraEpisodesNode.Aggregate("", (current, xmlDocument) => current + (", " + xmlDocument.SafeGetString("//EpisodeName"))); episode.Name = doc.SafeGetString("//EpisodeName") + extraNames; } episode.CommunityRating = doc.SafeGetSingle("//Rating", -1, 10); var firstAired = doc.SafeGetString("//FirstAired"); DateTime airDate; if (DateTime.TryParse(firstAired, out airDate) && airDate.Year > 1850) { episode.PremiereDate = airDate.ToUniversalTime(); episode.ProductionYear = airDate.Year; } if (!episode.LockedFields.Contains(MetadataFields.Cast)) { episode.People.Clear(); var actors = doc.SafeGetString("//GuestStars"); if (actors != null) { // Sometimes tvdb actors have leading spaces //Regex Info: //The first block are the posible delimitators (open-parentheses should be there cause if dont the next block will fail) //The second block Allow the delimitators to be part of the text if they're inside parentheses var persons = Regex.Matches(actors, @"(?<delimitators>([^|,(])|(?<ignoreinParentheses>\([^)]*\)*))+") .Cast<Match>() .Select(m => m.Value) .Where(i => !string.IsNullOrWhiteSpace(i) && !string.IsNullOrEmpty(i)); foreach (var person in persons.Select(str => { var nameGroup = str.Split(new[] { '(' }, 2, StringSplitOptions.RemoveEmptyEntries); var name = nameGroup[0].Trim(); var roles = nameGroup.Count() > 1 ? nameGroup[1].Trim() : null; if (roles != null) roles = roles.EndsWith(")") ? roles.Substring(0, roles.Length - 1) : roles; return new PersonInfo { Type = PersonType.GuestStar, Name = name, Role = roles }; })) { episode.AddPerson(person); } } foreach (var xmlDocument in extraEpisodesNode) { var extraActors = xmlDocument.SafeGetString("//GuestStars"); if (extraActors == null) continue; // Sometimes tvdb actors have leading spaces var persons = Regex.Matches(extraActors, @"(?<delimitators>([^|,(])|(?<ignoreinParentheses>\([^)]*\)*))+") .Cast<Match>() .Select(m => m.Value) .Where(i => !string.IsNullOrWhiteSpace(i) && !string.IsNullOrEmpty(i)); foreach (var person in persons.Select(str => { var nameGroup = str.Split(new[] { '(' }, 2, StringSplitOptions.RemoveEmptyEntries); var name = nameGroup[0].Trim(); var roles = nameGroup.Count() > 1 ? nameGroup[1].Trim() : null; if (roles != null) roles = roles.EndsWith(")") ? roles.Substring(0, roles.Length - 1) : roles; return new PersonInfo { Type = PersonType.GuestStar, Name = name, Role = roles }; })) { episode.AddPerson(person); } } var directors = doc.SafeGetString("//Director"); if (directors != null) { // Sometimes tvdb actors have leading spaces foreach (var person in directors.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries) .Where(i => !string.IsNullOrWhiteSpace(i)) .Select(str => new PersonInfo { Type = PersonType.Director, Name = str.Trim() })) { episode.AddPerson(person); } } var writers = doc.SafeGetString("//Writer"); if (writers != null) { // Sometimes tvdb actors have leading spaces foreach (var person in writers.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries) .Where(i => !string.IsNullOrWhiteSpace(i)) .Select(str => new PersonInfo { Type = PersonType.Writer, Name = str.Trim() })) { episode.AddPerson(person); } } } return status; }
public Item GetSeriesDetails(Item item) { DataProviderId dp = item.ProvidersId.Find(p => p.Name == this.Name); if (dp == null) return null; if (!LoadSeriesDetails(dp.Id)) return null; Item series = new Item(); series.ProvidersId = new List<DataProviderId> { dp }; XmlDocument doc = new XmlDocument(); doc.Load(Path.Combine(Path.Combine(XmlPath, dp.Id), lang + ".xml")); if (doc == null) return null; series.Title = series.SeriesName = doc.SafeGetString("//SeriesName"); series.Overview = doc.SafeGetString("//Overview"); series.Rating = doc.SafeGetSingle("//Rating", 0, 10); series.RunningTime = doc.SafeGetInt32("//Runtime"); series.MPAARating = doc.SafeGetString("//ContentRating"); string g = doc.SafeGetString("//Genre"); if (g != null) { string[] genres = g.Trim('|').Split('|'); if (g.Length > 0) { series.Genres = new List<string>(); series.Genres.AddRange(genres); } } XmlDocument actorsDoc = new XmlDocument(); actorsDoc.Load(Path.Combine(Path.Combine(XmlPath, dp.Id), "actors.xml")); if (actorsDoc != null) { series.Actors = new List<Actor>(); foreach (XmlNode actorNode in actorsDoc.SelectNodes("//Actor")) { string name = actorNode.SafeGetString("Name"); if (!string.IsNullOrEmpty(name)) { Actor actor = new Actor(); actor.Name = name; actor.Role = actorNode.SafeGetString("Role"); actor.ImagePath = BannerUrl + actorNode.SafeGetString("Image"); if (series.Actors == null) series.Actors = new List<Actor>(); series.Actors.Add(actor); } } } else { string actors = doc.SafeGetString("//Actors"); if (actors != null) { string[] a = actors.Trim('|').Split('|'); if (a.Length > 0) { series.Actors = new List<Actor>(); series.Actors.AddRange( a.Select(actor => new Actor { Name = actor })); } } } XmlDocument banners = new XmlDocument(); banners.Load(Path.Combine(Path.Combine(XmlPath, dp.Id), "banners.xml")); if (banners != null) { series.BackdropImagePaths = new List<Poster>(); series.ImagesPaths = new List<Poster>(); series.BannersPaths = new List<Poster>(); foreach (XmlNode node in banners.SelectNodes("//Banner")) { if (node.SafeGetString("BannerType") == "poster") { Poster poster = new Poster(); string path = node.SafeGetString("BannerPath"); string thumb = node.SafeGetString("ThumbnailPath"); if (!string.IsNullOrEmpty(thumb)) poster.Thumb = BannerUrl + thumb; poster.Image = BannerUrl + path; if (!string.IsNullOrEmpty(path)) series.ImagesPaths.Add(poster); } else if (node.SafeGetString("BannerType") == "fanart") { Poster poster = new Poster(); poster.Checked = false; string path = node.SafeGetString("BannerPath"); string thumb = node.SafeGetString("ThumbnailPath"); string size = node.SafeGetString("BannerType2"); if (size.Contains("x")) { poster.width = size.Substring(0, size.IndexOf("x")); poster.height = size.Substring(size.IndexOf("x") + 1); } if (!string.IsNullOrEmpty(thumb)) poster.Thumb = BannerUrl + thumb; poster.Image = BannerUrl + path; if (!string.IsNullOrEmpty(path)) series.BackdropImagePaths.Add(poster); } else if (node.SafeGetString("BannerType") == "series") { Poster poster = new Poster(); string path = node.SafeGetString("BannerPath"); poster.Image = BannerUrl + path; if (!string.IsNullOrEmpty(path)) series.BannersPaths.Add(poster); } } } return series; }
public override void Fetch() { var movie = Item as Movie; Debug.Assert(movie != null); string mfile = XmlLocation(); string location = Path.GetDirectoryName(mfile); if (File.Exists(mfile)) { DateTime modTime = new FileInfo(mfile).LastWriteTimeUtc; lastWriteTime = modTime; myMovieFile = mfile; XmlDocument doc = new XmlDocument(); doc.Load(mfile); string s = doc.SafeGetString("Title/LocalTitle"); if ((s == null) || (s == "")) s = doc.SafeGetString("Title/OriginalTitle"); movie.Name = s; movie.SortName = doc.SafeGetString("Title/SortTitle"); movie.Overview = doc.SafeGetString("Title/Description"); if (movie.Overview != null) movie.Overview = movie.Overview.Replace("\n\n", "\n"); string front = doc.SafeGetString("Title/Covers/Front"); if ((front != null) && (front.Length > 0)) { front = Path.Combine(location, front); if (File.Exists(front)) Item.PrimaryImagePath = front; } string back = doc.SafeGetString("Title/Covers/Back"); if ((back != null) && (back.Length > 0)) { back = Path.Combine(location, back); if (File.Exists(back)) Item.SecondaryImagePath = back; } if (movie.RunningTime == null) { int rt = doc.SafeGetInt32("Title/RunningTime",0); if (rt > 0) movie.RunningTime = rt; } if (movie.ProductionYear == null) { int y = doc.SafeGetInt32("Title/ProductionYear",0); if (y > 1900) movie.ProductionYear = y; } if (movie.ImdbRating == null) { float i = doc.SafeGetSingle("Title/IMDBrating", (float)-1, (float)10); if (i >= 0) movie.ImdbRating = i; } foreach (XmlNode node in doc.SelectNodes("Title/Persons/Person[Type='Actor']")) { try { if (movie.Actors == null) movie.Actors = new List<Actor>(); movie.Actors.Add(new Actor { Name = node.SelectSingleNode("Name").InnerText, Role = node.SelectSingleNode("Role").InnerText }); } catch { // fall through i dont care, one less actor } } foreach (XmlNode node in doc.SelectNodes("Title/Persons/Person[Type='Director']")) { try { if (movie.Directors == null) movie.Directors = new List<string>(); movie.Directors.Add(node.SelectSingleNode("Name").InnerText); } catch { // fall through i dont care, one less director } } foreach (XmlNode node in doc.SelectNodes("Title/Genres/Genre")) { try { if (movie.Genres == null) movie.Genres = new List<string>(); movie.Genres.Add(node.InnerText); } catch { // fall through i dont care, one less genre } } foreach (XmlNode node in doc.SelectNodes("Title/Studios/Studio")) { try { if (movie.Studios == null) movie.Studios = new List<string>(); movie.Studios.Add(node.InnerText); } catch { // fall through i dont care, one less actor } } if (movie.TrailerPath == null) movie.TrailerPath = doc.SafeGetString("Title/LocalTrailer/URL"); if (movie.MpaaRating == null) movie.MpaaRating = doc.SafeGetString("Title/MPAARating"); if (movie.MpaaRating == null) { int i = doc.SafeGetInt32("Title/ParentalRating/Value", (int)7); switch (i) { case -1: movie.MpaaRating = "NR"; break; case 0: movie.MpaaRating = "NR"; break; case 1: movie.MpaaRating = "G"; break; case 3: movie.MpaaRating = "PG"; break; case 4: movie.MpaaRating = "PG-13"; break; case 5: movie.MpaaRating = "NC-17"; break; case 6: movie.MpaaRating = "R"; break; default: movie.MpaaRating = null; break; } } } }
protected virtual void ProcessDocument(XmlDocument doc, bool ignoreImages) { Movie movie = Item as Movie; if (doc != null) { // This is problematic for foreign films we want to keep the alt title. //if (store.Name == null) // store.Name = doc.SafeGetString("//movie/title"); movie.Name = doc.SafeGetString("//movie/name"); movie.Overview = doc.SafeGetString("//movie/overview"); if (movie.Overview != null) movie.Overview = movie.Overview.Replace("\n\n", "\n"); movie.TagLine = doc.SafeGetString("//movie/tagline"); movie.ImdbID = doc.SafeGetString("//movie/imdb_id"); movie.ImdbRating = doc.SafeGetSingle("//movie/rating", -1, 10); string release = doc.SafeGetString("//movie/released"); if (!string.IsNullOrEmpty(release)) movie.ProductionYear = Int32.Parse(release.Substring(0, 4)); movie.RunningTime = doc.SafeGetInt32("//movie/runtime"); if (movie.MediaInfo != null && movie.MediaInfo.RunTime > 0) movie.RunningTime = movie.MediaInfo.RunTime; movie.MpaaRating = doc.SafeGetString("//movie/certification"); movie.Studios = null; foreach (XmlNode n in doc.SelectNodes("//studios/studio")) { if (movie.Studios == null) movie.Studios = new List<string>(); string name = n.SafeGetString("@name"); if (!string.IsNullOrEmpty(name)) movie.Studios.Add(name); } movie.Directors = null; foreach (XmlNode n in doc.SelectNodes("//cast/person[@job='Director']")) { if (movie.Directors == null) movie.Directors = new List<string>(); string name = n.SafeGetString("@name"); if (!string.IsNullOrEmpty(name)) movie.Directors.Add(name); } movie.Writers = null; foreach (XmlNode n in doc.SelectNodes("//cast/person[@job='Author']")) { if (movie.Writers == null) movie.Writers = new List<string>(); string name = n.SafeGetString("@name"); if (!string.IsNullOrEmpty(name)) movie.Writers.Add(name); } movie.Actors = null; foreach (XmlNode n in doc.SelectNodes("//cast/person[@job='Actor']")) { if (movie.Actors == null) movie.Actors = new List<Actor>(); string name = n.SafeGetString("@name"); string role = n.SafeGetString("@character"); if (!string.IsNullOrEmpty(name)) movie.Actors.Add(new Actor { Name = name, Role = role }); } XmlNodeList nodes = doc.SelectNodes("//movie/categories/category[@type='genre']/@name"); List<string> genres = new List<string>(); foreach (XmlNode node in nodes) { string n = MapGenre(node.InnerText); if ((!string.IsNullOrEmpty(n)) && (!genres.Contains(n))) genres.Add(n); } movie.Genres = genres; if (!ignoreImages) { string img = doc.SafeGetString("//movie/images/image[@type='poster' and @size='" + Kernel.Instance.ConfigData.FetchedPosterSize + "']/@url"); if (img == null) { img = doc.SafeGetString("//movie/images/image[@type='poster' and @size='original']/@url"); //couldn't find preferred size } if (img != null) { if (Kernel.Instance.ConfigData.SaveLocalMeta) { //download and save locally RemoteImage cover = new RemoteImage() { Path = img }; string ext = Path.GetExtension(img).ToLower(); string fn = (Path.Combine(Item.Path,"folder" + ext)); try { Kernel.IgnoreFileSystemMods = true; cover.DownloadImage().Save(fn, ext == ".png" ? System.Drawing.Imaging.ImageFormat.Png : System.Drawing.Imaging.ImageFormat.Jpeg); Kernel.IgnoreFileSystemMods = false; movie.PrimaryImagePath = fn; } catch (Exception e) { Logger.ReportException("Error downloading and saving image " + fn, e); } } else { movie.PrimaryImagePath = img; } } movie.BackdropImagePaths = new List<string>(); int bdNo = 0; RemoteImage bd; foreach (XmlNode n in doc.SelectNodes("//movie/images/image[@type='backdrop' and @size='original']/@url")) { if (Kernel.Instance.ConfigData.SaveLocalMeta) { bd = new RemoteImage() { Path = n.InnerText }; string ext = Path.GetExtension(n.InnerText).ToLower(); string fn = Path.Combine(Item.Path,"backdrop" + (bdNo > 0 ? bdNo.ToString() : "") + ext); try { Kernel.IgnoreFileSystemMods = true; bd.DownloadImage().Save(fn, ext == ".png" ? System.Drawing.Imaging.ImageFormat.Png : System.Drawing.Imaging.ImageFormat.Jpeg); Kernel.IgnoreFileSystemMods = false; movie.BackdropImagePaths.Add(fn); } catch (Exception e) { Logger.ReportException("Error downloading/saving image " + n.InnerText, e); } bdNo++; if (bdNo >= Kernel.Instance.ConfigData.MaxBackdrops) break; } else { movie.BackdropImagePaths.Add(n.InnerText); } } } } }
/// <summary> /// Fetches the main info. /// </summary> /// <param name="series">The series.</param> /// <param name="doc">The doc.</param> private void FetchMainInfo(Series series, XmlDocument doc) { if (!series.LockedFields.Contains(MetadataFields.Name)) { series.Name = doc.SafeGetString("//SeriesName"); } if (!series.LockedFields.Contains(MetadataFields.Overview)) { series.Overview = doc.SafeGetString("//Overview"); } series.CommunityRating = doc.SafeGetSingle("//Rating", 0, 10); series.AirDays = TVUtils.GetAirDays(doc.SafeGetString("//Airs_DayOfWeek")); series.AirTime = doc.SafeGetString("//Airs_Time"); SeriesStatus seriesStatus; if(Enum.TryParse(doc.SafeGetString("//Status"), true, out seriesStatus)) series.Status = seriesStatus; series.PremiereDate = doc.SafeGetDateTime("//FirstAired"); if (series.PremiereDate.HasValue) series.ProductionYear = series.PremiereDate.Value.Year; series.RunTimeTicks = TimeSpan.FromMinutes(doc.SafeGetInt32("//Runtime")).Ticks; if (!series.LockedFields.Contains(MetadataFields.Studios)) { string s = doc.SafeGetString("//Network"); if (!string.IsNullOrWhiteSpace(s)) { series.Studios.Clear(); foreach (var studio in s.Trim().Split('|')) { series.AddStudio(studio); } } } series.OfficialRating = doc.SafeGetString("//ContentRating"); if (!series.LockedFields.Contains(MetadataFields.Genres)) { string g = doc.SafeGetString("//Genre"); if (g != null) { string[] genres = g.Trim('|').Split('|'); if (g.Length > 0) { series.Genres.Clear(); foreach (var genre in genres) { series.AddGenre(genre); } } } } if (series.Status == SeriesStatus.Ended) { var document = XDocument.Load(new XmlNodeReader(doc)); var dates = document.Descendants("Episode").Where(x => { var seasonNumber = x.Element("SeasonNumber"); var firstAired = x.Element("FirstAired"); return firstAired != null && seasonNumber != null && (!string.IsNullOrEmpty(seasonNumber.Value) && seasonNumber.Value != "0") && !string.IsNullOrEmpty(firstAired.Value); }).Select(x => { DateTime? date = null; DateTime tempDate; var firstAired = x.Element("FirstAired"); if (firstAired != null && DateTime.TryParse(firstAired.Value, out tempDate)) { date = tempDate; } return date; }).ToList(); if(dates.Any(x=>x.HasValue)) series.EndDate = dates.Where(x => x.HasValue).Max(); } }
/// <summary> /// Fetches the episode data. /// </summary> /// <param name="seriesXml">The series XML.</param> /// <param name="episode">The episode.</param> /// <param name="seriesId">The series id.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> private async Task<ProviderRefreshStatus> FetchEpisodeData(XmlDocument seriesXml, Episode episode, string seriesId, CancellationToken cancellationToken) { var status = ProviderRefreshStatus.Success; if (episode.IndexNumber == null) { return status; } var seasonNumber = episode.ParentIndexNumber ?? TVUtils.GetSeasonNumberFromEpisodeFile(episode.Path); if (seasonNumber == null) { return status; } var usingAbsoluteData = false; var episodeNode = seriesXml.SelectSingleNode("//Episode[EpisodeNumber='" + episode.IndexNumber.Value + "'][SeasonNumber='" + seasonNumber.Value + "']"); if (episodeNode == null) { if (seasonNumber.Value == 1) { episodeNode = seriesXml.SelectSingleNode("//Episode[absolute_number='" + episode.IndexNumber.Value + "']"); usingAbsoluteData = true; } } // If still null, nothing we can do if (episodeNode == null) { return status; } var doc = new XmlDocument(); doc.LoadXml(episodeNode.OuterXml); if (!episode.HasImage(ImageType.Primary)) { var p = doc.SafeGetString("//filename"); if (p != null) { if (!Directory.Exists(episode.MetaLocation)) Directory.CreateDirectory(episode.MetaLocation); try { episode.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(episode, TVUtils.BannerUrl + p, Path.GetFileName(p), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken); } catch (HttpException) { status = ProviderRefreshStatus.CompletedWithErrors; } } } episode.Overview = doc.SafeGetString("//Overview"); if (usingAbsoluteData) episode.IndexNumber = doc.SafeGetInt32("//absolute_number", -1); if (episode.IndexNumber < 0) episode.IndexNumber = doc.SafeGetInt32("//EpisodeNumber"); episode.Name = doc.SafeGetString("//EpisodeName"); episode.CommunityRating = doc.SafeGetSingle("//Rating", -1, 10); var firstAired = doc.SafeGetString("//FirstAired"); DateTime airDate; if (DateTime.TryParse(firstAired, out airDate) && airDate.Year > 1850) { episode.PremiereDate = airDate.ToUniversalTime(); episode.ProductionYear = airDate.Year; } episode.People.Clear(); var actors = doc.SafeGetString("//GuestStars"); if (actors != null) { foreach (var person in actors.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Where(i => !string.IsNullOrWhiteSpace(i)) .Select(str => new PersonInfo { Type = PersonType.GuestStar, Name = str })) { episode.AddPerson(person); } } var directors = doc.SafeGetString("//Director"); if (directors != null) { foreach (var person in directors.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Where(i => !string.IsNullOrWhiteSpace(i)) .Select(str => new PersonInfo { Type = PersonType.Director, Name = str })) { episode.AddPerson(person); } } var writers = doc.SafeGetString("//Writer"); if (writers != null) { foreach (var person in writers.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Where(i => !string.IsNullOrWhiteSpace(i)) .Select(str => new PersonInfo { Type = PersonType.Writer, Name = str })) { episode.AddPerson(person); } } if (ConfigurationManager.Configuration.SaveLocalMeta) { if (!Directory.Exists(episode.MetaLocation)) Directory.CreateDirectory(episode.MetaLocation); var ms = new MemoryStream(); doc.Save(ms); await _providerManager.SaveToLibraryFilesystem(episode, Path.Combine(episode.MetaLocation, Path.GetFileNameWithoutExtension(episode.Path) + ".xml"), ms, cancellationToken).ConfigureAwait(false); } return status; }
private static void FetchXmlMovie(Item movie) { string mfile = Path.Combine(location, videofilename + ".nfo"); if (File.Exists(mfile)) { XmlDocument doc = new XmlDocument(); doc.Load(mfile); movie.Title = doc.SafeGetString("movie/title"); movie.OriginalTitle = doc.SafeGetString("movie/originaltitle"); movie.SortTitle = doc.SafeGetString("movie/sorttitle"); DateTime added; DateTime.TryParse(doc.SafeGetString("movie/added"), out added); if (added != null) movie.DateAdded = added; int? y = doc.SafeGetInt32("movie/year", 0); if (y.IsValidYear()) movie.Year = y; int? rt = doc.SafeGetInt32("movie/runtime", 0); if (rt.IsValidRunningTime()) movie.RunningTime = rt; movie.Rating = doc.SafeGetSingle("movie/rating", (float)-1, (float)10); movie.MPAARating = doc.SafeGetString("movie/mpaa"); movie.Overview = doc.SafeGetString("movie/plot"); movie.Mediatype = doc.SafeGetString("movie/type"); movie.AspectRatio = doc.SafeGetString("movie/aspectratio"); foreach (XmlNode node in doc.SelectNodes("movie/actor")) { if (movie.Actors == null) movie.Actors = new List<Actor>(); Actor actor = new Actor(); actor.Name = node.SafeGetString("name"); actor.Role = node.SafeGetString("role"); actor.ImagePath = node.SafeGetString("thumb"); if (string.IsNullOrEmpty(actor.ImagePath) && Directory.Exists(PluginOptions.Instance.ActorsThumbPath)) { string actorImage = Path.Combine(PluginOptions.Instance.ActorsThumbPath, actor.Name + ".tbn"); if (File.Exists(actorImage)) actor.ImagePath = actorImage; } movie.Actors.Add(actor); } foreach (XmlNode node in doc.SelectNodes("movie/director")) { if (movie.Crew == null) movie.Crew = new List<CrewMember>(); movie.Crew.Add(new CrewMember { Name = node.InnerText, Activity = "Director" }); } foreach (XmlNode node in doc.SelectNodes("movie/genre")) { if (movie.Genres == null) movie.Genres = new List<string>(); movie.Genres.Add(node.InnerText); } foreach (XmlNode node in doc.SelectNodes("movie/studio")) { if (movie.Studios == null) movie.Studios = new List<string>(); movie.Studios.Add(node.InnerText); } foreach (XmlNode node in doc.SelectNodes("movie/country")) { if (movie.Countries == null) movie.Countries = new List<string>(); movie.Countries.Add(node.InnerText); } foreach (XmlNode node in doc.SelectNodes("movie/tagline")) { if (movie.TagLines == null) movie.TagLines = new List<string>(); movie.TagLines.Add(node.InnerText); } foreach (XmlNode node in doc.SelectNodes("movie/trailer")) { if (movie.TrailerFiles == null) movie.TrailerFiles = new List<string>(); movie.TrailerFiles.Add(node.InnerText); } foreach (XmlNode node in doc.SelectNodes("movie/thumb")) { if (movie.ImagesPaths == null) movie.ImagesPaths = new List<Poster>(); movie.ImagesPaths.AddDistinctPoster(new Poster { Image = node.InnerText }); } foreach (XmlNode node in doc.SelectNodes("movie/fanart/thumb")) { if (movie.BackdropImagePaths == null) movie.BackdropImagePaths = new List<Poster>(); movie.BackdropImagePaths.AddDistinctPoster(new Poster { Image = node.InnerText }); } } }
private static void FetchSeries(Item series) { string mfile = Path.Combine(location, "tvshow.nfo"); if (File.Exists(mfile)) { XmlDocument doc = new XmlDocument(); doc.Load(mfile); series.SeriesName = series.Title = doc.SafeGetString("tvshow/title"); series.Rating = doc.SafeGetSingle("tvshow/rating", (float)-1, (float)10); string id = doc.SafeGetString("tvshow/id"); if (!string.IsNullOrEmpty(id)) { series.ProvidersId = new List<DataProviderId>(); series.ProvidersId.Add(new DataProviderId { Id = id, Name = "TheTVDB", Url = "http://thetvdb.com/?tab=series&id=" + id }); } series.Overview = doc.SafeGetString("tvshow/overview"); foreach (XmlNode node in doc.SelectNodes("tvshow/actor")) { if (series.Actors == null) series.Actors = new List<Actor>(); Actor actor = new Actor(); actor.Name = node.SafeGetString("name"); actor.Role = node.SafeGetString("role"); actor.ImagePath = node.SafeGetString("thumb"); if (string.IsNullOrEmpty(actor.ImagePath) && Directory.Exists(PluginOptions.Instance.ActorsThumbPath)) { string actorImage = Path.Combine(PluginOptions.Instance.ActorsThumbPath, actor.Name + ".tbn"); if (File.Exists(actorImage)) actor.ImagePath = actorImage; } series.Actors.Add(actor); } foreach (XmlNode node in doc.SelectNodes("tvshow/genre")) { if (series.Genres == null) series.Genres = new List<string>(); series.Genres.Add(node.InnerText); } series.MPAARating = doc.SafeGetString("mpaa"); int? rt = doc.SafeGetInt32("tvshow/runtime", 0); if (rt.IsValidRunningTime()) series.RunningTime = rt; series.Rating = doc.SafeGetSingle("tvshow/rating", (float)-1, (float)10); foreach (XmlNode node in doc.SelectNodes("tvshow/studio")) { if (series.Studios == null) series.Studios = new List<string>(); series.Studios.Add(node.InnerText); } foreach (XmlNode node in doc.SelectNodes("tvshow/tagline")) { if (series.TagLines == null) series.TagLines = new List<string>(); series.TagLines.Add(node.InnerText); } foreach (XmlNode node in doc.SelectNodes("tvshow/thumb")) { if (series.BannersPaths == null) series.BannersPaths = new List<Poster>(); series.BannersPaths.AddDistinctPoster(new Poster { Image = node.InnerText }); } } }
public override void Fetch() { Episode episode = Episode; Debug.Assert(episode != null); // store the location so we do not fetch again metadataFile = XmlLocation; // no data, do nothing if (metadataFile == null) return; metadataFileDate = new FileInfo(metadataFile).LastWriteTimeUtc; string metadataFolder = Path.GetDirectoryName(metadataFile); XmlDocument metadataDoc = new XmlDocument(); metadataDoc.Load(metadataFile); var p = metadataDoc.SafeGetString("//filename"); if (p != null && p.Length > 0) { string image = System.IO.Path.Combine(metadataFolder, System.IO.Path.GetFileName(p)); if (File.Exists(image)) Item.PrimaryImagePath = image; } else { string primaryExt = ".jpg"; string secondaryExt = ".png"; if (Config.Instance.PNGTakesPrecedence) { primaryExt = ".png"; secondaryExt = ".jpg"; } string file = Path.GetFileNameWithoutExtension(Item.Path); string image = System.IO.Path.Combine(metadataFolder, file + primaryExt); if (File.Exists(image)) { Item.PrimaryImagePath = image; } else { image = System.IO.Path.Combine(metadataFolder, file + secondaryExt); if (File.Exists(image)) Item.PrimaryImagePath = image; } } //if added date is in xml override the file/folder date DateTime added = DateTime.MinValue; DateTime.TryParse(metadataDoc.SafeGetString("//Added"), out added); if (added > DateTime.MinValue) episode.DateCreated = added; episode.Overview = metadataDoc.SafeGetString("//Overview"); episode.EpisodeNumber = metadataDoc.SafeGetString("//EpisodeNumber"); episode.Name = episode.EpisodeNumber + " - " + metadataDoc.SafeGetString("//EpisodeName"); episode.SeasonNumber = metadataDoc.SafeGetString("//SeasonNumber"); episode.ImdbRating = metadataDoc.SafeGetSingle("//Rating", (float)-1, 10); episode.FirstAired = metadataDoc.SafeGetString("//FirstAired"); DateTime airDate; int y = DateTime.TryParse(episode.FirstAired, out airDate) ? airDate.Year : -1; if (y > 1850) { episode.ProductionYear = y; } string writers = metadataDoc.SafeGetString("//Writer"); if (writers != null) episode.Writers = new List<string>(writers.Trim('|').Split('|')); string directors = metadataDoc.SafeGetString("//Director"); if (directors != null) episode.Directors = new List<string>(directors.Trim('|').Split('|')); var actors = ActorListFromString(metadataDoc.SafeGetString("//GuestStars")); if (actors != null) { if (episode.Actors == null) episode.Actors = new List<Actor>(); episode.Actors = actors; } if (string.IsNullOrEmpty(episode.DisplayMediaType)) { episode.DisplayMediaType = metadataDoc.SafeGetString("//Type", ""); switch (episode.DisplayMediaType.ToLower()) { case "blu-ray": episode.DisplayMediaType = MediaType.BluRay.ToString(); break; case "dvd": episode.DisplayMediaType = MediaType.DVD.ToString(); break; case "hd dvd": episode.DisplayMediaType = MediaType.HDDVD.ToString(); break; case "": episode.DisplayMediaType = null; break; } } if (episode.AspectRatio == null) episode.AspectRatio = metadataDoc.SafeGetString("//AspectRatio"); if (episode.MediaInfo == null) episode.MediaInfo = new MediaInfoData(); //we need to decode metabrowser strings to format and profile string audio = metadataDoc.SafeGetString("//MediaInfo/Audio/Codec", ""); if (audio != "") { switch (audio.ToLower()) { case "dts-es": case "dts-es matrix": case "dts-es discrete": episode.MediaInfo.OverrideData.AudioFormat = "DTS"; episode.MediaInfo.OverrideData.AudioProfile = "ES"; break; case "dts-hd hra": case "dts-hd high resolution": episode.MediaInfo.OverrideData.AudioFormat = "DTS"; episode.MediaInfo.OverrideData.AudioProfile = "HRA"; break; case "dts-hd ma": case "dts-hd master": episode.MediaInfo.OverrideData.AudioFormat = "DTS"; episode.MediaInfo.OverrideData.AudioProfile = "MA"; break; case "dolby digital": case "dolby digital surround ex": case "dolby surround": episode.MediaInfo.OverrideData.AudioFormat = "AC-3"; break; case "dolby digital plus": episode.MediaInfo.OverrideData.AudioFormat = "E-AC-3"; break; case "dolby truehd": episode.MediaInfo.OverrideData.AudioFormat = "AC-3"; episode.MediaInfo.OverrideData.AudioProfile = "TrueHD"; break; case "mp2": episode.MediaInfo.OverrideData.AudioFormat = "MPEG Audio"; episode.MediaInfo.OverrideData.AudioProfile = "Layer 2"; break; case "other": break; default: episode.MediaInfo.OverrideData.AudioFormat = audio; break; } } episode.MediaInfo.OverrideData.AudioStreamCount = metadataDoc.SelectNodes("//MediaInfo/Audio/Codec[text() != '']").Count; episode.MediaInfo.OverrideData.AudioChannelCount = metadataDoc.SafeGetString("//MediaInfo/Audio/Channels", ""); episode.MediaInfo.OverrideData.AudioBitRate = metadataDoc.SafeGetInt32("//MediaInfo/Audio/BitRate"); string video = metadataDoc.SafeGetString("Item/MediaInfo/Video/Codec", ""); if (video != "") { switch (video.ToLower()) { case "sorenson h.263": episode.MediaInfo.OverrideData.VideoCodec = "Sorenson H263"; break; case "h.262": episode.MediaInfo.OverrideData.VideoCodec = "MPEG-2 Video"; break; case "h.264": episode.MediaInfo.OverrideData.VideoCodec = "AVC"; break; default: episode.MediaInfo.OverrideData.VideoCodec = video; break; } } episode.MediaInfo.OverrideData.VideoBitRate = metadataDoc.SafeGetInt32("Item/MediaInfo/Video/BitRate"); episode.MediaInfo.OverrideData.Height = metadataDoc.SafeGetInt32("Item/MediaInfo/Video/Height"); episode.MediaInfo.OverrideData.Width = metadataDoc.SafeGetInt32("Item/MediaInfo/Video/Width"); episode.MediaInfo.OverrideData.ScanType = metadataDoc.SafeGetString("Item/MediaInfo/Video/ScanType", ""); episode.MediaInfo.OverrideData.VideoFPS = metadataDoc.SafeGetString("Item/MediaInfo/Video/FrameRate", ""); episode.MediaInfo.OverrideData.RunTime = metadataDoc.SafeGetInt32("Item/MediaInfo/Video/Duration"); if (episode.MediaInfo.RunTime > 0) episode.RunningTime = episode.MediaInfo.RunTime; XmlNodeList nodes = metadataDoc.SelectNodes("Item/MediaInfo/Audio/Language"); List<string> Langs = new List<string>(); foreach (XmlNode node in nodes) { string m = node.InnerText; if (!string.IsNullOrEmpty(m)) Langs.Add(m); } if (Langs.Count > 1) { episode.MediaInfo.OverrideData.AudioLanguages = String.Join(" / ", Langs.ToArray()); } else { episode.MediaInfo.OverrideData.AudioLanguages = metadataDoc.SafeGetString("Item/MediaInfo/Audio/Language", ""); } nodes = metadataDoc.SelectNodes("Item/MediaInfo/Subtitle/Language"); List<string> Subs = new List<string>(); foreach (XmlNode node in nodes) { string n = node.InnerText; if (!string.IsNullOrEmpty(n)) Subs.Add(n); } if (Subs.Count > 1) { episode.MediaInfo.OverrideData.Subtitles = String.Join(" / ", Subs.ToArray()); } else { episode.MediaInfo.OverrideData.Subtitles = metadataDoc.SafeGetString("Item/MediaInfo/Subtitle/Language", ""); } }