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