// Icons private static List <XmltvIcon> BuildProgramIcons(MxfProgram mxfProgram) { if (config.XmltvSingleImage) { var url = mxfProgram.mxfGuideImage?.ImageUrl ?? mxfProgram.mxfSeason?.mxfGuideImage?.ImageUrl ?? mxfProgram.mxfSeriesInfo?.mxfGuideImage?.ImageUrl; return(url == null ? null : new List <XmltvIcon> { new XmltvIcon { Src = url } }); } var artwork = new List <ProgramArtwork>(); // a movie or sport event will have a guide image from the program if (mxfProgram.extras.ContainsKey("artwork")) { artwork = mxfProgram.extras["artwork"]; } // get the season class from the program if it is has a season if (artwork.Count == 0 && (mxfProgram.mxfSeason?.extras.ContainsKey("artwork") ?? false)) { artwork = mxfProgram.mxfSeason.extras["artwork"]; } // get the series info class from the program if it is a series if (artwork.Count == 0 && (mxfProgram.mxfSeriesInfo?.extras.ContainsKey("artwork") ?? false)) { artwork = mxfProgram.mxfSeriesInfo.extras["artwork"]; } return(artwork.Count == 0 ? null : artwork.Select(image => new XmltvIcon { Src = Helper.Standalone ? image.Uri : $"{image.Uri.Replace($"{SdApi.JsonBaseUrl}{SdApi.JsonApi}", $"http://{Environment.MachineName}:{Helper.TcpPort}/")}", Height = image.Height, Width = image.Width }).ToList()); }
private static void determineTitlesAndDescriptions(ref MxfProgram prg, sdProgram sd) { // populate titles if (sd.Titles != null) { prg.Title = sd.Titles[0].Title120; } else { Logger.WriteWarning(string.Format("Program {0} is missing required content.", sd.ProgramID)); } prg.EpisodeTitle = sd.EpisodeTitle150; // populate descriptions and language if (sd.Descriptions != null) { string lang = string.Empty; prg.ShortDescription = getDescriptions(sd.Descriptions.Description100, out lang); prg.Description = getDescriptions(sd.Descriptions.Description1000, out lang); // if short description is empty, not a movie, and append episode option is enabled // copy long description into short description if (string.IsNullOrEmpty(prg.ShortDescription) && !sd.EntityType.ToLower().Equals("movie") && config.AppendEpisodeDesc) { prg.ShortDescription = prg.Description; } // populate language if (!string.IsNullOrEmpty(lang)) { prg.Language = lang.ToLower(); } } prg.OriginalAirdate = sd.OriginalAirDate; }
private static bool BuildScheduleEntries() { foreach (XmltvProgramme program in xmltv.Programs) { // determine which service the schedule entry is for MxfService mxfService = Common.mxf.With[0].getService(GetStationIdFromChannelId(program.Channel)); // determine start time DateTime dtStart = DateTime.ParseExact(program.Start, "yyyyMMddHHmmss zzz", CultureInfo.InvariantCulture).ToUniversalTime(); DateTime dtStop = DateTime.ParseExact(program.Stop, "yyyyMMddHHmmss zzz", CultureInfo.InvariantCulture).ToUniversalTime(); string startTime = dtStart.ToString("yyyy-MM-ddTHH:mm:ss"); if (dtStart == mxfService.mxfScheduleEntries.endTime) { startTime = null; } // prepopulate some of the program MxfProgram mxfProgram = new MxfProgram() { index = Common.mxf.With[0].Programs.Count + 1, episodeInfo = GetProgramEpisodeInformation(program.EpisodeNums), IsPremiere = (program.Premiere != null) ? "true" : null, IsSeasonPremiere = (program.Premiere?.Text != null && program.Premiere.Text.ToLower().Equals("season premiere")) ? "true" : null, IsSeriesPremiere = (program.Premiere?.Text != null && program.Premiere.Text.ToLower().Equals("series premiere")) ? "true" : null, _newDate = (program.New != null) ? dtStart.ToLocalTime().ToString("yyyy-MM-dd") : null, ActorRole = new List <MxfPersonRank>(), WriterRole = new List <MxfPersonRank>(), GuestActorRole = new List <MxfPersonRank>(), HostRole = new List <MxfPersonRank>(), ProducerRole = new List <MxfPersonRank>(), DirectorRole = new List <MxfPersonRank>() //IsSeasonFinale = , //IsSeriesFinale = , }; // if dd_progid is not valid, don't add it if (string.IsNullOrEmpty(mxfProgram.episodeInfo.TMSID)) { continue; } // populate the schedule entry and create program entry as required mxfService.mxfScheduleEntries.ScheduleEntry.Add(new MxfScheduleEntry() { AudioFormat = GetAudioFormat(program.Audio), Duration = (int)((dtStop - dtStart).TotalSeconds), IsCC = program.Subtitles.Count > 0 ? "true" : null, IsHdtv = (program.Video?.Quality != null && program.Video.Quality.ToLower().Equals("hdtv")) ? "true" : mxfService.isHD ? "true" : null, IsLive = (program.Live != null) ? "true" : null, IsPremiere = (program.Premiere != null) ? "true" : null, IsRepeat = (program.New == null && !mxfProgram.episodeInfo.Type.Equals("MV")) ? "true" : null, Part = (mxfProgram.episodeInfo.NumberOfParts > 1) ? mxfProgram.episodeInfo.PartNumber.ToString() : null, Parts = (mxfProgram.episodeInfo.NumberOfParts > 1) ? mxfProgram.episodeInfo.NumberOfParts.ToString() : null, Program = Common.mxf.With[0].getProgram(mxfProgram.episodeInfo.TMSID, mxfProgram).Id, StartTime = startTime, TvRating = GetUsTvRating(program.Rating) //Is3D = , //IsBlackout = , //IsClassroom = , //IsDelay = , //IsDvs = , //IsEnhanced = , //IsFinale = , //IsHdtvSimulCast = , //IsInProgress = , //IsLetterbox = , //IsLiveSports = , //IsSap = , //IsSubtitled = , //IsTape = , //IsSigned = }); BuildProgram(mxfProgram.episodeInfo.TMSID, program); } return(true); }
private static void completeEpisodeTitle(ref MxfProgram prg) { // by request, if there is no episode title, and the program is not generic, duplicate the program title in the episode title if (prg.tmsId.StartsWith("EP") && string.IsNullOrEmpty(prg.EpisodeTitle)) { prg.EpisodeTitle = prg.Title; } else if (string.IsNullOrEmpty(prg.EpisodeTitle)) { return; } // prefix episode title with season and episode numbers as configured if (config.PrefixEpisodeTitle) { if (!string.IsNullOrEmpty(prg.SeasonNumber) && !string.IsNullOrEmpty(prg.EpisodeNumber)) { prg.EpisodeTitle = string.Format("s{0}e{1} {2}", int.Parse(prg.SeasonNumber).ToString("D2"), int.Parse(prg.EpisodeNumber).ToString("D2"), prg.EpisodeTitle); } else if (!string.IsNullOrEmpty(prg.EpisodeNumber)) { prg.EpisodeTitle = string.Format("#{0} {1}", prg.EpisodeNumber, prg.EpisodeTitle); } } // prefix episode description with season and episode numbers as configured if ((config.PrefixEpisodeDescription) && !string.IsNullOrEmpty(prg.EpisodeNumber)) { string se = string.Empty; if (!string.IsNullOrEmpty(prg.SeasonNumber)) { se = string.Format("s{0}e{1} ", int.Parse(prg.SeasonNumber).ToString("D2"), int.Parse(prg.EpisodeNumber).ToString("D2")); } else { se = string.Format("#{0} ", int.Parse(prg.EpisodeNumber).ToString("D2")); } prg.Description = se + prg.Description; if (!string.IsNullOrEmpty(prg.ShortDescription)) { prg.ShortDescription = se + prg.ShortDescription; } } // append season and episode numbers to the program description as configured if (config.AppendEpisodeDesc) { if (!string.IsNullOrEmpty(prg.SeasonNumber) && !string.IsNullOrEmpty(prg.EpisodeNumber)) { prg.Description += string.Format(" \n\nSeason {0}, Episode {1}", int.Parse(prg.SeasonNumber).ToString("D2"), int.Parse(prg.EpisodeNumber).ToString("D2")); } else if (!string.IsNullOrEmpty(prg.EpisodeNumber)) { prg.Description += string.Format(" \n\nEpisode #{0}", prg.EpisodeNumber); } } // append part/parts to episode title as needed if (prg._part > 0) { prg.EpisodeTitle += string.Format(" ({0}/{1})", prg._part, prg._parts); } }
private static void determineProgramKeywords(ref MxfProgram prg, sdProgram sd) { // determine primary group of program GROUPS group = GROUPS.UNKNOWN; if (!string.IsNullOrEmpty(prg.IsMovie)) { group = GROUPS.MOVIES; } else if (!string.IsNullOrEmpty(prg.IsPaidProgramming)) { group = GROUPS.PAIDPROGRAMMING; } else if (!string.IsNullOrEmpty(prg.IsSports)) { group = GROUPS.SPORTS; } else if (!string.IsNullOrEmpty(prg.IsKids)) { group = GROUPS.KIDS; } else if (!string.IsNullOrEmpty(prg.IsEducational)) { group = GROUPS.EDUCATIONAL; } else if (!string.IsNullOrEmpty(prg.IsNews)) { group = GROUPS.NEWS; } else if (!string.IsNullOrEmpty(prg.IsSpecial)) { group = GROUPS.SPECIAL; } else if (!string.IsNullOrEmpty(prg.IsReality)) { group = GROUPS.REALITY; } else if (!string.IsNullOrEmpty(prg.IsSeries)) { group = GROUPS.SERIES; } // build the keywords/categories if (group != GROUPS.UNKNOWN) { prg.Keywords = string.Format("k{0}", (int)group + 1); // add premiere categories as necessary if (!string.IsNullOrEmpty(prg.IsSeasonPremiere) || !string.IsNullOrEmpty(prg.IsSeriesPremiere)) { prg.Keywords += string.Format(",k{0}", (int)GROUPS.PREMIERES + 1); if (!string.IsNullOrEmpty(prg.IsSeasonPremiere)) { prg.Keywords += "," + sdMxf.With[0].KeywordGroups[(int)GROUPS.PREMIERES].getKeywordId("Season Premiere"); } if (!string.IsNullOrEmpty(prg.IsSeriesPremiere)) { prg.Keywords += "," + sdMxf.With[0].KeywordGroups[(int)GROUPS.PREMIERES].getKeywordId("Series Premiere"); } } else if (!string.IsNullOrEmpty(prg.IsPremiere)) { if (group == GROUPS.MOVIES) { prg.Keywords += "," + sdMxf.With[0].KeywordGroups[(int)group].getKeywordId("Premiere"); } else if (Helper.tableContains(sd.Genres, "miniseries") == "true") { prg.Keywords += string.Format(",k{0}", (int)GROUPS.PREMIERES + 1); prg.Keywords += "," + sdMxf.With[0].KeywordGroups[(int)GROUPS.PREMIERES].getKeywordId("Miniseries Premiere"); } } // now add the real categories if (sd.Genres != null) { foreach (string genre in sd.Genres) { string key = sdMxf.With[0].KeywordGroups[(int)group].getKeywordId(genre); List <string> keys = prg.Keywords.Split(',').ToList(); if (!keys.Contains(key)) { prg.Keywords += "," + key; } } } if (prg.Keywords.Length < 5) { string key = sdMxf.With[0].KeywordGroups[(int)group].getKeywordId("Uncategorized"); prg.Keywords += "," + key; } } }
private static void setProgramFlags(ref MxfProgram prg, sdProgram sd) { // transfer genres to mxf program prg.IsAction = Helper.tableContains(sd.Genres, "Action"); prg.IsComedy = Helper.tableContains(sd.Genres, "Comedy"); prg.IsDocumentary = Helper.tableContains(sd.Genres, "Documentary"); prg.IsDrama = Helper.tableContains(sd.Genres, "Drama"); prg.IsEducational = Helper.tableContains(sd.Genres, "Educational"); prg.IsHorror = Helper.tableContains(sd.Genres, "Horror"); //prg.IsIndy = null; prg.IsKids = Helper.tableContains(sd.Genres, "Children"); prg.IsMusic = Helper.tableContains(sd.Genres, "Music"); prg.IsNews = Helper.tableContains(sd.Genres, "News"); prg.IsReality = Helper.tableContains(sd.Genres, "Reality"); prg.IsRomance = Helper.tableContains(sd.Genres, "Romance"); prg.IsScienceFiction = Helper.tableContains(sd.Genres, "Science Fiction"); prg.IsSoap = Helper.tableContains(sd.Genres, "Soap"); prg.IsThriller = Helper.tableContains(sd.Genres, "Suspense"); // below flags are populated when creating the program in processMd5ScheduleEntry(string md5) // prg.IsPremiere // prg.IsSeasonFinale // prg.IsSeasonPremiere // prg.IsSeriesFinale // prg.IsSeriesPremiere // transfer show types to mxf program //prg.IsLimitedSeries = null; prg.IsMiniseries = Helper.stringContains(sd.ShowType, "Miniseries"); prg.IsMovie = Helper.stringContains(sd.EntityType, "Movie"); prg.IsPaidProgramming = Helper.stringContains(sd.ShowType, "Paid Programming"); //prg.IsProgramEpisodic = null; //prg.IsSerial = null; prg.IsSeries = Helper.stringContains(sd.ShowType, "Series") ?? Helper.stringContains(sd.ShowType, "Sports non-event"); prg.IsShortFilm = Helper.stringContains(sd.ShowType, "Short Film"); prg.IsSpecial = Helper.stringContains(sd.ShowType, "Special"); prg.IsSports = Helper.stringContains(sd.ShowType, "Sports event"); // set isGeneric flag if programID starts with "SH", is a series, is not a miniseries, and is not paid programming if (prg.tmsId.StartsWith("SH") && ((!string.IsNullOrEmpty(prg.IsSports) && string.IsNullOrEmpty(Helper.stringContains(sd.EntityType, "Sports"))) || (!string.IsNullOrEmpty(prg.IsSeries) && string.IsNullOrEmpty(prg.IsMiniseries) && string.IsNullOrEmpty(prg.IsPaidProgramming)))) { prg.IsGeneric = "true"; } // special case to flag sports events ** I CURRENTLY SEE NO ADVANTAGE TO DOING THIS ** //if (!string.IsNullOrEmpty(Helper.stringContains(sd.ShowType, "Sports Event"))) //{ // // find all schedule entries that link to this program // foreach (MxfScheduleEntries mxfScheduleEntries in sdMxf.With[0].ScheduleEntries) // { // foreach (MxfScheduleEntry mxfScheduleEntry in mxfScheduleEntries.ScheduleEntry) // { // if (mxfScheduleEntry.Program.Equals(prg.Id) && !string.IsNullOrEmpty(mxfScheduleEntry.IsLive)) // { // mxfScheduleEntry.IsLiveSports = "true"; // } // } // } //} }
private static void BuildProgram(string id, HDHRProgram program) { MxfProgram mxfProgram = Common.mxf.With[0].getProgram(id); if (!string.IsNullOrEmpty(mxfProgram.Title)) { return; } mxfProgram.Title = program.Title; mxfProgram.EpisodeTitle = program.EpisodeTitle; mxfProgram.Description = program.Synopsis; mxfProgram.IsAction = Common.ListContains(program.Filters, "Action"); mxfProgram.IsComedy = Common.ListContains(program.Filters, "Comedy"); mxfProgram.IsDocumentary = Common.ListContains(program.Filters, "Documentary"); mxfProgram.IsDrama = Common.ListContains(program.Filters, "Drama"); mxfProgram.IsEducational = Common.ListContains(program.Filters, "Educational"); mxfProgram.IsHorror = Common.ListContains(program.Filters, "Horror"); //mxfProgram.IsIndy = null; mxfProgram.IsKids = Common.ListContains(program.Filters, "Children") ?? Common.ListContains(program.Filters, "Kids") ?? Common.ListContains(program.Filters, "Family"); mxfProgram.IsMusic = Common.ListContains(program.Filters, "Music"); mxfProgram.IsNews = Common.ListContains(program.Filters, "News"); mxfProgram.IsReality = Common.ListContains(program.Filters, "Reality"); mxfProgram.IsRomance = Common.ListContains(program.Filters, "Romance"); mxfProgram.IsScienceFiction = Common.ListContains(program.Filters, "Science Fiction"); mxfProgram.IsSoap = Common.ListContains(program.Filters, "Soap"); mxfProgram.IsThriller = Common.ListContains(program.Filters, "Suspense") ?? Common.ListContains(program.Filters, "Thriller"); //mxfProgram.IsPremiere = ; //mxfProgram.IsSeasonFinale = ; //mxfProgram.IsSeasonPremiere = ; //mxfProgram.IsSeriesFinale = ; //mxfProgram.IsSeriesPremiere = ; //mxfProgram.IsLimitedSeries = null; mxfProgram.IsMiniseries = Common.ListContains(program.Filters, "Miniseries"); mxfProgram.IsMovie = program.SeriesID.StartsWith("MV") ? "true" : Common.ListContains(program.Filters, "Movie"); mxfProgram.IsPaidProgramming = Common.ListContains(program.Filters, "Paid Programming") ?? Common.ListContains(program.Filters, "Shopping") ?? Common.ListContains(program.Filters, "Consumer"); //mxfProgram.IsProgramEpisodic = null; //mxfProgram.IsSerial = null; mxfProgram.IsSeries = Common.ListContains(program.Filters, "Series") ?? Common.ListContains(program.Filters, "Sports non-event"); mxfProgram.IsShortFilm = Common.ListContains(program.Filters, "Short Film"); mxfProgram.IsSpecial = Common.ListContains(program.Filters, "Special"); mxfProgram.IsSports = Common.ListContains(program.Filters, "Sports event") ?? Common.ListContains(program.Filters, "Sports", true); if (string.IsNullOrEmpty(mxfProgram.IsSeries + mxfProgram.IsMiniseries + mxfProgram.IsMovie + mxfProgram.IsPaidProgramming + mxfProgram.IsShortFilm + mxfProgram.IsSpecial + mxfProgram.IsSports)) { mxfProgram.IsSeries = "true"; } // determine keywords Common.determineProgramKeywords(ref mxfProgram, program.Filters); if (!program.SeriesID.StartsWith("MV")) { // write the language mxfProgram.Language = program.SeriesID.Substring(program.SeriesID.Length - 6, 2).ToLower(); // add the series MxfSeriesInfo mxfSeriesInfo = Common.mxf.With[0].getSeriesInfo(program.SeriesID); mxfSeriesInfo.Title = program.Title; mxfProgram.Series = mxfSeriesInfo.Id; // add the image if (!string.IsNullOrEmpty(program.ImageURL)) { mxfSeriesInfo.GuideImage = Common.mxf.With[0].getGuideImage(program.ImageURL).Id; } // handle any season and episode numbers along with season entries if (!string.IsNullOrEmpty(program.EpisodeNumber)) { string[] se = program.EpisodeNumber.Substring(1).Split('E'); mxfProgram.SeasonNumber = int.Parse(se[0]).ToString(); mxfProgram.EpisodeNumber = int.Parse(se[1]).ToString(); mxfProgram.Season = Common.mxf.With[0].getSeasonId(program.SeriesID, mxfProgram.SeasonNumber); } else if (string.IsNullOrEmpty(mxfProgram.EpisodeTitle)) { mxfProgram.IsGeneric = "true"; } if (string.IsNullOrEmpty(mxfProgram.IsGeneric)) { mxfProgram.OriginalAirdate = program.OriginalAirDateTime.ToString("yyyy-MM-dd"); } } else { if (!string.IsNullOrEmpty(program.PosterURL)) { mxfProgram.GuideImage = Common.mxf.With[0].getGuideImage(program.PosterURL).Id; } if (!string.IsNullOrEmpty(program.Synopsis)) { Match m = Regex.Match(program.Synopsis, @"\d\.\d/\d\.\d"); if (m != null) { string[] nums = m.Value.Split('/'); if (double.TryParse(nums[0], out double numerator) && double.TryParse(nums[1], out double denominator)) { int halfstars = (int)((numerator / denominator) * 8); mxfProgram.HalfStars = halfstars.ToString(); mxfProgram.Description = mxfProgram.Description.Replace(string.Format(" ({0})", m.Value), ""); } } } } }
private static bool IsSameSeries(Program wmc, MxfProgram mxf) // or close enough to same series { return(wmc.GetUIdValue().Substring(11, 8).Equals(mxf.Uid.Substring(11, 8)) || wmc.Title.Equals(mxf.Title)); }
private static void DetermineSeriesInfo(MxfProgram mxfProgram, SchedulesDirect.Program sdProgram) { // for sports programs that start with "SP", create a series entry based on program title // this groups them all together as a series for recordings MxfSeriesInfo mxfSeriesInfo; if (mxfProgram.ProgramId.StartsWith("SP")) { var name = mxfProgram.Title.Replace(' ', '_'); mxfSeriesInfo = SdMxf.GetSeriesInfo(name); sportsSeries.Add(name, mxfProgram.ProgramId); } else { // create a seriesInfo entry if needed mxfSeriesInfo = SdMxf.GetSeriesInfo(mxfProgram.ProgramId.Substring(2, 8), mxfProgram.ProgramId); if (!mxfSeriesInfo.extras.ContainsKey("tvdb") && sdProgram.Metadata != null) { foreach (var providers in sdProgram.Metadata) { if (providers.TryGetValue("TheTVDB", out var provider)) { mxfSeriesInfo.extras.Add("tvdb", provider.SeriesId.ToString()); } } } if (mxfProgram.ProgramId.StartsWith("SH")) { // go ahead and create/update the cache entry as needed if (epgCache.JsonFiles.ContainsKey(mxfProgram.ProgramId)) { try { using (var reader = new StringReader(epgCache.GetAsset(mxfProgram.ProgramId))) { var serializer = new JsonSerializer(); var cached = (GenericDescription)serializer.Deserialize(reader, typeof(GenericDescription)); if (cached.StartAirdate == null) { cached.StartAirdate = mxfProgram.OriginalAirdate ?? string.Empty; using (var writer = new StringWriter()) { serializer.Serialize(writer, cached); epgCache.UpdateAssetJsonEntry(mxfProgram.ProgramId, writer.ToString()); } } } } catch { // ignored } } else { var newEntry = new GenericDescription { Code = 0, Description1000 = mxfProgram.IsGeneric ? mxfProgram.Description : null, Description100 = mxfProgram.IsGeneric ? mxfProgram.ShortDescription : null, StartAirdate = mxfProgram.OriginalAirdate ?? string.Empty }; using (var writer = new StringWriter()) { var serializer = new JsonSerializer(); serializer.Serialize(writer, newEntry); epgCache.AddAsset(mxfProgram.ProgramId, writer.ToString()); } } } } mxfSeriesInfo.Title = mxfSeriesInfo.Title ?? mxfProgram.Title; mxfProgram.mxfSeriesInfo = mxfSeriesInfo; }
private static void DetermineProgramKeywords(MxfProgram mxfProgram, SchedulesDirect.Program sdProgram) { // determine primary group of program var group = keygroups.UNKNOWN; if (mxfProgram.IsMovie) { group = keygroups.MOVIES; } else if (mxfProgram.IsPaidProgramming) { group = keygroups.PAIDPROGRAMMING; } else if (mxfProgram.IsSports) { group = keygroups.SPORTS; } else if (mxfProgram.IsKids) { group = keygroups.KIDS; } else if (mxfProgram.IsEducational) { group = keygroups.EDUCATIONAL; } else if (mxfProgram.IsNews) { group = keygroups.NEWS; } else if (mxfProgram.IsSpecial) { group = keygroups.SPECIAL; } else if (mxfProgram.IsReality) { group = keygroups.REALITY; } else if (mxfProgram.IsSeries) { group = keygroups.SERIES; } // build the keywords/categories if (group == keygroups.UNKNOWN) { return; } var mxfKeyGroup = SdMxf.GetKeywordGroup(Groups[(int)group]); mxfProgram.mxfKeywords.Add(new MxfKeyword { Index = mxfKeyGroup.Index, Word = Groups[(int)group] }); // add premiere categories as necessary if (mxfProgram.IsSeasonPremiere || mxfProgram.IsSeriesPremiere) { var premiere = SdMxf.GetKeywordGroup(Groups[(int)keygroups.PREMIERES]); mxfProgram.mxfKeywords.Add(new MxfKeyword { Index = premiere.Index, Word = "Premieres" }); if (mxfProgram.IsSeasonPremiere) { mxfProgram.mxfKeywords.Add(premiere.GetKeyword("Season Premiere")); } if (mxfProgram.IsSeriesPremiere) { mxfProgram.mxfKeywords.Add(premiere.GetKeyword("Series Premiere")); } } else if (mxfProgram.extras["premiere"]) { if (group == keygroups.MOVIES) { mxfProgram.mxfKeywords.Add(mxfKeyGroup.GetKeyword("Premiere")); } else if (Helper.TableContains(sdProgram.Genres, "miniseries")) { var premiere = SdMxf.GetKeywordGroup(Groups[(int)keygroups.PREMIERES]); mxfProgram.mxfKeywords.Add(new MxfKeyword { Index = premiere.Index, Word = "Premieres" }); mxfProgram.mxfKeywords.Add(premiere.GetKeyword("Miniseries Premiere")); } } // now add the real categories if (sdProgram.Genres != null) { foreach (var genre in sdProgram.Genres) { mxfProgram.mxfKeywords.Add(mxfKeyGroup.GetKeyword(genre)); } } // ensure there is at least 1 category to present in category search if (mxfProgram.mxfKeywords.Count > 1) { return; } mxfProgram.mxfKeywords.Add(mxfKeyGroup.GetKeyword("Uncategorized")); }
public static void DetermineProgramKeywords(ref MxfProgram mxfProgram, List <XmltvText> programCategories) { DetermineProgramKeywords(ref mxfProgram, programCategories.Select(category => category.Text).ToArray()); }
private static List <XmltvEpisodeNum> buildEpisodeNumbers(MxfProgram mxfProgram, MxfScheduleEntry mxfScheduleEntry, DateTime startTime, string channelId) { List <XmltvEpisodeNum> list = new List <XmltvEpisodeNum>(); if (!mxfProgram.tmsId.StartsWith("EPG123")) { list.Add(new XmltvEpisodeNum() { System = "dd_progid", Text = mxfProgram.Uid.Substring(9).Replace("_", ".") }); } if (!string.IsNullOrEmpty(mxfProgram.EpisodeNumber) || !string.IsNullOrEmpty(mxfScheduleEntry.Part)) { string text = string.Format("{0}.{1}.{2}{3}", (mxfProgram.SeasonNumber != null) ? (int.Parse(mxfProgram.SeasonNumber) - 1).ToString() : string.Empty, (mxfProgram.EpisodeNumber != null) ? (int.Parse(mxfProgram.EpisodeNumber) - 1).ToString() : string.Empty, (mxfScheduleEntry.Part != null) ? (int.Parse(mxfScheduleEntry.Part) - 1).ToString() + "/" : "0/", (mxfScheduleEntry.Parts != null) ? (int.Parse(mxfScheduleEntry.Parts)).ToString() : "1"); list.Add(new XmltvEpisodeNum() { System = "xmltv_ns", Text = text }); } else if (mxfProgram.tmsId.StartsWith("EPG123")) { // filler data - create oad of scheduled start time list.Add(new XmltvEpisodeNum() { System = "original-air-date", Text = startTime.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") }); } else if (!mxfProgram.tmsId.StartsWith("MV")) { // add this entry due to Plex identifying anything without an episode number as being a movie string oad = mxfProgram.OriginalAirdate; if (string.IsNullOrEmpty(mxfScheduleEntry.IsRepeat)) { oad = startTime.ToLocalTime().ToString("yyyy-MM-dd HH:mm:") + randomNumber.Next(1, 60).ToString("00"); } else if (string.IsNullOrEmpty(oad)) { oad = "1900-01-01"; } list.Add(new XmltvEpisodeNum() { System = "original-air-date", Text = oad }); } if (mxfProgram.jsonProgramData.Metadata != null) { foreach (Dictionary <string, sdProgramMetadataProvider> providers in mxfProgram.jsonProgramData.Metadata) { foreach (KeyValuePair <string, sdProgramMetadataProvider> provider in providers) { if (provider.Key.ToLower().Equals("thetvdb")) { if (provider.Value.SeriesID > 0) { list.Add(new XmltvEpisodeNum() { System = "thetvdb.com", Text = "series/" + provider.Value.SeriesID.ToString() }); } if (provider.Value.EpisodeID > 0) { list.Add(new XmltvEpisodeNum() { System = "thetvdb.com", Text = "episode/" + provider.Value.EpisodeID.ToString() }); } } } } } return(list); }
private static bool CreateXmltvFile() { try { xmltv = new XMLTV() { Date = DateTime.UtcNow.ToString(), SourceInfoUrl = "http://schedulesdirect.org", SourceInfoName = "Schedules Direct", GeneratorInfoName = "EPG123", GeneratorInfoUrl = "http://epg123.garyan2.net", Channels = new List <XmltvChannel>(), Programs = new List <XmltvProgramme>() }; foreach (MxfLineup lineup in sdMxf.With[0].Lineups) { foreach (MxfChannel channel in lineup.channels) { xmltv.Channels.Add(buildXmltvChannel(channel)); } } foreach (MxfService service in sdMxf.With[0].Services) { DateTime startTime = new DateTime(); if (service.mxfScheduleEntries.ScheduleEntry.Count == 0 && config.XmltvAddFillerData) { // add a program specific for this service MxfProgram program = new MxfProgram() { Description = config.XmltvFillerProgramDescription, IsGeneric = "true", Title = service.Name, tmsId = string.Format("EPG123FILL{0}", service.StationID), index = sdMxf.With[0].Programs.Count + 1, jsonProgramData = new sdProgram() }; // populate the schedule entries startTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, 0, 0, 0); DateTime stopTime = startTime + TimeSpan.FromDays(config.DaysToDownload); do { service.mxfScheduleEntries.ScheduleEntry.Add(new MxfScheduleEntry() { Duration = config.XmltvFillerProgramLength * 60 * 60, Program = sdMxf.With[0].getProgram(program.tmsId, program).Id, StartTime = startTime.ToString("yyyy-MM-ddTHH:mm:ss"), IsRepeat = "true" }); startTime += TimeSpan.FromHours((double)config.XmltvFillerProgramLength); } while (startTime < stopTime); } foreach (MxfScheduleEntry scheduleEntry in service.mxfScheduleEntries.ScheduleEntry) { if (!string.IsNullOrEmpty(scheduleEntry.StartTime)) { startTime = DateTime.Parse(scheduleEntry.StartTime + "Z").ToUniversalTime(); } xmltv.Programs.Add(buildXmltvProgram(scheduleEntry, startTime, service.xmltvChannelID, out startTime)); } } return(true); } catch (Exception ex) { Logger.WriteInformation("Failed to create the XMLTV file. Message : " + ex.Message); } return(false); }
public static bool BuildMxfFromSliceGuide(List <hdhrDiscover> homeruns) { // scan each device for tuned channels and associated programs foreach (var device in homeruns.Select(homerun => Common.Api.ConnectDevice(homerun.DiscoverUrl))) { if (device == null || string.IsNullOrEmpty(device.LineupUrl)) { continue; } Logger.WriteInformation($"Processing {device.FriendlyName} {device.ModelNumber} ({device.DeviceId}) with firmware {device.FirmwareVersion}."); // get channels var channels = Common.Api.GetDeviceChannels(device.LineupUrl); if (channels == null) { continue; } // determine lineup var model = device.ModelNumber.Split('-')[1]; var deviceModel = model.Substring(model.Length - 2); var mxfLineup = Common.Mxf.With[0].GetLineup(deviceModel); foreach (var channel in channels) { var startTime = 0; var programs = Common.Api.GetChannelGuide(device.DeviceAuth, channel.GuideNumber, startTime); if (programs == null) { continue; } // build the service var mxfService = Common.Mxf.With[0].GetService(programs[0].GuideName); if (string.IsNullOrEmpty(mxfService.CallSign)) { mxfService.CallSign = programs[0].GuideName; mxfService.Name = channel.GuideName; mxfService.Affiliate = (!string.IsNullOrEmpty(programs[0].Affiliate)) ? Common.Mxf.With[0].GetAffiliateId(programs[0].Affiliate) : null; mxfService.LogoImage = (!Common.NoLogos && !string.IsNullOrEmpty(programs[0].ImageUrl)) ? Common.Mxf.With[0].GetGuideImage(programs[0].ImageUrl).Id : null; mxfService.MxfScheduleEntries.Service = mxfService.Id; } // add channel to the lineup if (int.TryParse(channel.GuideNumber, out _) || double.TryParse(channel.GuideNumber, out _)) { var digits = channel.GuideNumber.Split('.'); var number = int.Parse(digits[0]); var subnumber = 0; if (digits.Length > 1) { subnumber = int.Parse(digits[1]); } // add the channel to the lineup and make sure we don't duplicate channels var vchan = mxfLineup.channels .Where(arg => arg.Service == mxfService.Id) .Where(arg => arg.Number == number) .SingleOrDefault(arg => arg.SubNumber == subnumber); if (vchan == null) { string matchname; switch (deviceModel) { case "US": // ATSC matchname = $"OC:{number}:{subnumber}"; break; case "DT": // DVB-T matchname = $"DVBT:{channel.OriginalNetworkId}:{channel.TransportStreamId}:{channel.ProgramNumber}"; break; case "CC": // US CableCARD matchname = mxfService.Name; break; //case "IS": // ISDB //case "DC": // DVB-C default: matchname = mxfService.Name; break; } mxfLineup.channels.Add(new MxfChannel() { Lineup = mxfLineup.Id, LineupUid = mxfLineup.Uid, StationId = mxfService.CallSign, Service = mxfService.Id, Number = number, SubNumber = subnumber, MatchName = matchname }); Logger.WriteInformation($"--Processing station {mxfService.CallSign} on channel {number}{((subnumber > 0) ? "." + subnumber : string.Empty)}."); } } // if this channel's listings are already done, stop here if (!Common.ChannelsDone.Add(mxfService.CallSign)) { continue; } // build the programs do { foreach (var program in programs[0].Guide) { // establish the program ID var programId = program.SeriesId; if (!string.IsNullOrEmpty(program.EpisodeNumber)) { programId += "_" + program.EpisodeNumber; } else if (!programId.StartsWith("MV")) { programId += "_" + program.GetHashCode(); } // create an mxf program var mxfProgram = new MxfProgram { Index = Common.Mxf.With[0].Programs.Count + 1, ProgramId = programId }; // create the schedule entry and program if needed var start = program.StartDateTime.ToString("yyyy-MM-ddTHH:mm:ss"); if (program.StartDateTime == mxfService.MxfScheduleEntries.EndTime) { start = null; } mxfService.MxfScheduleEntries.ScheduleEntry.Add(new MxfScheduleEntry() { Duration = program.EndTime - program.StartTime, IsHdtv = channel.Hd ? "true" : null, Program = Common.Mxf.With[0].GetProgram(programId, mxfProgram).Id, StartTime = start }); // build the program BuildProgram(programId, program); startTime = program.EndTime; } } while ((programs = Common.Api.GetChannelGuide(device.DeviceAuth, channel.GuideNumber, startTime)) != null); } } return(true); }
private static bool BuildProgram(string tmsId, XmltvProgramme program) { MxfProgram mxfProgram = Common.mxf.With[0].getProgram(tmsId); if (!string.IsNullOrEmpty(mxfProgram.Title)) { return(true); } mxfProgram.Title = program.Titles[0].Text; if (mxfProgram.episodeInfo.NumberOfParts > 1) { string partofparts = string.Format(" ({0}/{1})", mxfProgram.episodeInfo.PartNumber, mxfProgram.episodeInfo.NumberOfParts); mxfProgram.Title = mxfProgram.Title.Replace(partofparts, "") + partofparts; } mxfProgram.EpisodeTitle = (program.SubTitles.Count > 0) ? program.SubTitles[0].Text : null; mxfProgram.Description = (program.Descriptions.Count > 0) ? program.Descriptions[0].Text : null; mxfProgram.Language = program.Language?.Text ?? program.Titles[0].Language; mxfProgram.SeasonNumber = (mxfProgram.episodeInfo.SeasonNumber > 0) ? mxfProgram.episodeInfo.SeasonNumber.ToString() : null; mxfProgram.EpisodeNumber = (mxfProgram.episodeInfo.EpisodeNumber > 0) ? mxfProgram.episodeInfo.EpisodeNumber.ToString() : null; mxfProgram.IsAction = Common.ListContains(program.Categories, "Action"); mxfProgram.IsComedy = Common.ListContains(program.Categories, "Comedy"); mxfProgram.IsDocumentary = Common.ListContains(program.Categories, "Documentary"); mxfProgram.IsDrama = Common.ListContains(program.Categories, "Drama"); mxfProgram.IsEducational = Common.ListContains(program.Categories, "Educational"); mxfProgram.IsHorror = Common.ListContains(program.Categories, "Horror"); //mxfProgram.IsIndy = null; mxfProgram.IsKids = Common.ListContains(program.Categories, "Children") ?? Common.ListContains(program.Categories, "Family"); mxfProgram.IsMusic = Common.ListContains(program.Categories, "Music"); mxfProgram.IsNews = Common.ListContains(program.Categories, "News"); mxfProgram.IsReality = Common.ListContains(program.Categories, "Reality"); mxfProgram.IsRomance = Common.ListContains(program.Categories, "Romance"); mxfProgram.IsScienceFiction = Common.ListContains(program.Categories, "Science Fiction"); mxfProgram.IsSoap = Common.ListContains(program.Categories, "Soap"); mxfProgram.IsThriller = Common.ListContains(program.Categories, "Suspense") ?? Common.ListContains(program.Categories, "Thriller"); //mxfProgram.IsPremiere = ; //mxfProgram.IsSeasonFinale = ; //mxfProgram.IsSeasonPremiere = ; //mxfProgram.IsSeriesFinale = ; //mxfProgram.IsSeriesPremiere = ; //mxfProgram.IsLimitedSeries = null; mxfProgram.IsMiniseries = Common.ListContains(program.Categories, "Miniseries"); mxfProgram.IsMovie = mxfProgram.episodeInfo.Type.Equals("MV") ? "true" : Common.ListContains(program.Categories, "Movie"); mxfProgram.IsPaidProgramming = Common.ListContains(program.Categories, "Paid Programming"); //mxfProgram.IsProgramEpisodic = null; //mxfProgram.IsSerial = null; mxfProgram.IsSeries = Common.ListContains(program.Categories, "Series") ?? Common.ListContains(program.Categories, "Sports non-event"); mxfProgram.IsShortFilm = Common.ListContains(program.Categories, "Short Film"); mxfProgram.IsSpecial = Common.ListContains(program.Categories, "Special"); mxfProgram.IsSports = Common.ListContains(program.Categories, "Sports event"); if (string.IsNullOrEmpty(mxfProgram.IsSeries + mxfProgram.IsMiniseries + mxfProgram.IsMovie + mxfProgram.IsPaidProgramming + mxfProgram.IsShortFilm + mxfProgram.IsSpecial + mxfProgram.IsSports)) { mxfProgram.IsSeries = "true"; } // determine if generic if (mxfProgram.episodeInfo.Type.Equals("SH") && (!string.IsNullOrEmpty(mxfProgram.IsSeries) || !string.IsNullOrEmpty(mxfProgram.IsSports)) && string.IsNullOrEmpty(mxfProgram.IsMiniseries) && string.IsNullOrEmpty(mxfProgram.IsPaidProgramming)) { mxfProgram.IsGeneric = "true"; } // determine keywords Common.determineProgramKeywords(ref mxfProgram, program.Categories); // take care of episode original air date or movie year if (!string.IsNullOrEmpty(mxfProgram.IsMovie) && !string.IsNullOrEmpty(program.Date)) { mxfProgram.Year = program.Date.Substring(0, 4); } else if (!string.IsNullOrEmpty(program.Date) && program.Date.Length >= 8) { mxfProgram.OriginalAirdate = program.Date.Substring(0, 4) + "-" + program.Date.Substring(4, 2) + "-" + program.Date.Substring(6, 2); } else if (program.PreviouslyShown != null) { mxfProgram.OriginalAirdate = "1970-01-01"; } // handle series specific info if (string.IsNullOrEmpty(mxfProgram.IsMovie)) { MxfSeriesInfo mxfSeriesInfo = Common.mxf.With[0].getSeriesInfo(mxfProgram.episodeInfo.SeriesID); if (string.IsNullOrEmpty(mxfSeriesInfo.Title)) { mxfSeriesInfo.Title = mxfProgram.Title; if (program.Icons.Count > 0) { mxfSeriesInfo.GuideImage = Common.mxf.With[0].getGuideImage(program.Icons[0].src)?.Id; } } if (mxfProgram.episodeInfo.Type.Equals("SH")) { if (string.IsNullOrEmpty(mxfSeriesInfo.Description)) { mxfSeriesInfo.Description = mxfProgram.Description; } } mxfProgram.Series = mxfSeriesInfo.Id; // if there is a season number, create as seasonInfo entry if (!string.IsNullOrEmpty(mxfProgram.SeasonNumber)) { mxfProgram.Season = Common.mxf.With[0].getSeasonId(mxfProgram.episodeInfo.SeriesID, mxfProgram.SeasonNumber); } } // handle movie specific info else { // grab the movie poster var icon = program.Icons.Where(arg => arg.src.Contains("/posters/")).SingleOrDefault(); if (icon != null) { mxfProgram.GuideImage = Common.mxf.With[0].getGuideImage(icon.src).Id; } else if (program.Icons.Count > 0) { mxfProgram.GuideImage = Common.mxf.With[0].getGuideImage(program.Icons[0].src).Id; } // get the star ratings if (program.StarRating.Count > 0) { mxfProgram.HalfStars = GetStarRating(program.StarRating); } else if (program.Descriptions.Count > 0) { Match m = Regex.Match(program.Descriptions[0].Text, @"\d\.\d/\d\.\d"); if (m != null) { string[] nums = m.Value.Split('/'); if (nums.Length == 2) { if (double.TryParse(nums[0], out double numerator) && double.TryParse(nums[1], out double denominator)) { int halfstars = (int)((numerator / denominator) * 8); mxfProgram.HalfStars = halfstars.ToString(); mxfProgram.Description = mxfProgram.Description.Replace(string.Format(" ({0})", m.Value), ""); } } } } // handle movie ratings and advisories GetUsMovieRatings(program.Rating, mxfProgram); } // handle cast and crew if (program.Credits != null) { foreach (string person in program.Credits.Directors) { mxfProgram.DirectorRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } foreach (XmltvActor person in program.Credits.Actors) { mxfProgram.ActorRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person.Actor), Character = person.Role, }); } foreach (string person in program.Credits.Writers) { mxfProgram.WriterRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } foreach (string person in program.Credits.Adapters) { mxfProgram.WriterRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } foreach (string person in program.Credits.Producers) { mxfProgram.ProducerRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } foreach (string person in program.Credits.Composers) { mxfProgram.ProducerRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } foreach (string person in program.Credits.Editors) { mxfProgram.HostRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } foreach (string person in program.Credits.Presenters) { mxfProgram.HostRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } foreach (string person in program.Credits.Commentators) { mxfProgram.HostRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } foreach (string person in program.Credits.Guests) { mxfProgram.GuestActorRole.Add(new MxfPersonRank() { Person = Common.mxf.With[0].getPersonId(person), }); } } return(true); }
private static void GetUsMovieRatings(List <XmltvRating> ratings, MxfProgram mxfProgram) { foreach (XmltvRating rating in ratings) { if (string.IsNullOrEmpty(rating.System)) { continue; } if (rating.System.ToLower().Equals("motion picture association of america") || rating.System.ToLower().Equals("mpaa")) { switch (rating.Value.ToLower().Replace("-", "")) { case "g": mxfProgram.MpaaRating = "1"; break; case "pg": mxfProgram.MpaaRating = "2"; break; case "pg13": mxfProgram.MpaaRating = "3"; break; case "r": mxfProgram.MpaaRating = "4"; break; case "nc17": mxfProgram.MpaaRating = "5"; break; case "x": mxfProgram.MpaaRating = "6"; break; case "nr": mxfProgram.MpaaRating = "7"; break; case "ao": mxfProgram.MpaaRating = "8"; break; default: break; } } else if (rating.System.ToLower().Equals("advisory")) { switch (rating.Value.ToLower()) { case "adult situations": mxfProgram.HasAdult = "true"; break; case "brief nudity": mxfProgram.HasBriefNudity = "true"; break; case "graphic language": mxfProgram.HasGraphicLanguage = "true"; break; case "graphic violence": mxfProgram.HasGraphicViolence = "true"; break; case "adult language": mxfProgram.HasLanguage = "true"; break; case "mild violence": mxfProgram.HasMildViolence = "true"; break; case "nudity": mxfProgram.HasNudity = "true"; break; case "rape": mxfProgram.HasRape = "true"; break; case "strong sexual content": mxfProgram.HasStrongSexualContent = "true"; break; case "violence": mxfProgram.HasViolence = "true"; break; default: break; } } } }
private static void CompleteEpisodeTitle(MxfProgram mxfProgram) { // by request, if there is no episode title, and the program is not generic, duplicate the program title in the episode title if (mxfProgram.ProgramId.StartsWith("EP") && string.IsNullOrEmpty(mxfProgram.EpisodeTitle)) { mxfProgram.EpisodeTitle = mxfProgram.Title; } else if (string.IsNullOrEmpty(mxfProgram.EpisodeTitle)) { return; } var se = config.AlternateSEFormat ? "S{0}:E{1} " : "s{0:D2}e{1:D2} "; if (mxfProgram.SeasonNumber != 0) { se = string.Format(se, mxfProgram.SeasonNumber, mxfProgram.EpisodeNumber); } else if (mxfProgram.EpisodeNumber != 0) { se = $"#{mxfProgram.EpisodeNumber} "; } else { se = string.Empty; } // prefix episode title with season and episode numbers as configured if (config.PrefixEpisodeTitle) { mxfProgram.EpisodeTitle = se + mxfProgram.EpisodeTitle; } // prefix episode description with season and episode numbers as configured if (config.PrefixEpisodeDescription) { mxfProgram.Description = se + mxfProgram.Description; if (!string.IsNullOrEmpty(mxfProgram.ShortDescription)) { mxfProgram.ShortDescription = se + mxfProgram.ShortDescription; } } // append season and episode numbers to the program description as configured if (config.AppendEpisodeDesc) { // add space before appending season and episode numbers in case there is no short description if (mxfProgram.SeasonNumber != 0 && mxfProgram.EpisodeNumber != 0) { mxfProgram.Description += $" \u000D\u000ASeason {mxfProgram.SeasonNumber}, Episode {mxfProgram.EpisodeNumber}"; } else if (mxfProgram.EpisodeNumber != 0) { mxfProgram.Description += $" \u000D\u000AProduction #{mxfProgram.EpisodeNumber}"; } } // append part/parts to episode title as needed if (mxfProgram.extras.ContainsKey("multipart")) { mxfProgram.EpisodeTitle += $" ({mxfProgram.extras["multipart"]})"; } }
public static void determineProgramKeywords(ref MxfProgram mxfProgram, string[] programCategories) { // determine primary group of program GROUPS group = GROUPS.UNKNOWN; if (!string.IsNullOrEmpty(mxfProgram.IsMovie)) { group = GROUPS.MOVIES; } else if (!string.IsNullOrEmpty(mxfProgram.IsPaidProgramming)) { group = GROUPS.PAIDPROGRAMMING; } else if (!string.IsNullOrEmpty(mxfProgram.IsSports)) { group = GROUPS.SPORTS; } else if (!string.IsNullOrEmpty(mxfProgram.IsKids)) { group = GROUPS.KIDS; } else if (!string.IsNullOrEmpty(mxfProgram.IsEducational)) { group = GROUPS.EDUCATIONAL; } else if (!string.IsNullOrEmpty(mxfProgram.IsNews)) { group = GROUPS.NEWS; } else if (!string.IsNullOrEmpty(mxfProgram.IsSpecial)) { group = GROUPS.SPECIAL; } else if (!string.IsNullOrEmpty(mxfProgram.IsReality)) { group = GROUPS.REALITY; } else if (!string.IsNullOrEmpty(mxfProgram.IsSeries)) { group = GROUPS.SERIES; } // build the keywords/categories if (group != GROUPS.UNKNOWN) { mxfProgram.Keywords = string.Format("k{0}", (int)group + 1); // add premiere categories as necessary if (!string.IsNullOrEmpty(mxfProgram.IsSeasonPremiere) || !string.IsNullOrEmpty(mxfProgram.IsSeriesPremiere)) { mxfProgram.Keywords += string.Format(",k{0}", (int)GROUPS.PREMIERES + 1); if (!string.IsNullOrEmpty(mxfProgram.IsSeasonPremiere)) { mxfProgram.Keywords += "," + mxf.With[0].KeywordGroups[(int)GROUPS.PREMIERES].getKeywordId("Season Premiere"); } if (!string.IsNullOrEmpty(mxfProgram.IsSeriesPremiere)) { mxfProgram.Keywords += "," + mxf.With[0].KeywordGroups[(int)GROUPS.PREMIERES].getKeywordId("Series Premiere"); } } else if (!string.IsNullOrEmpty(mxfProgram.IsPremiere) && string.IsNullOrEmpty(mxfProgram.IsGeneric)) { if (group == GROUPS.MOVIES) { mxfProgram.Keywords += "," + mxf.With[0].KeywordGroups[(int)group].getKeywordId("Premiere"); } else if (!string.IsNullOrEmpty(mxfProgram.IsMiniseries)) { mxfProgram.Keywords += string.Format(",k{0}", (int)GROUPS.PREMIERES + 1); mxfProgram.Keywords += "," + mxf.With[0].KeywordGroups[(int)GROUPS.PREMIERES].getKeywordId("Miniseries Premiere"); } else if (!string.IsNullOrEmpty(mxfProgram.IsSeries)) { mxfProgram.Keywords += string.Format(",k{0}", (int)GROUPS.PREMIERES + 1); mxfProgram.Keywords += "," + mxf.With[0].KeywordGroups[(int)GROUPS.PREMIERES].getKeywordId("Series/Season Premiere"); } } // now add the real categories if (programCategories != null) { foreach (string category in programCategories) { switch (category.ToLower()) { case "feature film": case "short film": case "tv movie": case "miniseries": case "series": case "special": case "sports event": case "sports non-event": case "paid programming": case "theatre event": case "show": case "episode": case "sports": case "movie": break; default: string key = mxf.With[0].KeywordGroups[(int)group].getKeywordId(CultureInfo.InvariantCulture.TextInfo.ToTitleCase(category.ToLowerInvariant())); List <string> keys = mxfProgram.Keywords.Split(',').ToList(); if (!keys.Contains(key)) { mxfProgram.Keywords += "," + key; } break; } } } if (mxfProgram.Keywords.Length < 5) { string key = mxf.With[0].KeywordGroups[(int)group].getKeywordId("Uncategorized"); mxfProgram.Keywords += "," + key; } } }
public static bool BuildMxfFromSliceGuide(List <HDHRDiscover> homeruns) { // scan each device for tuned channels and associated programs foreach (HDHRDiscover homerun in homeruns) { HDHRDevice device = Common.api.ConnectDevice(homerun.DiscoverURL); if (device == null || string.IsNullOrEmpty(device.LineupURL)) { continue; } else { Console.WriteLine(string.Format("Processing {0} {1} ({2}) with firmware {3}.", device.FriendlyName, device.ModelNumber, device.DeviceID, device.FirmwareVersion)); } // get channels List <HDHRChannel> channels = Common.api.GetDeviceChannels(device.LineupURL); if (channels == null) { continue; } // determine lineup string model = device.ModelNumber.Split('-')[1]; string deviceModel = model.Substring(model.Length - 2); MxfLineup mxfLineup = Common.mxf.With[0].getLineup(deviceModel); foreach (HDHRChannel channel in channels) { int startTime = 0; List <HDHRChannelGuide> programs = Common.api.GetChannelGuide(device.DeviceAuth, channel.GuideNumber, startTime); if (programs == null) { continue; } // build the service MxfService mxfService = Common.mxf.With[0].getService(programs[0].GuideName); if (string.IsNullOrEmpty(mxfService.CallSign)) { mxfService.CallSign = programs[0].GuideName; mxfService.Name = channel.GuideName; mxfService.Affiliate = (!string.IsNullOrEmpty(programs[0].Affiliate)) ? Common.mxf.With[0].getAffiliateId(programs[0].Affiliate) : null; mxfService.LogoImage = (!Common.noLogos && !string.IsNullOrEmpty(programs[0].ImageURL)) ? Common.mxf.With[0].getGuideImage(programs[0].ImageURL).Id : null; mxfService.mxfScheduleEntries.Service = mxfService.Id; } // add channel to the lineup if (int.TryParse(channel.GuideNumber, out int iChannel) || double.TryParse(channel.GuideNumber, out double dChannel)) { string[] digits = channel.GuideNumber.Split('.'); int number = int.Parse(digits[0]); int subnumber = 0; if (digits.Length > 1) { subnumber = int.Parse(digits[1]); } // add the channel to the lineup and make sure we don't duplicate channels var vchan = mxfLineup.channels.Where(arg => arg.Service == mxfService.Id) .Where(arg => arg.Number == number) .Where(arg => arg.SubNumber == subnumber) .SingleOrDefault(); if (vchan == null) { string matchname = null; switch (deviceModel) { case "US": // ATSC matchname = string.Format("OC:{0}:{1}", number, subnumber); break; case "DT": // DVB-T matchname = string.Format("DVBT:{0}:{1}:{2}", channel.OriginalNetworkID, channel.TransportStreamID, channel.ProgramNumber); break; case "CC": // US CableCARD matchname = mxfService.Name; break; case "IS": // ISDB case "DC": // DVB-C default: matchname = mxfService.Name; break; } mxfLineup.channels.Add(new MxfChannel() { Lineup = mxfLineup.Id, lineupUid = mxfLineup.Uid, stationId = mxfService.CallSign, Service = mxfService.Id, Number = number, SubNumber = subnumber, MatchName = matchname }); Console.WriteLine(string.Format("--Processing station {0} on channel {1}{2}.", mxfService.CallSign, number, (subnumber > 0) ? "." + subnumber.ToString() : string.Empty)); } } // if this channel's listings are already done, stop here if (!Common.channelsDone.Add(mxfService.CallSign)) { continue; } // build the programs do { foreach (HDHRProgram program in programs[0].Guide) { // establish the program ID string programID = program.SeriesID; if (!string.IsNullOrEmpty(program.EpisodeNumber)) { programID += "_" + program.EpisodeNumber; } else if (!programID.StartsWith("MV")) { programID += "_" + program.GetHashCode().ToString(); } // create an mxf program MxfProgram mxfProgram = new MxfProgram() { index = Common.mxf.With[0].Programs.Count + 1 }; mxfProgram.programId = programID; // create the schedule entry and program if needed string start = program.StartDateTime.ToString("yyyy-MM-ddTHH:mm:ss"); if (program.StartDateTime == mxfService.mxfScheduleEntries.endTime) { start = null; } mxfService.mxfScheduleEntries.ScheduleEntry.Add(new MxfScheduleEntry() { Duration = program.EndTime - program.StartTime, IsHdtv = channel.HD ? "true" : null, Program = Common.mxf.With[0].getProgram(programID, mxfProgram).Id, StartTime = start }); // build the program BuildProgram(programID, program); startTime = program.EndTime; } } while ((programs = Common.api.GetChannelGuide(device.DeviceAuth, channel.GuideNumber, startTime)) != null); } } return(true); }