|
|
|
@ -1,6 +1,12 @@ |
|
|
|
|
use structopt::StructOpt; |
|
|
|
|
use wikipedia_infobox_analyzer::wikipedia_infobox_analyzer::*; |
|
|
|
|
|
|
|
|
|
use dirs_next::cache_dir; |
|
|
|
|
use std::collections::HashMap; |
|
|
|
|
use std::fs; |
|
|
|
|
use std::io; |
|
|
|
|
use std::path::PathBuf; |
|
|
|
|
use structopt::StructOpt; |
|
|
|
|
|
|
|
|
|
#[derive(StructOpt)] |
|
|
|
|
struct Cli { |
|
|
|
|
#[structopt(default_value = "Earth", long = "title")] |
|
|
|
@ -11,10 +17,88 @@ struct Cli { |
|
|
|
|
infobox_template_file: std::path::PathBuf, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[derive(Debug)] |
|
|
|
|
struct StorageDisk { |
|
|
|
|
base_path: PathBuf, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl StorageDisk { |
|
|
|
|
fn new(app_name: &str) -> Self { |
|
|
|
|
// Get OS-specific cache directory, otherwise use a fallback location
|
|
|
|
|
let mut path = match cache_dir() { |
|
|
|
|
Some(path) => path, |
|
|
|
|
None => PathBuf::from("./.cache"), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
path.push(app_name); |
|
|
|
|
fs::create_dir_all(&path) |
|
|
|
|
.unwrap_or_else(|_| panic!("Failed to create storage directory: {path:?}")); |
|
|
|
|
|
|
|
|
|
StorageDisk { base_path: path } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[allow(dead_code)] |
|
|
|
|
fn delete(&self) -> std::io::Result<()> { |
|
|
|
|
fs::remove_dir_all(&self.base_path) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn store_data(&self, filename: String, data: String) -> std::io::Result<()> { |
|
|
|
|
let file_path = self.base_path.join(filename); |
|
|
|
|
fs::write(file_path, data) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn read_data(&self, filename: String) -> std::io::Result<String> { |
|
|
|
|
let file_path = self.base_path.join(filename); |
|
|
|
|
fs::read_to_string(file_path) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct Cache { |
|
|
|
|
file_name: String, |
|
|
|
|
storage: StorageDisk, |
|
|
|
|
property_labels: HashMap<String, String>, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Cache { |
|
|
|
|
fn new(file_name: String, storage: StorageDisk) -> std::io::Result<Self> { |
|
|
|
|
let mut property_labels: HashMap<String, String> = HashMap::new(); |
|
|
|
|
|
|
|
|
|
match storage.read_data(file_name.clone()) { |
|
|
|
|
Ok(raw_data) => { |
|
|
|
|
property_labels = serde_json::from_str(&raw_data)?; |
|
|
|
|
} |
|
|
|
|
Err(err) if err.kind() == io::ErrorKind::NotFound => { |
|
|
|
|
println!("No cache found, populating the program cache with wikidata..."); |
|
|
|
|
|
|
|
|
|
property_labels = HashMap::new(); |
|
|
|
|
property_labels.insert("P31".to_string(), "instance of".to_string()); |
|
|
|
|
|
|
|
|
|
let data = serde_json::to_string(&property_labels)?; |
|
|
|
|
storage.store_data(file_name.clone(), data)?; |
|
|
|
|
|
|
|
|
|
println!("Cache populated from wikidata") |
|
|
|
|
} |
|
|
|
|
Err(err) => { |
|
|
|
|
println!("Unknown error occurred, exiting gracefully"); |
|
|
|
|
return Err(err); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Ok(Cache { |
|
|
|
|
file_name, |
|
|
|
|
storage, |
|
|
|
|
property_labels, |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> { |
|
|
|
|
let args = Cli::from_args(); |
|
|
|
|
// Initialize cache and storage
|
|
|
|
|
let storage = StorageDisk::new("wikipedia-infobox-analyzer"); |
|
|
|
|
let cache = Cache::new("property_labels.cache".to_string(), storage); |
|
|
|
|
|
|
|
|
|
// Input to the program
|
|
|
|
|
let args = Cli::from_args(); |
|
|
|
|
let title = args.wikipedia_article_title; |
|
|
|
|
let language = args.wikipedia_language_code; |
|
|
|
|
let template = std::fs::read_to_string(&args.infobox_template_file)?; |
|
|
|
|