nako-metadata-scraper 0.1.0-alpha.2

Official Nako metadata scraper Addon Sidecar.
Documentation
use crate::{
    config::DoubanProviderConfig,
    providers::http_runtime::{
        ProviderHttpResult, ProviderHttpRuntime, ProviderHttpTransport,
        ReqwestProviderHttpTransport,
    },
    providers::rendered_page::{RenderedHtmlPage, RenderedPageRuntime},
};

use super::{DOUBAN_PROVIDER_ID, DoubanMetadataProvider};

impl DoubanMetadataProvider<ReqwestProviderHttpTransport> {
    pub fn new(config: DoubanProviderConfig) -> ProviderHttpResult<Self> {
        let rendered_pages = RenderedPageRuntime::new(config.rendered_pages.clone())?;
        Ok(Self {
            config,
            rendered_pages,
        })
    }
}

impl<T> DoubanMetadataProvider<T>
where
    T: ProviderHttpTransport,
{
    #[must_use]
    pub fn with_runtime(config: DoubanProviderConfig, runtime: ProviderHttpRuntime<T>) -> Self {
        let rendered_pages =
            RenderedPageRuntime::with_runtime(config.rendered_pages.clone(), runtime);
        Self {
            config,
            rendered_pages,
        }
    }

    pub(super) fn search_url(&self, title: &str) -> String {
        format!(
            "{}?search_text={}",
            self.config.search_base_url.trim_end_matches('?'),
            percent_encode_query(title)
        )
    }

    pub(super) async fn render(&self, url: String) -> anyhow::Result<RenderedHtmlPage> {
        let intent = self
            .config
            .rendered_pages
            .intent(&self.config.render_path, url);
        self.rendered_pages
            .render_html(DOUBAN_PROVIDER_ID, "render page", intent)
            .await
    }
}

pub(super) fn percent_encode_query(value: &str) -> String {
    let mut encoded = String::new();
    for byte in value.as_bytes() {
        match *byte {
            b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
                encoded.push(char::from(*byte));
            }
            b' ' => encoded.push_str("%20"),
            byte => encoded.push_str(&format!("%{byte:02X}")),
        }
    }
    encoded
}