Skip to main content

lnu_elytra/
lib.rs

1//! [使用文档](https://lnu-elytra.mcitem.net)
2
3#[cfg(feature = "blocking")]
4pub mod blocking;
5
6#[cfg(feature = "__pyo3")]
7pub mod pyo3;
8
9#[cfg(feature = "__flutter")]
10pub mod flutter;
11
12mod course;
13mod error;
14mod method;
15mod utils;
16
17pub use course::{Course, Jxb};
18pub use error::Error;
19pub use method::SelectCourseResponse;
20
21use reqwest::Url;
22
23#[cfg(feature = "reqwest_cookie_store")]
24use {reqwest_cookie_store::CookieStoreRwLock, std::sync::Arc};
25
26use scraper::Selector;
27use std::{collections::HashMap, sync::LazyLock};
28
29#[derive(Debug)]
30pub struct Client {
31    base_url: Url,
32    client: reqwest::Client,
33    stores: HashMap<String, String>, // input[type="hidden"]
34    #[cfg(feature = "cookie_override")]
35    cookie_override: Option<String>, // 覆盖cookie
36    #[cfg(feature = "reqwest_cookie_store")]
37    pub cookie_store: Arc<CookieStoreRwLock>,
38}
39
40impl Client {
41    const LOGIN_URL: &str = "/xtgl/login_slogin.html";
42    const PUBLIC_KEY_URL: &str = "/xtgl/login_getPublicKey.html";
43
44    const SELECT_COURSE_URL: &str = "/xsxk/zzxkyzb_xkBcZyZzxkYzb.html?gnmkdm=N253512";
45    const SELECT_COURSE_HTML_URL: &str = "/xsxk/zzxkyzb_cxZzxkYzbIndex.html?gnmkdm=N253512";
46    const SELECT_COURSE_DISPLAY_URL: &str = "/xsxk/zzxkyzb_cxZzxkYzbDisplay.html?gnmkdm=N253512";
47    const SELECT_COURSE_PART_DISPLAY_URL: &str =
48        "/xsxk/zzxkyzb_cxZzxkYzbPartDisplay.html?gnmkdm=N253512";
49    const SELECT_COURSE_QUERY_DO_WITH_COURSE_ID_URL: &str =
50        "/xsxk/zzxkyzbjk_cxJxbWithKchZzxkYzb.html?gnmkdm=N253512";
51
52    const S_CSRFTOKEN: LazyLock<Selector> =
53        LazyLock::new(|| Selector::parse("#csrftoken").unwrap());
54    const S_SESSION_USER_KEY: LazyLock<Selector> =
55        LazyLock::new(|| Selector::parse("#sessionUserKey").unwrap());
56    const S_INPUT_HIDDENT: LazyLock<Selector> =
57        LazyLock::new(|| Selector::parse("input[type='hidden']").unwrap());
58    const S_INPUT_MMSFJM: LazyLock<Selector> =
59        LazyLock::new(|| Selector::parse("input[type='hidden'][name='mmsfjm']").unwrap());
60
61    pub fn new() -> Self {
62        Self::new_with_base(Url::parse("http://jw.lingnan.edu.cn").unwrap())
63    }
64
65    pub fn new_with_base(backend: Url) -> Self {
66        #[cfg(feature = "reqwest_cookie_store")]
67        let cookie_store = Arc::new(CookieStoreRwLock::default());
68
69        let client = reqwest::Client::builder();
70
71        #[cfg(not(feature = "reqwest_cookie_store"))]
72        let client = client.cookie_store(true);
73
74        #[cfg(feature = "reqwest_cookie_store")]
75        let client = client.cookie_provider(cookie_store.clone());
76
77        Self {
78            base_url: backend,
79            client: client.build().unwrap(),
80            stores: HashMap::new(),
81            #[cfg(feature = "cookie_override")]
82            cookie_override: None,
83            #[cfg(feature = "reqwest_cookie_store")]
84            cookie_store,
85        }
86    }
87
88    pub fn set_base(mut self, backend: Url) -> Self {
89        self.base_url = backend;
90        self
91    }
92}