use crate::config::CONFIG;
use anyhow::{Context, Result};
pub mod article;
pub mod parser;
pub mod search;
const USER_AGENT: &str =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0";
pub struct WikiApi {
client: reqwest::blocking::Client,
parser: Box<dyn parser::Parser>,
}
impl WikiApi {
pub fn new() -> Self {
let default_parser = parser::Default {};
WikiApi {
client: reqwest::blocking::ClientBuilder::new()
.user_agent(USER_AGENT)
.build()
.expect(&format!(
"Could not create a reqwest::blocking::Client with the user agent: {}",
USER_AGENT
)),
parser: Box::new(default_parser),
}
}
pub fn search(&self, query: &str) -> Result<search::SearchResponse> {
self.search_articles(query, None)
}
pub fn continue_search(
&self,
query: &str,
continue_code: &search::ContinueCode,
) -> Result<search::SearchResponse> {
self.search_articles(query, Some(continue_code))
}
fn search_articles(
&self,
query: &str,
continue_code: Option<&search::ContinueCode>,
) -> Result<search::SearchResponse> {
let mut url = format!(
"{}/w/api.php?action=query&list=search&srwhat=text&srsearch={}&format=json",
CONFIG.api_config.base_url, query
);
if let Some(_continue) = continue_code {
let continue_code = &_continue.continue_code;
let continue_scroll_offset = _continue.scroll_offset;
url = format!(
"{}/w/api.php?action=query&list=search&srwhat=text&srsearch={}&format=json&continue={}&sroffset={}",
CONFIG.api_config.base_url,
query,
continue_code,
continue_scroll_offset
);
}
let response = self
.client
.get(&url)
.send()
.context("Failed sending the search request")?;
response
.json::<search::SearchResponse>()
.context("Failed serializing the search response")
}
pub fn get_article(&self, page_id: &i32) -> Result<article::ParsedArticle> {
self.parse_article(&format!(
"{}?curid={}",
CONFIG.api_config.base_url.clone(),
page_id
))
}
fn parse_article(&self, url: &str) -> Result<article::ParsedArticle> {
let article_html = self.client.get(url).send().with_context(|| {
format!(
"Could not make a request to {}.\nIs your internet connection working?",
url
)
})?;
self.parser.parse(article_html)
}
pub fn open_article(&self, target: &str) -> Result<article::ParsedArticle> {
self.parse_article(&format!("{}{}", CONFIG.api_config.base_url.clone(), target))
}
}
impl Default for WikiApi {
fn default() -> Self {
Self::new()
}
}
unsafe impl Send for WikiApi {}
unsafe impl Sync for WikiApi {}