Show the property columns side by side

- infobox requirements
- wikidata entries
master
Raymon Zutekouw 23 hours ago
parent ef9b5ad85f
commit d938106f84
Signed by: raymon
GPG Key ID: 0E62222846283925
  1. 68
      src/lib.rs
  2. 15
      src/main.rs

@ -21,18 +21,56 @@ pub mod wikipedia_infobox_analyzer {
} }
/// Creates an ascii infobox out of the properties /// Creates an ascii infobox out of the properties
pub fn format_infobox_from_used_properties(name: String, properties: Vec<u64>) -> String { pub fn format_infobox_from_used_properties(name: String, qid: String, properties_template: Vec<u64>, properties_item: Vec<u64>, ) -> String {
let mut ascii_table = AsciiTable::default(); let mut ascii_table = AsciiTable::default();
ascii_table.set_max_width(26); ascii_table.set_max_width(80);
ascii_table ascii_table
.column(0) .column(0)
.set_header(name) .set_header("Infobox requires")
.set_align(Align::Left); .set_align(Align::Left);
let data: Vec<Vec<String>> = properties.iter().map(|v| vec![format!("P{v}")]).collect(); ascii_table
.column(1)
.set_header(format!("Wikidata {name} ({qid})"))
.set_align(Align::Left);
// Display the property columns as a table
let data: Vec<Vec<String>> = join_columns(&properties_template, &properties_item)
.iter()
.map(|&m| {
let (v1, v2) = m;
vec![ v1.map_or("".to_owned(), |v| format!("P{v}").to_owned())
, v2.map_or("".to_owned(), |v| format!("P{v}").to_owned())]
}
).collect();
ascii_table.format(data) ascii_table.format(data)
} }
/// Properties will be displayed in the right column if they are in the list for that column
/// All items in the left columns will be displayed
/// The remaining items in the right columns not in the left columns will trail in the right column
/// ┌───────┬───────┐
/// │ 1 │ 1 │
/// │ 3 │ │
/// │ │ 2 │
/// │ │ 4 │
/// └───────┴───────┘
/// So for example, [1, 3] and [1, 2, 4] become [1, 2, 3, 4], as shown above
fn join_columns<T: Copy + Eq>(vec1: &[T], vec2: &[T]) -> Vec<(Option<T>, Option<T>)> {
vec1.iter()
.flat_map(|n1| {
if let Some(&n2) = vec2.iter().find(|&x| x == n1) {
std::iter::once((Some(*n1), Some(n2)))
} else {
std::iter::once((Some(*n1), None))
}
})
.chain(vec2.iter()
.filter(|&n2| !vec1.contains(n2))
.map(|n2| (None, Some(*n2))))
.collect()
}
/// Fetches the wikidata label for the wiki property /// Fetches the wikidata label for the wiki property
pub async fn fetch_name_for_wiki_property(pid: u64) -> String { pub async fn fetch_name_for_wiki_property(pid: u64) -> String {
let query = format!(" let query = format!("
@ -139,16 +177,22 @@ mod tests {
assert_eq!( assert_eq!(
format_infobox_from_used_properties( format_infobox_from_used_properties(
"Earth".to_string(), "Earth".to_string(),
vec![31, 361, 571] "Q2".to_string(),
vec![18, 170, 571],
vec![18, 31, 138, 170, 361, 571]
), ),
concat![ concat![
"┌───────┐\n", "┌──────────────────┬─────────────────────┐\n",
"│ Earth │\n", // item identifier: Q2 "│ Infobox requires │ Wikidata Earth (Q2) │\n",
"├───────┤\n", "├──────────────────┼─────────────────────┤\n",
"│ P31 │\n", // property: instance of "│ P18 │ P18 │\n", // property: image
"│ P361 │\n", // property: part of "│ P170 │ P170 │\n", // property: creator
"│ P571 │\n", // property: inception "│ P571 │ P571 │\n", // property: inception
"└───────┘\n" "│ │ P31 │\n", // property: instance of
"│ │ P138 │\n", // property: inception
"│ │ P361 │\n", // property: part of
"└──────────────────┴─────────────────────┘\n",
] ]
); );
} }

@ -17,15 +17,20 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Input to the program // Input to the program
let title = args.wikipedia_article_title; let title = args.wikipedia_article_title;
let language = args.wikipedia_language_code; let language = args.wikipedia_language_code;
let _template = std::fs::read_to_string(&args.infobox_template_file)?; let template = std::fs::read_to_string(&args.infobox_template_file)?;
let qid = fetch_wiki_item_by_article_title(title.clone(), language.clone()); let qid = fetch_wiki_item_by_article_title(title.clone(), language.clone());
let properties_template = extract_used_properties_from_template(template);
let properties = fetch_properties_for_wiki_item(qid); let properties_item = fetch_properties_for_wiki_item(qid);
let table = format_infobox_from_used_properties(title.clone(), properties); let table = format_infobox_from_used_properties(
title.clone(),
format!("Q{qid}"),
properties_template,
properties_item,
);
println!("Qid: {qid}"); // Output of the program
println!("Template file exists");
println!("{table}"); println!("{table}");
Ok(()) Ok(())

Loading…
Cancel
Save