public CourseResultModel CreateCourseFromHtml(IEnumerable <IElement> html, CourseModel c) { string[] courseInfo = html.ElementAt(0).TextContent.Split(" - "); string creditHours = html.ElementAt(1).TextContent.Split('\n').Where(s => s.Contains("Credits")).ElementAt(0).Trim().Remove(5); IElement[] courseDetailsElements = html.ElementAt(1).GetElementsByTagName("tr").Skip(1).ToArray(); List <string> times = new List <string>(); List <string> inst = new List <string>(); List <string> days = new List <string>(); List <string> locations = new List <string>(); for (int i = 0; i < courseDetailsElements.Length; i++) { string[] crseDetails = courseDetailsElements.ElementAt(i).TextContent.Split('\n'); times.Add(crseDetails[2]); if (crseDetails[2] == " ") { crseDetails[2] = "N/A"; } days.Add(crseDetails[3]); locations.Add(crseDetails[4]); inst.Add(crseDetails[7].Replace("(P)", "")); } var courseResult = new CourseResultModel(c); if (courseInfo[0].Contains(':')) { var fullTitle = courseInfo[0].Trim('\n', ' ').Split(":"); courseResult.Topic = fullTitle[1].Trim(); } courseResult.CourseRegistrationNum = courseInfo[1].Trim(); courseResult.Section = courseInfo[3].Trim(); courseResult.Instructor = inst.Select(x => x.Trim()).FirstOrDefault(); courseResult.CreditHours = creditHours; courseResult.Meetings = ParseCourseMeetingInformation(days, locations, times); return(courseResult); }
private async Task <CourseResultList> GetCourses(CourseModel courseModel, string termId) { CourseResultList courseRes = new CourseResultList(courseModel); //Check for cache, it if exists...just get current seat count. string cacheId = $"{termId}.{courseModel.SubjectCode}{courseModel.CourseNumber}"; if (this.CachedCourses.TryGetValue <CourseResultList>(cacheId, out _)) { courseRes = this.CachedCourses.Get <CourseResultList>(cacheId); for (int i = 0; i < courseRes.Results.Count; i++) { (int remainingSeats, int remainingWaitlist)seatData = await GetSeatCapacities(courseRes.Results[i].CourseRegistrationNum, termId); courseRes.Results[i].RemainingSeats = seatData.remainingSeats; courseRes.Results[i].RemainingWaitlist = seatData.remainingWaitlist; } return(courseRes); } List <KeyValuePair <string, string> > values = BannerQueryValues.GetKeyValues(termId, courseModel.SubjectCode, courseModel.CourseNumber); HttpContent content = new FormUrlEncodedContent(values); HttpResponseMessage result = await this.Client.PostAsync("bwckschd.p_get_crse_unsec", content); var html = await result.Content.ReadAsStringAsync(); var htmlDoc = await BrowsingContext.New(Configuration.Default.WithXPath()).OpenAsync(req => req.Content(html)); if (result.IsSuccessStatusCode) { try { var trows = htmlDoc.QuerySelectorAll("*[xpath>'/body/div[3]/table[1]/tbody/tr']").ToList(); for (int i = 0; i < trows.Count(); i += 2) { //Collecting and Parsing all the data required to make a CourseResult object var courseRows = trows.Skip(i).Take(2); CourseResultModel courseResult = this.CourseResultModelFactory.CreateCourseFromHtml(courseRows, courseModel); (int remainingSeats, int remainingWaitlist)seatData = await GetSeatCapacities(courseResult.CourseRegistrationNum, termId); courseResult.RemainingSeats = seatData.remainingSeats; courseResult.RemainingWaitlist = seatData.remainingWaitlist; courseRes.Results.Add(courseResult); } courseRes.Results.OrderByDescending(x => x.RemainingSeats).ThenBy(x => x.Section).ToList(); this.CachedCourses.Set(cacheId, courseRes, TimeSpan.FromDays(15)); } catch { Logger.LogInformation($"Match not found for {courseModel.SubjectCode} {courseModel.CourseNumber}."); this.CachedCourses.Set(cacheId, courseRes, TimeSpan.FromDays(15)); } } else { Logger.LogWarning($"Banner responded with a {result.StatusCode} while searching for {courseModel.SubjectCode} {courseModel.CourseNumber}."); } return(courseRes); }