1use crate::error::{ManabaError, Result};
2use reqwest::{IntoUrl, Method, RequestBuilder, header::HeaderMap};
3use scraper::{Html, Selector};
4use std::fmt::Display;
5
6pub struct Client {
7 pub base_url: String,
8 pub(crate) reqwest_client: reqwest::Client,
9 pub(crate) headers: HeaderMap,
10}
11
12impl Client {
13 pub async fn new(base_url: &str, cookie: &str) -> Result<Self> {
14 let reqwest_client = reqwest::Client::builder().build().unwrap();
15
16 let headers = {
17 let mut headers = HeaderMap::new();
18 headers.insert("Cookie", cookie.parse().unwrap());
19 headers
20 };
21
22 let client = Client {
23 base_url: base_url.to_owned(),
24 reqwest_client,
25 headers,
26 };
27
28 if client.is_valid_cookie().await? {
29 Ok(client)
30 } else {
31 Err(ManabaError::InvalidCookie)
32 }
33 }
34
35 pub(crate) fn request(&self, method: Method, url: impl IntoUrl + Display) -> RequestBuilder {
36 self.reqwest_client
37 .request(method, format!("{}/{}", self.base_url, url))
38 .headers(self.headers.clone())
39 }
40
41 pub async fn is_valid_cookie(&self) -> Result<bool> {
42 let request = self.request(reqwest::Method::GET, "");
43
44 let response = request
45 .send()
46 .await
47 .map_err(ManabaError::SendRequestError)?;
48
49 let body = response
50 .text()
51 .await
52 .map_err(ManabaError::HtmlBodyParseError)?;
53
54 let document = Html::parse_document(&body);
55
56 let selector = Selector::parse("div#orgheader").unwrap();
57 let elements = document.select(&selector);
58
59 Ok(elements.count() != 0)
60 }
61}