/// <summary> /// Scrape the list of /// </summary> /// <param name="classRoomRepository"></param> /// <param name="bookingRepository"></param> /// <param name="week">The week of the year (1-51)</param> /// <returns></returns> public async Task <List <Classroom> > Execute(int week) { try { var logger = LogManager.GetLogger("Scraper"); var startTimeScrape = DateTime.UtcNow; logger.Info($"=== Scraper Started at {startTimeScrape} ==="); var rooms = ClassroomRepository.GetAllClassrooms().ToList(); var startDate = TimeConversion.FirstDateOfWeekIso8601(DateTime.Today.Year, week); var endDate = startDate.AddDays(4); var secret = WebConfigurationManager.AppSettings["Hint.Api.Secret"]; logger.Info($"Scraping {rooms.Count} rooms"); foreach (var room in rooms) { logger.Info($"Starting scraping room {room.RoomId} ({rooms.IndexOf(room)}/{rooms.Count}"); //Format the request for the HINT API var roomName = room.RoomId; var start = $"{startDate.Year}-{startDate.Month:00}-{startDate.Day:00}"; var end = $"{endDate.Year}-{endDate.Month:00}-{endDate.Day:00}"; var url = string.Format(BaseUrl, secret, roomName, start, end); //Prepare Client & Send Request var client = new HttpClient(); var request = client.GetAsync(new Uri(url)).Result; if (!request.IsSuccessStatusCode) { continue; } //Read the response of the page var data = await request.Content.ReadAsStringAsync(); ScraperClassroom classroom; try { classroom = JsonConvert.DeserializeObject <ScraperClassroom>(data); } //Should only happen when the lesson is not an array but one lesson catch (JsonSerializationException ex) { logger.Error($"Failed scraping {room.RoomId}", ex); continue; } //Find the classroom that is connected the one being scraped var existingClassroom = ClassroomRepository.GetClassroomWithCourses(classroom.ElementName); logger.Info($"Found {classroom.Lesson.Count} lessons for {room.RoomId}"); //For each lesson that is in the classroom from the API foreach (var course in classroom.Lesson) { //Find an existing lesson or booking during these times var availability = FindExisting(week, room, course); switch (availability) { case Availability.Free: var updatedClassroom = MapCourse(course, existingClassroom, week); ClassroomRepository.AddOrUpdateClassroom(updatedClassroom); break; case Availability.Booked: //TODO: Geboekt, maar nieuwe officiele les op dat moment break; case Availability.Duplicate: //double scrape break; default: throw new ArgumentOutOfRangeException(); } } } var endTimeScrape = DateTime.UtcNow; logger.Info($"Scraping finished at {endTimeScrape}"); logger.Info($"Scraping took {(endTimeScrape-startTimeScrape).TotalSeconds}s"); return(rooms); } catch (Exception e) { return(null); } }