|
|
|
@ -1,6 +1,5 @@ |
|
|
|
|
#[doc = include_str!("../README.md")] |
|
|
|
|
pub mod wikipedia_infobox_analyzer { |
|
|
|
|
use ascii_table::{Align, AsciiTable}; |
|
|
|
|
use regex::Regex; |
|
|
|
|
use itertools::Itertools; |
|
|
|
|
|
|
|
|
@ -20,43 +19,20 @@ pub mod wikipedia_infobox_analyzer { |
|
|
|
|
.collect() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Creates an ascii infobox out of the properties
|
|
|
|
|
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(80); |
|
|
|
|
ascii_table |
|
|
|
|
.column(0) |
|
|
|
|
.set_header("Infobox requires") |
|
|
|
|
.set_align(Align::Left); |
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
/// ```md
|
|
|
|
|
/// ┌───────┬───────┐
|
|
|
|
|
/// │ 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>)> { |
|
|
|
|
pub 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) { |
|
|
|
@ -124,7 +100,7 @@ pub mod wikipedia_infobox_analyzer { |
|
|
|
|
.collect::<Vec<u64>>() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Fetch the wikidata identifier associated with the wikipedia article
|
|
|
|
|
/// Fetches the wikidata identifier associated with the wikipedia article
|
|
|
|
|
pub fn fetch_wiki_item_by_article_title(title: String, language_code: String) -> u64 { |
|
|
|
|
let uri = format!("https://{}.wikipedia.org/w/api.php?action=query&prop=pageprops&format=json&titles={}", &language_code, &title); |
|
|
|
|
|
|
|
|
@ -172,31 +148,6 @@ mod tests_lib { |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn test_format_infobox_from_used_properties() { |
|
|
|
|
assert_eq!( |
|
|
|
|
format_infobox_from_used_properties( |
|
|
|
|
"Earth".to_string(), |
|
|
|
|
"Q2".to_string(), |
|
|
|
|
vec![18, 170, 571], |
|
|
|
|
vec![18, 31, 138, 170, 361, 571] |
|
|
|
|
), |
|
|
|
|
|
|
|
|
|
concat![ |
|
|
|
|
"┌──────────────────┬─────────────────────┐\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", |
|
|
|
|
] |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[tokio::test] |
|
|
|
|
async fn test_fetch_name_for_wiki_property() { |
|
|
|
|
let name = fetch_name_for_wiki_property(31).await; |
|
|
|
|