From a304370df4f998f7054731bac173113f91bf5cb1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 6 Apr 2020 14:43:28 +0200 Subject: implement guild display & filtering options Filtering based on guilds is slow, as it will have to retrieve every guild name from the GW2 API, and it has to parse every log file instead of bailing early. Therefore, guilds are not searched by default, and have to be explicitely turned on with --guilds. In addition, this means that raidgrep will now need network access when --guilds is passed, which was not the case before. --- src/guilds.rs | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/guilds.rs (limited to 'src/guilds.rs') diff --git a/src/guilds.rs b/src/guilds.rs new file mode 100644 index 0000000..0eff6ad --- /dev/null +++ b/src/guilds.rs @@ -0,0 +1,79 @@ +//! Guild name retrieval and caching functions. +use std::collections::HashMap; +use std::fs::File; +use std::path::PathBuf; +use std::sync::RwLock; + +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; + +static CACHE: Lazy>> = Lazy::new(|| RwLock::new(HashMap::new())); + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Guild { + tag: String, + name: String, +} + +impl Guild { + pub fn tag(&self) -> &str { + &self.tag + } + + pub fn name(&self) -> &str { + &self.name + } +} + +/// Looks up the given guild. +/// +/// This checks the cache first, and if nothing was found, it will hit the API. +pub fn lookup(api_id: &str) -> Option { + { + let cache = CACHE.read().unwrap(); + if let Some(guild) = cache.get(api_id) { + return Some(guild.clone()); + } + } + + let mut cache = CACHE.write().unwrap(); + let url = format!("https://api.guildwars2.com/v2/guild/{}", api_id); + let result = ureq::get(&url) + .call() + .into_json() + .expect("Invalid JSON in API response"); + let name = result["name"].as_str()?; + let tag = result["tag"].as_str()?; + let guild = Guild { + tag: tag.into(), + name: name.into(), + }; + cache.insert(api_id.into(), guild.clone()); + Some(guild) +} + +fn cache_path() -> PathBuf { + let mut cache_path = dirs::cache_dir().unwrap(); + cache_path.push("raidgrep"); + cache_path +} + +/// Loads the cache from the file system. +pub fn prepare_cache() { + let path = cache_path(); + if !path.is_file() { + return; + } + + let file = File::open(path).expect("Unable to read cache file"); + let cache = serde_json::from_reader(file).expect("Cache file has invalid format"); + let mut target = CACHE.write().unwrap(); + *target = cache; +} + +/// Saves the cache to the file system +pub fn save_cache() { + let path = cache_path(); + let file = File::create(path).expect("Cannot open cache for writing"); + serde_json::to_writer(file, &*CACHE.read().unwrap()).unwrap(); +} -- cgit v1.2.3