Show the property columns side by side
- infobox requirements - wikidata entries
This commit is contained in:
+56
-12
@@ -21,18 +21,56 @@ pub mod wikipedia_infobox_analyzer {
|
||||
}
|
||||
|
||||
/// 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();
|
||||
ascii_table.set_max_width(26);
|
||||
ascii_table.set_max_width(80);
|
||||
ascii_table
|
||||
.column(0)
|
||||
.set_header(name)
|
||||
.set_header("Infobox requires")
|
||||
.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)
|
||||
}
|
||||
|
||||
/// 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
|
||||
pub async fn fetch_name_for_wiki_property(pid: u64) -> String {
|
||||
let query = format!("
|
||||
@@ -139,16 +177,22 @@ mod tests {
|
||||
assert_eq!(
|
||||
format_infobox_from_used_properties(
|
||||
"Earth".to_string(),
|
||||
vec![31, 361, 571]
|
||||
"Q2".to_string(),
|
||||
vec![18, 170, 571],
|
||||
vec![18, 31, 138, 170, 361, 571]
|
||||
),
|
||||
|
||||
concat![
|
||||
"┌───────┐\n",
|
||||
"│ Earth │\n", // item identifier: Q2
|
||||
"├───────┤\n",
|
||||
"│ P31 │\n", // property: instance of
|
||||
"│ P361 │\n", // property: part of
|
||||
"│ P571 │\n", // property: inception
|
||||
"└───────┘\n"
|
||||
"┌──────────────────┬─────────────────────┐\n",
|
||||
"│ Infobox requires │ Wikidata Earth (Q2) │\n",
|
||||
"├──────────────────┼─────────────────────┤\n",
|
||||
"│ P18 │ P18 │\n", // property: image
|
||||
"│ P170 │ P170 │\n", // property: creator
|
||||
"│ P571 │ P571 │\n", // property: inception
|
||||
"│ │ P31 │\n", // property: instance of
|
||||
"│ │ P138 │\n", // property: inception
|
||||
"│ │ P361 │\n", // property: part of
|
||||
"└──────────────────┴─────────────────────┘\n",
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user