Group support and multiple package import.
2 using System.Collections.Generic;
5 using System.Threading.Tasks;
7 using System.Diagnostics;
16 // Create a new CQ object wrapping a single element.
20 // URL to a KingOfSat channel list. Typically a package list.
23 // List of channels parsed.
24 public static List<Channel> Parse(List<Channel> aChannels, string aUrl, string aOrbitalPosition)
26 //To avoid duplicated name
27 Dictionary<string, int> names = new Dictionary<string, int>();
29 string kos = new WebClient().DownloadString(aUrl);
34 //Get all the Frequency elements in our page
35 CQ sats = dom[".frq"];
37 //Create our list of channels
38 List<Channel> channels = new List<Channel>();
40 foreach (IDomObject frq in sats.ToList())
42 Channel common = new Channel();
44 //Parse channel details
45 common.OrbitalPosition = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td > a > font").Get(0).InnerText).Trim();
46 if (common.OrbitalPosition != aOrbitalPosition)
51 common.Satellite = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(2) > a").Get(0).InnerText);
52 common.Frequency = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(3)").Get(0).InnerText);
53 common.Polarisation = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(4)").Get(0).InnerText);
54 common.Transponder = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(5) > a").Get(0).InnerText);
55 common.Beam = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(6) > a").Get(0).InnerText);
56 common.Standard = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(7)").Get(0).InnerText);
57 common.Modulation = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(8)").Get(0).InnerText);
58 common.SymbolRate = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(9) > a").Get(0).InnerText);
59 common.FEC = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(9) > a:nth-child(2)").Get(0).InnerText);
62 common.Provider = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(10) > b").Get(0).InnerText);
68 common.Bitrate = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(10)").Get(0).InnerText);
69 if (common.Bitrate.Substring(0, ", ".Length) == ", ")
71 common.Bitrate = common.Bitrate.Substring(", ".Length, common.Bitrate.Length - ", ".Length);
74 common.NetworkID = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(11)").Get(0).InnerText);
75 common.NetworkID = common.NetworkID.Substring("NID:".Length, common.NetworkID.Length - "NID:".Length);
77 common.TransponderID = WebUtility.HtmlDecode(frq.Cq().Find("tbody > tr > td:nth-child(12)").Get(0).InnerText);
78 common.TransponderID = common.TransponderID.Substring("TID:".Length, common.TransponderID.Length - "TID:".Length);
80 //We got common properties for the coming channels
81 //Debug.Write(common.ToString());
83 //Now get all the channels for that frequency
84 //Channel common = new Channel();
86 CQ channelsDiv = frq.Cq().Next("div");
87 CQ channelsTableRows = channelsDiv.Find("table.fl > tbody").Children("tr");
89 foreach (IDomObject row in channelsTableRows)
91 Channel channel = new Channel();
92 //Initialize this channel with common properties on this frequency
95 //Try and parse channel name
96 CQ cqChannelName = row.Cq().Find("td:nth-child(3) > a");
97 if (cqChannelName.Length == 0)
99 cqChannelName = row.Cq().Find("td:nth-child(3) > i");
100 if (cqChannelName.Length == 0)
102 //Can't get channel name
103 Debug.Write("WARNING: Can't find channel name! Skipping this channel");
108 string channelNameInnerText = cqChannelName.Get(0).InnerText;
109 channel.Name = WebUtility.HtmlDecode(channelNameInnerText).Trim();
110 //Encoding decoder = Encoding.UTF8;
111 //channel.Name = decoder.GetString(channel.Name);
112 //channel.Name = channelNameInnerText.Trim(); //Make up your mind :)
113 if (channel.Name == "Name")
115 //Skipping header rows
119 //Make sure our channel name looks descent
120 channel.Name = CleanChannelName(channel.Name);
121 //Make sure the resulting name is unique to avoid having multiple tuning detail for a single channel
122 if (names.ContainsKey(channel.Name))
124 names[channel.Name]++;
125 channel.Name += " " + names[channel.Name];
129 names.Add(channel.Name, 1);
133 //We don't want channels we already have
134 Channel existingChannel = aChannels.Find(c => c.Name == channel.Name);
135 if (existingChannel!=null)
141 //So we have a channel name get the other properties then
142 channel.Country = WebUtility.HtmlDecode(row.Cq().Find("td:nth-child(4)").Get(0).InnerText).Trim();
143 channel.Category = WebUtility.HtmlDecode(row.Cq().Find("td:nth-child(5)").Get(0).InnerText).Trim();
144 if (channel.Category=="")
146 channel.Category = "Other";
149 //Skip the encryptions
150 channel.SID = WebUtility.HtmlDecode(row.Cq().Find("td:nth-child(8)").Get(0).InnerText).Trim();
151 channel.VPID = WebUtility.HtmlDecode(row.Cq().Find("td:nth-child(9)").Get(0).InnerText).Trim();
153 channel.PMT = WebUtility.HtmlDecode(row.Cq().Find("td:nth-child(11)").Get(0).InnerText).Trim();
154 channel.PCR = WebUtility.HtmlDecode(row.Cq().Find("td:nth-child(11)").Get(0).InnerText).Trim();
155 channel.TXT = WebUtility.HtmlDecode(row.Cq().Find("td:nth-child(11)").Get(0).InnerText).Trim();
157 //Append that new channel to our list
158 channels.Add(channel);
160 //Show it in debug output
161 Debug.Write(channel);
163 } //For each frequency
169 public static string CleanChannelName(string aName)
171 aName = aName.Trim();
172 string[] remove = { " Germany", " Deutschland", " (Germany)", " (Deutschland)" };
174 foreach (string item in remove)
176 //if (aName.EndsWith(item))
177 if (aName.Contains(item))
179 aName = aName.Substring(0, aName.LastIndexOf(item));
180 break; //only allow one match at most
183 aName = aName.Trim();
188 public static List<Channel> CleanChannelList(List<Channel> aChannels)
190 //Create our list of channels
191 List<Channel> channels = new List<Channel>();
193 foreach (Channel channel in aChannels)
195 Channel hdChannel = aChannels.Find(c => c.Name == channel.Name + " HD");
197 && !(channel.Name.Contains("Bundesliga") && !channel.Name.Contains("HD")) //We don't want non HD bundesliga
198 && !(channel.Name.StartsWith("Sky Sport") && !channel.Name.Contains("HD")) //We don't want non HD Sky Sport
201 //Patch some missing or bad categories
202 if (channel.Name.Contains("Bundesliga")
203 || channel.Name.Contains("Sport"))
205 channel.Category = "Sport";
208 if (channel.Name.Contains("Sky Select"))
210 channel.Category = "Pay per view";
214 if (channel.Name.StartsWith("Sky Atlantic")
215 || channel.Name.StartsWith("SyFy")
216 || channel.Name.StartsWith("Fox"))
218 channel.Category = "Series";
221 if (channel.Name.StartsWith("Sky 3D"))
223 channel.Category = "Movies";
226 //Collapse some categories
227 if (channel.Category == "Entertainment"
228 || channel.Category == "Music"
229 || channel.Name.Contains("Music"))
231 channel.Category = "General";
234 if (channel.Category == "Porn")
236 channel.Category = "Erotic";
239 if (channel.Category == "Presentations")
241 channel.Category = "News";
244 if (channel.Category == "History")
246 channel.Category = "Documentaries";
249 if (channel.Category == "Lifestyle")
251 channel.Category = "General";
254 //if (channel.Category == "Regional")
256 // channel.Category = "General";
259 if (channel.Category == "Other")
261 channel.Category = "General";
264 if (channel.Category == "Cultural")
266 channel.Category = "General";
270 //No corresponding HD channel, keep it then
271 channels.Add(channel);
275 Debug.Write("WARNING: Found HD channel for " + channel.Name + ". Discarding it!\n");