manaba_sdk/scrape/
report.rs

1use crate::assignment::{AssignmentDate, AssignmentState};
2use crate::error::Result;
3use crate::{Client, Course};
4use scraper::Selector;
5
6#[derive(Debug)]
7pub struct Report {
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_reports(&self, course: &Course) -> Result<Vec<Report>> {
16        let url = format!("{}_report", course.id);
17        let html = self.get_html(reqwest::Method::GET, url).await?;
18
19        let selector = Selector::parse("table.stdlist tr:not(.title)").unwrap();
20        let reports_element = html.select(&selector);
21
22        let reports = reports_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                Report {
66                    title,
67                    state,
68                    start_date,
69                    due_date,
70                }
71            })
72            .collect::<Vec<Report>>();
73
74        Ok(reports)
75    }
76}