public static bool TryParseRawTime(string raw, out CourseSectionTime time) { time = new CourseSectionTime(); if (raw.Equals("TBA")) { time.MeetTimes = new List <CourseSectionTimeSpan>(); time.TBA = true; return(true); } if (!rawTimeRegex.IsMatch(raw)) { return(false); } List <CourseSectionTimeSpan> spans = new List <CourseSectionTimeSpan>(); foreach (Capture capture in rawTimeRegex.Match(raw).Groups["span"].Captures) { CourseSectionTimeSpan span; string rawSpan = capture.ToString(); if (!UTCourseSectionTimeSpan.TryParseRawTimeSpan(rawSpan, out span)) { return(false); } // Correct the abbreviation form, e.g. TF9 => T9F9 if (span.Start != 0 || span.End != 0) { for (int i = 0; i < spans.Count; i++) { CourseSectionTimeSpan prevSpan = spans[i]; if (prevSpan.Start == 0 && prevSpan.End == 0) { prevSpan.Start = span.Start; prevSpan.End = span.End; } spans[i] = prevSpan; } } spans.Add(span); } time.MeetTimes = spans; return(true); }
public override IEnumerable <UTCourse> FetchItems() { List <UTCourse> results = new List <UTCourse>(); this.Content = this.Content.Replace("\n", String.Empty).Replace("\r", String.Empty); MatchCollection courseMatches = TableRegex.Matches(this.Content); foreach (Match courseMatch in courseMatches) { UTCourse course = new UTCourse() { Department = this.Department, Code = courseMatch.Groups["code"].Value, SemesterPrefix = courseMatch.Groups["prefix"].Value, Semester = courseMatch.Groups["semester"].Value, Sections = new List <CourseSection>(), Campus = "UTM" }; Console.Write("UTM Course: " + course.Abbr); // Process name string name = HttpUtility.HtmlDecode(courseMatch.Groups["name"].Value).Replace("<esp233>", "é"); name = AngleRegex.Replace(name, String.Empty); if (name.Contains("SSc")) { course.AddCategory("SSc"); } if (name.Contains("SCI")) { course.AddCategory("SCI"); } if (name.Contains("HUM")) { course.AddCategory("HUM"); } course.Name = CircleRegex.Replace(name, String.Empty).Trim(' '); // Parse detail string[] details = AngleRegex.Replace(courseMatch.Groups["detail"].Value.Replace("<br>", "|"), String.Empty).Split('|'); course.Description = HttpUtility.HtmlDecode(details[0]).Replace("\t", String.Empty).Replace("Course Details", String.Empty).Trim(' '); foreach (string detail in details) { if (detail.StartsWith("Exclusion")) { course.Exclusions = detail.Substring("Exclusion: ".Length).Replace("\t", String.Empty); } else if (detail.StartsWith("Prerequisite")) { course.Prerequisites = detail.Substring("Prerequisites: ".Length).Replace("\t", String.Empty); } else if (detail.StartsWith("Corequisite")) { course.Corequisites = detail.Substring("Corequisites: ".Length).Replace("\t", String.Empty); } } // Process sections and meettime string courseContent = courseMatch.Groups["content"].Value; string[] sectionContents = courseContent.Replace("</tr>", "|").Split('|'); int nameColumn = 0, instructorColumn = 0, dayColumn = 0, startColumn = 0, endColumn = 0, locationColumn = 0; int count = 0; // Assign column number foreach (string column in AngleRegex.Replace(sectionContents[0].Replace("</th>", "|"), String.Empty).Split('|')) { string columnTrim = column.Trim(); switch (columnTrim) { case ("Section"): { nameColumn = count; break; } case ("Instructor"): { instructorColumn = count; break; } case ("Day"): { dayColumn = count; break; } case ("Start"): { startColumn = count; break; } case ("End"): { endColumn = count; break; } case ("Room"): { locationColumn = count; break; } } count++; } // Parse section foreach (string sectionContent in sectionContents) { UTCourseSection section = new UTCourseSection(); string[] meetTimeContent = sectionContent.Replace("</td>", "|").Split('|'); if (meetTimeContent.Length < 4) { continue; } string[] meetTimeTmp = meetTimeContent[dayColumn].Replace("\t", String.Empty).Replace(" ", String.Empty).Replace("<br>", "|").Split('|'); int meetTimeCount = 0; foreach (string meet in meetTimeTmp) { if (meet.Length > 0) { meetTimeCount += 1; } } // Pre-initialize the meet times CourseSectionTime time = new CourseSectionTime(); List <CourseSectionTimeSpan> meets = new List <CourseSectionTimeSpan>(); for (int i = 0; i < meetTimeCount; i++) { meets.Add(new CourseSectionTimeSpan()); } for (int i = 0; i < meetTimeContent.Length; i++) { // Section name if (i == nameColumn) { section.Name = AngleRegex.Replace(meetTimeContent[i], String.Empty).Trim(); } // Instructor else if (i == instructorColumn) { section.Instructor = AngleRegex.Replace(meetTimeContent[i].Replace("<br>", " "), String.Empty).Trim(); } // Day else if (i == dayColumn) { string[] days = AngleRegex.Replace(meetTimeContent[i].Replace("\t", String.Empty).Replace(" ", String.Empty).Replace("<br>", "|"), String.Empty).Split('|'); for (int j = 0; j < days.Length; j++) { if (days[j].Length == 0) { continue; } CourseSectionTimeSpan span = meets[j]; span.Day = UTMTimeParser.ParseDay(days[j]); meets[j] = span; } } // Start time else if (i == startColumn) { int meetCount = 0; foreach (string rawTime in AngleRegex.Replace(meetTimeContent[i].Replace("\t", String.Empty).Replace(" ", String.Empty).Replace("<br>", "|"), String.Empty).Split('|')) { if (rawTime.Length == 0) { continue; } byte startTime; UTCourseSectionTimeSpan.TryParseTimeSpanInt(rawTime, out startTime); CourseSectionTimeSpan span = meets[meetCount]; span.Start = startTime; meets[meetCount] = span; meetCount++; } } // End time else if (i == endColumn) { int meetCount = 0; foreach (string rawTime in AngleRegex.Replace(meetTimeContent[i].Replace("\t", String.Empty).Replace(" ", String.Empty).Replace("<br>", "|"), String.Empty).Split('|')) { if (rawTime.Length == 0) { continue; } byte endTime; UTCourseSectionTimeSpan.TryParseTimeSpanInt(rawTime, out endTime); CourseSectionTimeSpan span = meets[meetCount]; span.End = endTime; meets[meetCount] = span; meetCount++; } } // Location else if (i == locationColumn) { section.Location = AngleRegex.Replace(meetTimeContent[i].Replace("\t", String.Empty).Replace(" ", String.Empty).Replace("<br>", "|"), String.Empty).Replace("|", " ").Trim('\t'); } } time.MeetTimes = meets; section.ParsedTime = time; course.Sections.Add(section); Console.Write(" " + section.Name); } Console.WriteLine(); results.Add(course); } return(results); }
public override IEnumerable <UTCourse> FetchItems() { List <UTCourse> results = new List <UTCourse>(); int lineCount = 0; // Parse the csv file by line foreach (string line in this.Content.TrimStart('\n').Split('\n')) { lineCount++; if (lineCount == 1) { continue; } int columnCount = 0; UTCourse course = new UTCourse() { Campus = "UTSC" }; UTCourseSection courseSection = new UTCourseSection(); CourseSectionTimeSpan span = new CourseSectionTimeSpan(); MatchCollection lineMatches = CsvRegex.Matches(line); foreach (Match column in lineMatches) { string content = column.Value.Trim('\"'); switch (columnCount) { // Course code case (0): { Match codeMatch = CodeRegex.Match(content); course.Code = codeMatch.Groups["code"].Value; course.SemesterPrefix = codeMatch.Groups["prefix"].Value; course.Semester = codeMatch.Groups["semester"].Value; break; } // Section name case (1): { courseSection.Name = content; break; } // Day case (3): { span.Day = UTMTimeParser.ParseDay(content); break; } // Start time case (4): { byte start; UTCourseSectionTimeSpan.TryParseTimeSpanInt(content, out start); span.Start = start; break; } // End time case (5): { byte end; UTCourseSectionTimeSpan.TryParseTimeSpanInt(content, out end); span.End = end; break; } // Location case (6): { courseSection.Location = content.Replace(" ", String.Empty); break; } // Instructor case (7): { courseSection.Instructor = content; break; } default: { break; } } columnCount++; } if (String.IsNullOrEmpty(course.Abbr)) { continue; } // Check if it is the same course if (results.Count > 0) { UTCourse lastCourse = results.Last(); if (lastCourse.Abbr == course.Abbr) { UTCourseSection lastSection = lastCourse.Sections.Last() as UTCourseSection; // Check if it is the same section if (lastSection.Name == courseSection.Name) { // Add the meet time List <CourseSectionTimeSpan> meets = lastSection.ParsedTime.MeetTimes.ToList(); meets.Add(span); lastSection.ParsedTime = new CourseSectionTime(meets); String.Join(" ", lastSection.Location, courseSection.Location); continue; } else { // Add the course section List <CourseSectionTimeSpan> meets = new List <CourseSectionTimeSpan>(); meets.Add(span); courseSection.ParsedTime = new CourseSectionTime(meets); lastCourse.Sections.Add(courseSection); continue; } } } // Add the course List <CourseSectionTimeSpan> meets2 = new List <CourseSectionTimeSpan>(); meets2.Add(span); courseSection.ParsedTime = new CourseSectionTime(meets2); course.Sections.Add(courseSection); results.Add(course); } return(results); }
/// <summary> /// Parse the time format on UT artsci to CourseTimeSpan format /// </summary> /// <param name="rawSpan">e.g. "M2-4"</param> /// <returns>CourseTimeSpan Monday 28 32</returns> public static bool TryParseRawTimeSpan(string rawSpan, out CourseSectionTimeSpan span) { span = new CourseSectionTimeSpan(); if (!rawSpanRegex.IsMatch(rawSpan)) throw new ArgumentException("Fail to parse the span: " + rawSpan); Match match = rawSpanRegex.Match(rawSpan); // Process day DayOfWeek day; switch (match.Groups["day"].ToString()) { case "M": day = DayOfWeek.Monday; break; case "T": day = DayOfWeek.Tuesday; break; case "W": day = DayOfWeek.Wednesday; break; case "R": day = DayOfWeek.Thursday; break; case "F": day = DayOfWeek.Friday; break; default: return false; } span.Day = day; // Process time if (!String.IsNullOrEmpty(match.Groups["start"].ToString())) { byte startTime, endTime; if (!TryParseTimeSpanInt(match.Groups["start"].ToString(), out startTime)) return false; if (!String.IsNullOrEmpty(match.Groups["end"].ToString())) { if (!TryParseTimeSpanInt(match.Groups["end"].ToString(), out endTime)) return false; } else { endTime = (byte)(startTime + 4); if (endTime == 48) endTime = 0; } span.Start = To24HourTime(startTime, endTime == 36); span.End = To24HourTime(endTime, span.Start >= 52); } return true; }
/// <summary> /// Parse the time format on UT artsci to CourseTimeSpan format /// </summary> /// <param name="rawSpan">e.g. "M2-4"</param> /// <returns>CourseTimeSpan Monday 28 32</returns> public static bool TryParseRawTimeSpan(string rawSpan, out CourseSectionTimeSpan span) { span = new CourseSectionTimeSpan(); if (!rawSpanRegex.IsMatch(rawSpan)) { throw new ArgumentException("Fail to parse the span: " + rawSpan); } Match match = rawSpanRegex.Match(rawSpan); // Process day DayOfWeek day; switch (match.Groups["day"].ToString()) { case "M": day = DayOfWeek.Monday; break; case "T": day = DayOfWeek.Tuesday; break; case "W": day = DayOfWeek.Wednesday; break; case "R": day = DayOfWeek.Thursday; break; case "F": day = DayOfWeek.Friday; break; default: return(false); } span.Day = day; // Process time if (!String.IsNullOrEmpty(match.Groups["start"].ToString())) { byte startTime, endTime; if (!TryParseTimeSpanInt(match.Groups["start"].ToString(), out startTime)) { return(false); } if (!String.IsNullOrEmpty(match.Groups["end"].ToString())) { if (!TryParseTimeSpanInt(match.Groups["end"].ToString(), out endTime)) { return(false); } } else { endTime = (byte)(startTime + 4); if (endTime == 48) { endTime = 0; } } span.Start = To24HourTime(startTime, endTime == 36); span.End = To24HourTime(endTime, span.Start >= 52); } return(true); }