예제 #1
0
파일: API.cs 프로젝트: czubehead/Bigybox
		private static void SetGrades(string HTMLdom, User user)
		{
			if (user.Subjects.Count > 0)
			{
				CQ dom = HTMLdom;
				CQ HTMLtable = dom[".dettable tbody"].RenderSelection();

				List<string> lines = new List<string>();

				int i = 0;
				while (true)
				{
					try
					{
						lines.Add(HTMLtable.Select("tr")[i].InnerHTML);
						i++;
					}
					catch { break; }
				}

				string currentSubj = "";

				foreach (string line in lines)
				{
					CQ CQline = line;
					string strmark = CQline["td:nth-child(2)"].Text().Replace(" ", "");
					double dblmark;

					string type = WebUtility.HtmlDecode(CQline[".dettyp"].Text().Replace(" ", ""));
					if (type == "C")
						type = "10";

					int weight = int.Parse(type, CultureInfo.InvariantCulture);
					string[] strdate = (CQline[".detdatum"].Text().Replace(" ", "")).Split('.');

					DateTime date = new DateTime((int.Parse(strdate[2], CultureInfo.InvariantCulture) + 2000), int.Parse(strdate[1], CultureInfo.InvariantCulture), int.Parse(strdate[0], CultureInfo.InvariantCulture));
					string label = WebUtility.HtmlDecode(CQline[".detcaption"].Text());
					string detail = WebUtility.HtmlDecode(CQline[".detpozn2"].Text().Replace("(", "").Replace(")", ""));

					if (strmark.ToUpper(CultureInfo.InvariantCulture).Contains("N"))
					{
						dblmark = 0.0;
					}
					else if (strmark.Contains("-"))
					{
						dblmark = double.Parse((strmark.Replace("-", ".5")), CultureInfo.InvariantCulture);
					}
					else
					{
						dblmark = double.Parse(strmark.Replace(" ", ""), CultureInfo.InvariantCulture);
					}

					if (!string.IsNullOrEmpty((CQline[".detpredm"].Text())))
					{
						currentSubj = CQline[".detpredm"].Text();
					}

					var query = from q in user.Subjects
								 where (q.Info.LongName == currentSubj)
								 select q;

					Grade grade = new Grade
					{
						Time = date,
						Detail = detail,
						Name = label,
						Value = dblmark,
						Weight = weight
					};

					if (query.Any())
					{
						Subject parent = query.First();
						parent.Grades.Add(grade);
					}
				}
			}
		}
예제 #2
0
파일: API.cs 프로젝트: czubehead/Bigybox
		/// <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;
		}