public Schedule_MatchUp( int _index, DateTime _date, Game _game, string _title = "MatchUp", Categories _category = Categories.MATCHUP, ScheduleCategory _schedules = ScheduleCategory.MATCHUP, string _desc = "" ) : base(_index, _date, _title, _category, _schedules, _desc) { description = "We have a match on " + date.ToString("MMM dd", CultureInfo.CreateSpecificCulture("en-US")) + "."; isSelectable = false; game = _game; if (game.home == Values.myTeam) { enemy = game.away; } else { enemy = game.home; } }
/// <summary> /// Translate nodes to items /// </summary> /// <param name="nodes"></param> /// <param name="category"></param> /// <returns></returns> public static List <Item> NodesToItems(ScheduleCategory category, HtmlNodeCollection nodes) { //If there are no nodes then there is no list if (nodes == null) { return(null); } List <Item> items = new List <Item>(); //Translate nodes to items and add them to the list foreach (var node in nodes) { //Skip items with invalid id int id = -1; if (!int.TryParse(node.Id, out id)) { continue; } Item item = new Item(); item.Id = id; item.Name = node.InnerText; item.Category = category; item.HasSchedule = false; items.Add(item); } return(items); }
public async Task <List <Item> > GetItemContentsAsync(int item_id, ScheduleCategory category) { //Get the document containing wanted items string url = $@"https://plan.polsl.pl/left_menu_feed.php?type={(int)category}&branch={item_id}"; HtmlDocument doc = await GetDocument(url, Encoding.UTF8); //Get items with no specific schedule as HTMLnodes var nodes = doc.DocumentNode.SelectNodes(@"//li[@class='closed']"); //If these were found then translate them to list of items and return if (nodes != null) { return(NodeAnalyzer.GetItemsFromNodesWithoutSchedule(category, nodes)); } //Otherwise find items that have a specific schedule nodes = doc.DocumentNode.SelectNodes(@"//li"); //If these were found then translate them to list of items and return if (nodes != null) { return(NodeAnalyzer.GetItemsFromNodesWithSchedule(category, nodes)); } //If no items were found return null return(null); }
//member functions public Schedule(int _index, DateTime _date, string _title, Categories _category, ScheduleCategory _schedules, string _desc, bool hasComponent = false) { index = _index; date = _date; title = _title; category = _category; scheduleCategory = _schedules; description = _desc; }
public Schedule_Test_noSelect(int _index, DateTime _date, string _title = "Test schedule without items.", Categories _category = Categories.TESTING, ScheduleCategory _schedules = ScheduleCategory.TESTING_NOSELECT, string _desc = "") : base(_index, _date, _title, _category, _schedules, _desc) { description = "Hey, this is just a sample testing schedule in " + date.ToString("MMM dd", CultureInfo.CreateSpecificCulture("en-US")) + ", without selectable items!"; isSelectable = false; }
public ScheduleUnit GetScheduleUnit(WeekDay day, TimeSlot slot, ScheduleCategory category = ScheduleCategory.Default) { if (dailyData.TryGetValue(day, out DailyScheduleData daily)) { if (daily.data.TryGetValue(slot, out ScheduleUnitData unitData)) { return(unitData.units.TryGetValue(category, out ScheduleUnit res) ? res : null); } } return(null); }
public async Task <List <Item> > GetMainItemsOfCategoryAsync(ScheduleCategory category) { List <Item> items = new List <Item>(); //Get the document with the items string url = $@"https://plan.polsl.pl/left_menu.php?type={(int)category}"; HtmlDocument doc = await GetDocument(url, Encoding.GetEncoding("iso-8859-2")); //Get the node with the items var main_tree_node = doc.DocumentNode.SelectSingleNode(@"//ul[@class='main_tree']"); //Return items translated from nodes return(NodeAnalyzer.NodesToItems(category, main_tree_node.ChildNodes)); }
/// <summary> /// Translates node collection to list of items with a schedule /// </summary> /// <param name="category">Category of items</param> /// <param name="nodes"></param> /// <returns></returns> public static List <Item> GetItemsFromNodesWithSchedule(ScheduleCategory category, HtmlNodeCollection nodes) { //No nodes means no items if (nodes == null) { return(null); } List <Item> items = new List <Item>(); //For each node create an item foreach (var node in nodes) { //Extract hyperlink associated with nodes var hyperlink_node = node.Descendants().Single(n => n.Name == "a"); //Extract query string from hyperlink var link = hyperlink_node.Attributes.AttributesWithName("href").Single(); var parsed_query_string = HttpUtility.ParseQueryString(link.Value); //Parse id to int int id = -1; if (!int.TryParse(parsed_query_string.Get("amp;id"), out id)) { continue; } //Extract name byte[] bytes = Encoding.UTF8.GetBytes(node.InnerText); //Create item Item item = new Item() { Id = id, HasSchedule = true, Category = category, Name = Encoding.UTF8.GetString(bytes) }; items.Add(item); } return(items); }
public Schedule_Test_WithComponents(int _index, DateTime _date, string _title = "Test schedule with components.", Categories _category = Categories.TESTING, ScheduleCategory _schedules = ScheduleCategory.TESTING_WITHCOMPONENT, string _desc = "") : base(_index, _date, _title, _category, _schedules, _desc, true) { description = "Hey, this is just a sample testing schedule in " + date.ToString("MMM dd", CultureInfo.CreateSpecificCulture("en-US")) + ", with some components!"; items = new string[] { "Say hello to my friend.", "This is a test schedule item.", "Yes, of course you can.", "Sorry, better next time.", "I'm really disappointed with that." }; isSelectable = true; }
/// <summary> /// Translates node collection to list of items without a schedule /// </summary> /// <param name="category">Category of items</param> /// <param name="nodes"></param> /// <returns></returns> public static List <Item> GetItemsFromNodesWithoutSchedule(ScheduleCategory category, HtmlNodeCollection nodes) { //No nodes no items if (nodes == null) { return(null); } List <Item> items = new List <Item>(); foreach (var node in nodes) { //Get id from node as string var img_child_node = node.FirstChild; var tmp_string = img_child_node?.Id == null ? "" : img_child_node.Id; var id_as_string = Regex.Replace(tmp_string, "[^0-9.]", ""); //Skip items with invalid id int id = -1; if (!int.TryParse(id_as_string, out id)) { continue; } //Extract name byte[] bytes = Encoding.UTF8.GetBytes(node.InnerText); //Create item Item item = new Item() { Id = id, Category = category, HasSchedule = false, Name = Encoding.UTF8.GetString(bytes), }; items.Add(item); } return(items); }
public static List <ScheduleItem> GetScheduleInfoFromNodes(ScheduleCategory category, HtmlNodeCollection nodes) { List <ScheduleItem> items = new List <ScheduleItem>(); foreach (var node in nodes) { var children = node.Descendants(); var text_children = children.Where(child => child.Name == "#text" && !string.IsNullOrWhiteSpace(child.InnerText)).ToList(); if (text_children.Count == 0) { continue; } var current_child = text_children.First(); #region Extract abbreviation and type //Extract abbreviation and the type of item string abrrev_and_type = current_child.InnerText; //Find separator int coma_pos = abrrev_and_type.LastIndexOf(','); if (coma_pos < 0) { continue; } //Get abbreviation string abbrev = abrrev_and_type.Substring(0, coma_pos); //Get type string type_as_string = abrrev_and_type.Substring(coma_pos + 2); var type = Translator.TranslateAbbrevToItemType(type_as_string); //Remove child as it's content was analyzed text_children.Remove(current_child); #endregion #region Extract rooms, teachers and groups //Get nodes that are hyperlinks (these are either a teacher, a room or a group) var rooms_teachers_groups = children.Where(child => child.Name == "a"); //Define lists for storing content associated with schedule item List <string> teachers = new List <string>(); List <string> rooms = new List <string>(); List <string> groups = new List <string>(); //Add teachers and room to item foreach (var child in rooms_teachers_groups) { //Query string of the link contains information whether content is a room or a teacher string link = child.Attributes["href"].Value; string query_str = link.Substring(link.IndexOf('?') + 1); var parsed = HttpUtility.ParseQueryString(query_str); switch (parsed["type"]) { case "0": //Child is representing a group groups.Add(child.InnerText); break; case "10": //Child is representing a teacher teachers.Add(child.InnerText); break; case "20": //Child is representing a room rooms.Add(child.InnerText); break; default: break; } //Remove any children of just processed child text_children.RemoveAll(txt_child => child.ChildNodes.Contains(txt_child)); } #endregion #region Extract additional info string additional_info = string.Empty; //Any text content that wasn't processed earlier belongs to additional information while (text_children.Count > 0) { var child = text_children.First(); additional_info += child.InnerText; text_children.Remove(child); } #endregion #region Extract day, parity and time //The style of the div contains position of the item which can be converted to day and time of the course string style = node.Attributes["style"].Value; //Find position attributes in format attribute: value Regex regex = new Regex(@"\w{1,}: \d{1,}"); var matches = regex.Matches(style); int width = -1; int height = -1; int xpos = -1; int ypos = 1; //Extract values for the attributes above foreach (Match match in matches) { //Get position of semicolon int semicolon_pos = match.Value.IndexOf(':'); //Extract string key = match.Value.Substring(0, semicolon_pos); //Extract value //Skip on failure int value = -1; if (!int.TryParse(match.Value.Substring(semicolon_pos + 2), out value)) { continue; } //Assign value to corresponding key switch (key) { case "width": width = value; break; case "height": height = value; break; case "left": xpos = value; break; case "top": ypos = value; break; default: break; } } //Calculate position of item in amount of fields int amount_left = (xpos - 88) / 131; int amount_top = Convert.ToInt32((Convert.ToDouble(ypos) - 236.5) / 11.3); int amount_height = Convert.ToInt32(Math.Round(Convert.ToDouble(height) / 10.0)); int amount_width = width / 119; Parity parity; //Extract parity depending on width of block and position if (amount_width == 1) { parity = (Parity)(amount_left % 2); } else { parity = Parity.Both; } //Convert from number to DayOfWeek var day = (DayOfWeek)((amount_left / 2 + 1) % 7); //Convert from position to time var starting_time = new DateTime(1, 1, 1, 7, 0, 0) + TimeSpan.FromMinutes(15 * amount_top); var ending_time = new DateTime(1, 1, 1, 7, 0, 0) + TimeSpan.FromMinutes(15 * (amount_top + amount_height)); #endregion #region Assign extracted data ScheduleItem item; //Add a schedule item to list with extracted content switch (category) { case ScheduleCategory.Groups: //Item for group schedule item = new GroupsScheduleItem() { Teachers = teachers, Rooms = rooms }; break; case ScheduleCategory.Teachers: //Item for teacher schedule item = new TeachersScheduleItem() { Groups = groups, Rooms = rooms }; break; case ScheduleCategory.Rooms: //Item for room schedule item = new RoomsScheduleItem() { Groups = groups, Teachers = teachers }; break; default: //Improper value of category return(null); } //Assign common data item.Abbrev = abbrev; item.Type = type; item.Day = day; item.Parity = parity; item.StartingTime = starting_time; item.EndingTime = ending_time; item.AdditionalInfo = additional_info; #endregion items.Add(item); } return(items); }
public async Task <Tuple <string, List <ScheduleItem> > > GetScheduleInfoAsync(int id, ScheduleCategory category, Semester semester, CancellationToken ct) { //Get document with schedule string url = $@"https://plan.polsl.pl/plan.php?type={(((int)category - 1) * 10)}&id={id}&winW=2000&winH=1000&wd={(int)semester}"; HtmlDocument doc = await GetDocument(url, Encoding.GetEncoding("iso-8859-2")); //Check if task is canceled and exit task if true ct.ThrowIfCancellationRequested(); lock (_lock) { //Get title of the schedule var title_node = doc.DocumentNode.SelectSingleNode(@"/html[1]/body[1]/div[3]/div[1]"); string title = title_node?.InnerText.Trim(); //Get nodes representing courses var nodes = doc.DocumentNode.SelectNodes(@"//div[@class='coursediv']"); if (nodes == null) { return(new Tuple <string, List <ScheduleItem> >(title, null)); } //Get node containing legend var legend_node = doc.DocumentNode.SelectSingleNode(@"//div[@class='data']"); //Get legend var legend = NodeAnalyzer.MapLegend(legend_node); //Get appropriate schedule items depending on the category List <ScheduleItem> items = NodeAnalyzer.GetScheduleInfoFromNodes(category, nodes); //Map full names to abbrev of the items foreach (var item in items) { var name = ""; if (!legend.TryGetValue(item.Abbrev, out name)) { continue; } item.Name = name; } return(new Tuple <string, List <ScheduleItem> >(title, items)); } }