use std::collections::HashMap;
use crate::cache::Store;
use crate::parser::Parser;
use crate::untils::headers::Headers;
use crate::untils::proxies::Proxies;
use crate::value::Value;
use reqwest::blocking::Client;
use select::document::Document;
pub struct Requests<'a, T> {
pub text: String, pub url: &'a str,
store: &'a T,
headers: Headers,
proxies: Proxies,
}
impl<'a, T> Requests<'a, T>
where
T: Store,
{
pub fn new(store: &'a T) -> Requests<T> {
Requests {
text: "".to_string(),
url: "",
store,
headers: Headers::None,
proxies: Proxies::None,
}
}
pub fn parser<F>(&self, parser_call: F, key: &str) -> &T
where
F: Fn(Parser) -> Value,
{
let document = Document::from(self.text.as_str());
let mut parser = Parser::new(&document);
parser.defined_css_processes();
let result = parser_call(parser);
self.store.pipes(key, result);
self.store
}
pub fn free_parse<F>(&self, parse_call: F)
where
F: Fn(Parser),
{
let document = Document::from(self.text.as_str());
let mut parser = Parser::new(&document);
parser.defined_css_processes();
parse_call(parser)
}
pub fn default_headers(&self) -> Self {
Self {
text: self.text.clone(),
url: self.url,
store: self.store,
headers: Headers::Default,
proxies: self.proxies,
}
}
pub fn connect(&self, url: &'a str) -> Self {
Self {
text: self.text.clone(),
url,
store: self.store,
headers: self.headers,
proxies: self.proxies,
}
}
pub fn headers(&self, headers: &'static str) -> Self {
Self {
text: self.text.clone(),
url: self.url,
store: self.store,
headers: Headers::JSON(headers),
proxies: self.proxies,
}
}
pub fn proxies(&self, proxies: &'static str) -> Self {
Self {
text: self.text.clone(),
url: self.url,
store: self.store,
headers: self.headers,
proxies: Proxies::STR(proxies),
}
}
pub fn send(&self) -> Result<Self, String> {
let text = self._build();
match text {
Ok(text) => Ok(Self {
text,
url: self.url,
store: self.store,
headers: self.headers,
proxies: self.proxies,
}),
Err(err) => Err(err),
}
}
fn _build(&self) -> Result<String, String> {
let client_builder = Client::builder();
let client = match self.proxies {
Proxies::STR(data) => {
let proxy = reqwest::Proxy::https(data.to_owned()).expect("no connect proxy");
client_builder.proxy(proxy).build().expect("无法连接到代理")
}
Proxies::None => client_builder.build().expect("无法使用http客户端"),
};
let mut request_builder = client.get(self.url);
let res = match self.headers {
Headers::None => request_builder.send(),
Headers::Default => {
request_builder.header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36").send()
}
Headers::JSON(data) => {
let object_data: HashMap<String, serde_json::Value> =
serde_json::from_str(data).unwrap();
for (k, v) in object_data {
request_builder = request_builder.header(k, v.to_string());
}
request_builder.send()
}
};
match res {
Ok(res) => {
let data = res.text().unwrap_or_else(|err| {
panic!("error url: {}, error: {:?}", self.url, err);
});
Ok(data)
}
Err(err) => Err(err.to_string()),
}
}
}