use super::*;
pub(super) struct RenderHints {
pub worth: bool,
pub client_code: bool,
pub client_redirect: bool,
}
pub(super) struct Fetched {
pub doc: pagesift_content::Document,
pub html: String,
pub decode_warning: Option<String>,
pub http_chars: usize,
pub render: Option<RenderHints>,
pub embedded: Option<(Option<String>, pagesift_api::types::PlanStep)>,
}
const SMALL_HTML_BYTES: usize = 4096;
pub(super) async fn extract_fetched(
decode: impl FnOnce() -> pagesift_net::Decoded + Send + 'static,
base: &Url,
status: Option<u16>,
opts: &ScrapeOptions,
auto: bool,
) -> Result<Fetched, ApiError> {
let copts = content_options(base, status, opts);
let tags = tag_filter(opts)?;
let tagged = tags.is_some();
cpu_task(move || {
let decoded = decode();
let decode_warning = decoded.warning();
let html = decoded.text;
let (doc, client_code) = if let Some(doc) = super::feed::parse(&html, copts.links) {
(doc, None)
} else if let Some(t) = tags {
let filtered = t.apply(&html);
let doc = CONTENT_WORKSPACE.with(|ws| {
pagesift_content::process_with_workspace(&filtered, &copts, &mut ws.borrow_mut())
});
(doc, None)
} else {
CONTENT_WORKSPACE.with(|ws| {
pagesift_content::process_with_workspace_then(
&html,
&copts,
&mut ws.borrow_mut(),
|dom, doc| (auto && needs_render(doc)).then(|| client_code_in(dom)),
)
})
};
let embedded = (auto && !tagged && needs_render(&doc))
.then(|| {
let mut merged = doc.clone();
let step = super::planner::embedded_json(&mut merged, &html)?;
Some((step.chosen.then_some(merged.markdown), step))
})
.flatten();
let http_chars = text_weight(&doc.markdown);
let render = (auto && needs_render(&doc)).then(|| RenderHints {
worth: html.len() >= SMALL_HTML_BYTES || pagesift_flow::sniff::has_script_tag(&html),
client_code: client_code.unwrap_or_else(|| has_client_code(&html)),
client_redirect: http_chars == 0
&& html.len() < SMALL_HTML_BYTES
&& pagesift_flow::sniff::has_client_redirect(&html),
});
Fetched {
doc,
html,
decode_warning,
http_chars,
render,
embedded,
}
})
.await
}