use crate::structs; use quick_xml::events::Event; use quick_xml::Reader; extern crate reqwest; extern crate serde_json; pub async fn search( client: reqwest::Client, query: &str, tags: Vec<&str>, broad_search: bool, ) -> Result, structs::Error> { let tags_mode = match broad_search { true => "OR", false => "AND", }; Ok(serde_json::from_str( &serde_json::from_str::( &client.post("https://search.htv-services.com") .header("Content-Type", "application/json") .body(serde_json::json!( {"search_text": &query, "tags": tags, "tags_mode": tags_mode, "brands": [], "blacklist": [], "order_by": "created_at_unix", "ordering": "desc", "page": 0} ).to_string()) .send() .await? .text() .await? )?.hits )?) } pub async fn get_hentai( client: reqwest::Client, id: &str, ) -> Result, structs::Error> { let resp = client .get(&format!("https://hanime.tv/videos/hentai/{}", id)) .send() .await?; if resp.status() != 200 { return Ok(None); } let text = resp.text().await?; let mut reader = Reader::from_str(&text); reader.check_end_names(false); let mut buf = Vec::new(); let mut script = String::new(); let mut is_inside_script = false; let mut to_return = None; loop { match reader.read_event(&mut buf) { Ok(Event::Start(ref e)) if e.name() == b"script" => is_inside_script = true, Ok(Event::Text(e)) if is_inside_script => { let text = match reader.decode(e.escaped()) { Ok(text) => text, Err(_) => continue, }; if !script.is_empty() || text.starts_with("window.__NUXT__={") { script.push_str(&text); } } Ok(Event::End(ref e)) if e.name() == b"script" && is_inside_script => { if script.is_empty() { is_inside_script = false; } else { to_return = Some(serde_json::from_str( script.splitn(2, "=").nth(1).unwrap().trim_end_matches(';'), )?); break; } } Err(err) => panic!("Error at position {}: {:?}", reader.buffer_position(), err), Ok(Event::Eof) => break, _ => (), }; buf.clear(); } Ok(to_return) }