/// <summary> /// Converts given ShedulePosition to datetime /// </summary> /// <param name="someDayOfWeek">Any day of desired week.</param> /// <returns></returns> public static DateTime ToDateTime(ShedulePosition input,DateTime someDayOfWeek) { DateTime monday = Helper.ToMonday(someDayOfWeek).AddDays(input.Day); monday = monday.AddHours(-1.0 * monday.Hour); monday = monday.AddMinutes(-1.0 * monday.Minute); if (input.Hour != 0) { int plusminutes = 0; monday = monday.AddMinutes((60 * 8)); for (int i = 0; i < input.Hour; i++) { if (i > 0) plusminutes += 55; if (i == 2) plusminutes += 10; } monday = monday.AddMinutes(plusminutes); } else { monday = monday.AddMinutes(7 * 60.0 + 5); } return monday; }
/// <summary> /// loads data from a specific existing session /// </summary> /// <param name="sessionId">ASP.NET_SessionId of a logged connection</param> /// <returns>user loaded from website</returns> public User Load(string sessionId) { if (string.IsNullOrWhiteSpace(sessionId)) throw new ArgumentException("sessionId cannot be empty!"); if (isDisposed) throw new ObjectDisposedException("API"); User user = new User(); _client.CookieContainer.GetCookies(new Uri(GradesUrl)).Add(new Cookie("ASP.NET_SessionId", sessionId)); string welcome=_client.GETRequest(CombineUrl("uvod.aspx")); CQ welcomeHtml = welcome;//todo:reset back string nameLabel = Helper.Decode( Helper.RemoveStartingWhitespaces( Helper.RemoveEndingWhitespaces( Helper.RemoveLineBreaks(welcomeHtml[".logjmeno"][0].InnerText) ) ) ); #region name formating string name; if (nameLabel.Contains(','))//remove the class name { name = nameLabel.Split(',')[0]; } else name = nameLabel; if (name.Contains(' '))//switch name and surename to friendlier form (Smith John > John Smith) { user.Name = name.Split(' ')[1] + " " + name.Split(' ')[0]; } else user.Name = name; #endregion //scrapping sequence string scheduleUrl = CombineUrl(welcomeHtml["#panelmenu > div > div:nth-child(4) > div > ul > li:nth-child(1) > a"][0]["href"]); string gradesUrl = CombineUrl(welcomeHtml["#panelmenu > div > div:nth-child(6) > div > ul > li:nth-child(1) > a"][0]["href"]); #region shedule scrapping NameValueCollection scheduleData = Client.GetFieldsFromHtml(_client.DownloadString(scheduleUrl)); scheduleData.Set("hlavnimenuSI", "3i0"); scheduleData.Set("ctl00$cphmain$radiorozvrh", "stálý rozvrh"); scheduleData.Set("ctl00$cphmain$Flyrozvrh$checkucitel", "on"); scheduleData.Set("ctl00$cphmain$Flyrozvrh$checkskupina", "on"); scheduleData.Set("ctl00$cphmain$Flyrozvrh$Checkmistnost", "on"); string scheduleHtml = _client.POSTRequest(scheduleUrl, scheduleData);//this is weekly schedule HTML user.Subjects = ParseSubjects(scheduleHtml); #endregion #region subjects' counts string countsHtml = _client.GETRequest(CombineUrl("prehled.aspx?s=9")); SetSubjectsCount(countsHtml, user.Subjects); #endregion #region grades NameValueCollection gradesData = Client.GetFieldsFromHtml(_client.GETRequest(gradesUrl)); gradesData.Set("ctl00$cphmain$Checkdetail", "on"); gradesData.Set("ctl00$cphmain$Flyout2$Checktypy", "on"); gradesData.Set("ctl00$cphmain$Flyout2$Checkdatumy", "on"); gradesData.Set("ctl00$cphmain$Flyout2$Checkprumery", "on"); gradesData.Set("ctl00$cphmain$Flyout2$checkpoznamky", "on"); gradesData.Set("hlavnimenuSI", "2i0"); string gradesHtml = _client.POSTRequest(gradesUrl, gradesData); SetGrades(gradesHtml, user); #endregion #region absences //list for storing mondays of each week we know that contains absences List<DateTime> weeklyAbsences = new List<DateTime>(); /* idea of monthly checks: it's not necessary to check every week in semester, when most of them should be empty. We'll save the weeks, which weren't empty and look up the absences note: this is slower for ppl with a lots of absences, but it's their problem, right? */ #region mothly checks //do not touch, optimisation is probably impossible! very fragile! #region getting the right values for monthly checks NameValueCollection absenceData = Client.GetFieldsFromHtml(_client.GETRequest(CombineUrl("prehled.aspx?s=3"))); absenceData.Set("ctl00$cphmain$listdobaoml", "zadané období"); absenceData.Set("ctl00$cphmain$listjakoml", "seznam"); absenceData = Client.GetFieldsFromHtml( _client.POSTRequest(CombineUrl("prehled.aspx?s=3"), absenceData)); absenceData.Set("ctl00$cphmain$listabsencedo", "daný měsíc"); absenceData.Set("ctl00$cphmain$listdobaoml", "zadané období"); absenceData.Set("ctl00$cphmain$listjakoml", "seznam"); #endregion //go through every month in semester and find weeks with absences foreach (DateTime monthDate in _absenceMonths) { string unixTime = Helper.ToUnixtime(monthDate).ToString() + "000"; absenceData.Set("cphmain_listabsenceod_Raw", unixTime); CQ monthlyAbsenceHtml = _client.POSTRequest(CombineUrl("prehled.aspx?s=3"), absenceData); CQ rows = monthlyAbsenceHtml[".omlseztab > tbody> tr.omlsezbody"]; string table = monthlyAbsenceHtml.RenderSelection(); for (int r = 0; r < rows.Length; r++)//go through each row of table. table represents month's days { CQ cells = ((CQ)rows[r].InnerHTML)["td"];//row cells for (int i = 0; i < cells.Length; i++) { if (i == 0)//first cell with date, we know the date from "r" and "date" continue; else if (i == 1)//shortened day of week, e.g. "po", "út"... continue; string cell = cells[i].InnerText; if (string.IsNullOrWhiteSpace(cell)) continue;//no absence for this cell //now we know there's an absence DateTime mondayOfCheckedWeek = Helper.ToMonday(new DateTime(monthDate.Year, monthDate.Month, r + 1)); bool contains = weeklyAbsences.Contains(mondayOfCheckedWeek); if (!contains) weeklyAbsences.Add(mondayOfCheckedWeek);//we'll check this week later break; } } } #endregion #region weekly checks //look up every week we know that contains absences and save 'em NameValueCollection weeklyAbsenceData = Client.GetFieldsFromHtml(_client.GETRequest(CombineUrl("prehled.aspx?s=3"))); weeklyAbsenceData.Set("ctl00$cphmain$Flyoutoml$Checkomlpredmety", "on"); weeklyAbsenceData.Set("ctl00$cphmain$listdobaoml", "zadané období"); weeklyAbsenceData.Set("ctl00$cphmain$listjakoml", "tabulka"); weeklyAbsenceData = Client.GetFieldsFromHtml( _client.POSTRequest(CombineUrl("prehled.aspx?s=3"), weeklyAbsenceData)); weeklyAbsenceData.Set("ctl00$cphmain$listabsencedo", "daný týden"); weeklyAbsenceData.Set("ctl00$cphmain$Flyoutoml$Checkomlpredmety", "on"); weeklyAbsenceData.Set("ctl00$cphmain$listdobaoml", "zadané období"); weeklyAbsenceData.Set("ctl00$cphmain$listjakoml", "tabulka"); foreach (DateTime weekDate in weeklyAbsences) { string unix = Helper.ToUnixtime(weekDate).ToString() + "000"; weeklyAbsenceData.Set("cphmain_listabsenceod_Raw", unix); CQ weeklyAbsencesHtml = _client.POSTRequest(CombineUrl("prehled.aspx?s=3"), weeklyAbsenceData); //select even rows with subject's name inside CQ s_rows = weeklyAbsencesHtml["#trozvrh > table > tbody > tr:nth-child(even)"]; //select odd rows with images to find out the absence's type CQ i_rows = weeklyAbsencesHtml["#trozvrh > table > tbody > tr:nth-child(odd)"]; for (int row = 0; row < 5; row++) { for (int col = 0; col < 15; col++) { //the cell with possible name of subject IDomObject s_cell=Cq(s_rows[row + 1])["td"][col]; //name of subject for abs, long string subjName = s_cell.HasAttribute("title") ? s_cell["title"] : null; if (!string.IsNullOrWhiteSpace(subjName))//there's an absence { //the source of image IDomObject i_cell = Cq(i_rows[row + 1])["td"][col+1]; IDomObject img = Cq(i_cell)["img"][0]; string imgSrc = img["src"]; Absence.EType absType;//type of current absence if (imgSrc.Contains("wAbOk.gif")) absType = Absence.EType.Execused; else if (imgSrc.Contains("wAbsent.gif")) absType = Absence.EType.YetUnexecused; else if (imgSrc.Contains("wAbMiss.gif")) absType = Absence.EType.Unexecused; else if (imgSrc.Contains("wAbSoon.gif")) absType = Absence.EType.Early; else if (imgSrc.Contains("wAbLate.gif")) absType = Absence.EType.Late; else absType = Absence.EType.Uncountable; ShedulePosition pos = new ShedulePosition(row, col); Absence newAbsence = new Absence { Type = absType, Time = ShedulePosition.ToDateTime(pos, weekDate) }; var query = from q in user.Subjects where q.Info.LongName == subjName select q.Absences; if (query.Any()) { query.First().Add(newAbsence); } else Debug.WriteLine("no matching subject found for '" + subjName + "'"); } } } } weeklyAbsenceData.Set("cphmain_listabsenceod_Raw", ""); #endregion #endregion return user; }
public static ShedulePosition FromDatetime(DateTime input) { ShedulePosition res = new ShedulePosition(); int days; switch (input.DayOfWeek) { case DayOfWeek.Monday: days = 0; break; case DayOfWeek.Tuesday: days = 1; break; case DayOfWeek.Wednesday: days = 2; break; case DayOfWeek.Thursday: days = 3; break; case DayOfWeek.Friday: days = 4; break; case DayOfWeek.Saturday: days = 5; break; case DayOfWeek.Sunday: days = 6; break; default: days = 0; break; } int hour = 0; DateTime dayZeroHour = new DateTime(input.Year, input.Month, input.Day, 7, 5, 0); for (int i = 0; i < 15; i++) { int plusMinutes = i * 55; if (i >= 2) plusMinutes += 10; if (input >= dayZeroHour.AddMinutes(plusMinutes) && input < dayZeroHour.AddMinutes(plusMinutes + 45)) { hour = i; } if (input.Hour == 8 && input.Minute == 55) { hour = 2; break; } } res.Hour = hour; res.Day = days; return res; }