manaba_sdk/scrape/
exam.rs1use crate::Client;
2use crate::assignment::{AssignmentDate, AssignmentState};
3use crate::{Course, error::Result};
4use reqwest::Method;
5use scraper::Selector;
6
7pub struct Exam {
8 pub title: String,
9 pub state: AssignmentState,
10 pub start_date: Option<AssignmentDate>,
11 pub due_date: Option<AssignmentDate>,
12}
13
14impl Client {
15 pub async fn get_exams(&self, course: &Course) -> Result<Vec<Exam>> {
16 let url = format!("{}_query", course.id);
17 let html = self.get_html(Method::GET, url).await?;
18
19 let selector = Selector::parse("table.stdlist tr:not(.title)").unwrap();
20 let exam_element = html.select(&selector);
21
22 let exams = exam_element
23 .map(|report_element| {
24 let selector = Selector::parse("td").unwrap();
25 let mut rows = report_element.select(&selector);
26
27 let title = {
28 let row = rows.next().unwrap();
29 let selector = Selector::parse("a").unwrap();
30 let report_title_element = row.select(&selector).next().unwrap();
31 report_title_element.inner_html()
32 };
33
34 let state = {
35 let row = rows.next().unwrap();
36 let selector = Selector::parse("strong").unwrap();
37
38 if row.select(&selector).next().is_some() {
39 AssignmentState::Done
40 } else {
41 AssignmentState::Todo
42 }
43 };
44
45 let start_date = {
46 let row = rows.next().unwrap();
47 let date = row.inner_html();
48 if date.is_empty() {
49 None
50 } else {
51 Some(AssignmentDate::new(&date))
52 }
53 };
54
55 let due_date = {
56 let row = rows.next().unwrap();
57 let date = row.inner_html();
58 if date.is_empty() {
59 None
60 } else {
61 Some(AssignmentDate::new(&date))
62 }
63 };
64
65 Exam {
66 title,
67 state,
68 start_date,
69 due_date,
70 }
71 })
72 .collect::<Vec<Exam>>();
73
74 Ok(exams)
75 }
76}