use std::io::Write;
use pagesift_content::{Options, process};
use pagesift_plan::quality::{FEATURE_NAMES, features};
use pagesift_plan::script::ScriptStats;
use pagesift_stat::Delta;
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let [manifest, out, weights_out] = args.as_slice() else {
panic!("usage: quality_data <manifest.jsonl> <out.jsonl> <weights.json>");
};
let mut rows = Vec::new();
let mut stats = ScriptStats::default();
for line in std::fs::read_to_string(manifest)
.unwrap()
.lines()
.filter(|l| !l.trim().is_empty())
{
let row: serde_json::Value = serde_json::from_str(line).unwrap();
let html = String::from_utf8_lossy(&std::fs::read(row["path"].as_str().unwrap()).unwrap())
.into_owned();
let opts = Options {
base_url: row["url"].as_str().and_then(|u| url::Url::parse(u).ok()),
..Options::default()
};
let doc = process(&html, &opts);
stats.observe(doc.plain_text.as_deref().unwrap_or(&doc.markdown));
rows.push((row, html.len(), doc));
}
let weights = stats.weights(Delta::DEFAULT);
let mut w = std::io::BufWriter::new(std::fs::File::create(out).unwrap());
for (row, html_bytes, doc) in &rows {
let f = features(doc, *html_bytes, &weights);
let rec = serde_json::json!({"id": row["id"], "set": row["set"], "markdown": doc.markdown, "features": f});
writeln!(w, "{rec}").unwrap();
}
let table: serde_json::Map<String, serde_json::Value> = weights
.iter()
.map(|(s, wt)| {
let (h, n) = stats.entropy(s).unwrap_or((f64::NAN, 0));
(
format!("{s:?}"),
serde_json::json!({"weight": wt, "entropy_nats": h, "chars": n}),
)
})
.collect();
std::fs::write(weights_out, serde_json::to_string_pretty(&table).unwrap()).unwrap();
eprintln!(
"quality_data: {} pages, {} features",
rows.len(),
FEATURE_NAMES.len()
);
}