Example #1
0
        /// <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);
            }
        }