1use color_eyre::{Result, eyre::bail};
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 bail!("Cookie is invalid");
30 }
31
32 Ok(client)
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) -> bool {
42 let request = self.request(reqwest::Method::GET, "");
43
44 let result: Result<()> = async {
45 let response = request.send().await?;
46 let body = response.text().await?;
47 let document = Html::parse_document(&body);
48
49 let selector = Selector::parse("div#orgheader").unwrap();
50 let elements = document.select(&selector);
51
52 if elements.count() == 0 {
53 bail!("")
54 }
55
56 Ok(())
57 }
58 .await;
59
60 result.is_ok()
61 }
62}