/// <summary> /// Parses the specified XMLTV file. /// </summary> /// <param name="config">The configuration.</param> /// <returns> /// List of extracted programmes. /// </returns> public IEnumerable <XMLTVProgramme> ParseFile(XMLTVConfiguration config) { var channels = new Dictionary <string, string[]>(); var document = XDocument.Load(config.File); foreach (var channel in document.Descendants("channel")) { var id = channel.Attribute("id"); var name = channel.Descendants("display-name").ToList(); var url = channel.Descendants("url").ToList(); if (id == null || !name.Any()) { continue; } channels.Add(id.Value, new[] { name[0].Value, url.Any() ? url.Last().Value : null }); } foreach (var programme in document.Descendants("programme")) { var channel = programme.Attribute("channel"); var start = programme.Attribute("start"); var title = programme.Descendants("title").ToList(); var descr = programme.Descendants("desc").ToList(); if (channel == null || start == null || !title.Any()) { continue; } DateTime airdate; if (!DateTime.TryParseExact(start.Value, "yyyyMMddHHmmss zzz", CultureInfo.InvariantCulture, DateTimeStyles.None, out airdate)) { continue; } var prog = new XMLTVProgramme { Channel = channels[channel.Value][0], Name = title[0].Value.Trim(), Airdate = airdate, URL = channels[channel.Value][1] }; if (descr.Any()) { prog.Description = descr[0].Value.Trim(); } yield return(prog); } }
/// <summary> /// Parses the specified XMLTV file. /// </summary> /// <param name="config">The configuration.</param> /// <returns> /// List of extracted programmes. /// </returns> public IEnumerable<XMLTVProgramme> ParseFile(XMLTVConfiguration config) { var channels = new Dictionary<string, string[]>(); var document = XDocument.Load(config.File); foreach (var channel in document.Descendants("channel")) { var id = channel.Attribute("id"); var name = channel.Descendants("display-name").ToList(); var url = channel.Descendants("url").ToList(); if (id == null || !name.Any()) { continue; } channels.Add(id.Value, new[] { name[0].Value, url.Any() ? url.Last().Value : null }); } foreach (var programme in document.Descendants("programme")) { var channel = programme.Attribute("channel"); var start = programme.Attribute("start"); var title = programme.Descendants("title").ToList(); var descr = programme.Descendants("desc").ToList(); if (channel == null || start == null || !title.Any()) { continue; } DateTime airdate; if (!DateTime.TryParseExact(start.Value, "yyyyMMddHHmmss zzz", CultureInfo.InvariantCulture, DateTimeStyles.None, out airdate)) { continue; } var prog = new XMLTVProgramme { Channel = channels[channel.Value][0], Name = title[0].Value.Trim(), Airdate = airdate, URL = channels[channel.Value][1] }; if (descr.Any()) { prog.Description = descr[0].Value.Trim(); } yield return prog; } }
/// <summary> /// Gets a list of upcoming episodes in your area ordered by airdate. /// </summary> /// <param name="config">The config.</param> /// <returns> /// List of upcoming episodes in your area. /// </returns> public override IEnumerable<Programme> GetListing(Configuration config) { var xconfig = (XMLTVConfiguration) config; var listing = (List<XMLTVProgramme>) null; var cache = Path.Combine(Signature.FullPath, @"misc\xmltv-" + xconfig.Language + "-" + xconfig.File.GetHashCode().ToString("x")); if (File.Exists(cache) && File.GetLastWriteTime(cache) > File.GetLastWriteTime(xconfig.File)) { try { using (var fs = File.OpenRead(cache)) using (var br = new BinaryReader(fs)) { var ver = br.ReadByte(); var upd = br.ReadUInt32(); var cnt = br.ReadUInt32(); listing = new List<XMLTVProgramme>(); for (var i = 0; i < cnt; i++) { var prog = new XMLTVProgramme(); prog.ShowID = br.ReadInt32(); prog.Name = br.ReadString(); prog.Number = br.ReadString(); prog.Description = br.ReadString(); prog.Channel = br.ReadString(); prog.Airdate = ((double)br.ReadInt32()).GetUnixTimestamp(); prog.URL = br.ReadString(); listing.Add(prog); } } } catch { listing = null; } } if (listing == null) { listing = Filter(ParseFile(xconfig), xconfig).ToList(); } if (!Directory.Exists(Path.GetDirectoryName(cache))) { Directory.CreateDirectory(Path.GetDirectoryName(cache)); } using (var fs = File.OpenWrite(cache)) using (var bw = new BinaryWriter(fs)) { bw.Write((byte)1); bw.Write((uint)DateTime.Now.ToUnixTimestamp()); bw.Write((uint)listing.Count); foreach (var prog in listing) { bw.Write(prog.ShowID); bw.Write(prog.Name ?? string.Empty); bw.Write(prog.Number ?? string.Empty); bw.Write(prog.Description ?? string.Empty); bw.Write(prog.Channel ?? string.Empty); bw.Write((int)prog.Airdate.ToUnixTimestamp()); bw.Write(prog.URL ?? string.Empty); } } foreach (var prog in listing.Where(p => p.Airdate.AddHours(xconfig.TZCorrection) > DateTime.Now)) { if (xconfig.AdvHuRoParse && prog.Description.StartsWith(prog.Name)) { var ep = Regex.Match(prog.Description, @"(?:(?:(?<sr>[IVXLCDM]+)\.(?: évad)?\s*/\s*)?(?<e>\d{1,3})\. rész|(?<s>\d{1,2})\. évad(?:,? (?<e>\d{1,3})\. rész)?|(?:sezonul (?<s>\d{1,2}), )?episodul (?<e>\d{1,3})|^\s*" + Regex.Escape(prog.Name) + @"\s+(?<e>\d{1,3})\.(?:,\s+)?)"); prog.Description = Regex.Replace(prog.Description, @"^\s*" + Regex.Escape(prog.Name) + @"\s*(\d{1,3}\.(?:,\s+|$))?(?:\([^\)]+\)\s*)?(?:\(ism\.\)\s*)?(?:(?:\d{1,2}|[IVXLCDM]+)\. évad(?:\s*[,/] \d{1,3}\. rész(?:, )?)?)?(?:\-\s*)?(?:\((?:reluare|St)\)\s*)?(?: Utána: .+| Feliratozva .+)?", string.Empty, RegexOptions.IgnoreCase); if (ep.Success) { prog.Number = string.Empty; if (ep.Groups["sr"].Success) { prog.Number = "S" + Utils.RomanToNumber(ep.Groups["sr"].Value).ToString("00"); if (ep.Groups["e"].Success) { prog.Number += " #" + int.Parse(ep.Groups["e"].Value); } } else { if (ep.Groups["s"].Success) { prog.Number = "S" + int.Parse(ep.Groups["s"].Value).ToString("00"); } else if (ep.Groups["e"].Success) { prog.Number += "#" + int.Parse(ep.Groups["e"].Value); } if (ep.Groups["s"].Success && ep.Groups["e"].Success) { prog.Number += "E" + int.Parse(ep.Groups["e"].Value).ToString("00"); } } } } if (xconfig.UseMappedNames) { prog.Name = prog.Show.Name; } if (xconfig.TZCorrection != 0) { prog.Airdate = prog.Airdate.AddHours(xconfig.TZCorrection); } yield return prog; } }
/// <summary> /// Gets a list of upcoming episodes in your area ordered by airdate. /// </summary> /// <param name="config">The config.</param> /// <returns> /// List of upcoming episodes in your area. /// </returns> public override IEnumerable <Programme> GetListing(Configuration config) { var xconfig = (XMLTVConfiguration)config; var listing = (List <XMLTVProgramme>)null; var cache = Path.Combine(Signature.InstallPath, @"misc\xmltv-" + xconfig.Language + "-" + xconfig.File.GetHashCode().ToString("x")); if (File.Exists(cache) && File.GetLastWriteTime(cache) > File.GetLastWriteTime(xconfig.File)) { try { using (var fs = File.OpenRead(cache)) using (var br = new BinaryReader(fs)) { var ver = br.ReadByte(); var upd = br.ReadUInt32(); var cnt = br.ReadUInt32(); listing = new List <XMLTVProgramme>(); for (var i = 0; i < cnt; i++) { var prog = new XMLTVProgramme(); prog.ShowID = br.ReadInt32(); prog.Name = br.ReadString(); prog.Number = br.ReadString(); prog.Description = br.ReadString(); prog.Channel = br.ReadString(); prog.Airdate = ((double)br.ReadInt32()).GetUnixTimestamp(); prog.URL = br.ReadString(); listing.Add(prog); } } } catch { listing = null; } } if (listing == null) { listing = Filter(ParseFile(xconfig), xconfig).ToList(); } if (!Directory.Exists(Path.GetDirectoryName(cache))) { Directory.CreateDirectory(Path.GetDirectoryName(cache)); } using (var fs = File.OpenWrite(cache)) using (var bw = new BinaryWriter(fs)) { bw.Write((byte)1); bw.Write((uint)DateTime.Now.ToUnixTimestamp()); bw.Write((uint)listing.Count); foreach (var prog in listing) { bw.Write(prog.ShowID); bw.Write(prog.Name ?? string.Empty); bw.Write(prog.Number ?? string.Empty); bw.Write(prog.Description ?? string.Empty); bw.Write(prog.Channel ?? string.Empty); bw.Write((int)prog.Airdate.ToUnixTimestamp()); bw.Write(prog.URL ?? string.Empty); } } foreach (var prog in listing.Where(p => p.Airdate.AddHours(xconfig.TZCorrection) > DateTime.Now)) { if (xconfig.AdvHuRoParse && prog.Description.StartsWith(prog.Name)) { var ep = Regex.Match(prog.Description, @"(?:(?:(?<sr>[IVXLCDM]+)\.(?: évad)?\s*/\s*)?(?<e>\d{1,3})\. rész|(?<s>\d{1,2})\. évad(?:,? (?<e>\d{1,3})\. rész)?|(?:sezonul (?<s>\d{1,2}), )?episodul (?<e>\d{1,3})|^\s*" + Regex.Escape(prog.Name) + @"\s+(?<e>\d{1,3})\.(?:,\s+)?)"); prog.Description = Regex.Replace(prog.Description, @"^\s*" + Regex.Escape(prog.Name) + @"\s*(\d{1,3}\.(?:,\s+|$))?(?:\([^\)]+\)\s*)?(?:\(ism\.\)\s*)?(?:(?:\d{1,2}|[IVXLCDM]+)\. évad(?:\s*[,/] \d{1,3}\. rész(?:, )?)?)?(?:\-\s*)?(?:\((?:reluare|St)\)\s*)?(?: Utána: .+| Feliratozva .+)?", string.Empty, RegexOptions.IgnoreCase); if (ep.Success) { prog.Number = string.Empty; if (ep.Groups["sr"].Success) { prog.Number = "S" + Utils.RomanToNumber(ep.Groups["sr"].Value).ToString("00"); if (ep.Groups["e"].Success) { prog.Number += " #" + int.Parse(ep.Groups["e"].Value); } } else { if (ep.Groups["s"].Success) { prog.Number = "S" + int.Parse(ep.Groups["s"].Value).ToString("00"); } else if (ep.Groups["e"].Success) { prog.Number += "#" + int.Parse(ep.Groups["e"].Value); } if (ep.Groups["s"].Success && ep.Groups["e"].Success) { prog.Number += "E" + int.Parse(ep.Groups["e"].Value).ToString("00"); } } } } if (xconfig.UseMappedNames) { prog.Name = prog.Show.Title; } if (xconfig.TZCorrection != 0) { prog.Airdate = prog.Airdate.AddHours(xconfig.TZCorrection); } yield return(prog); } }