diff options
author | Daniel <kingdread@gmx.de> | 2020-04-06 14:43:28 +0200 |
---|---|---|
committer | Daniel <kingdread@gmx.de> | 2020-04-06 14:43:28 +0200 |
commit | a304370df4f998f7054731bac173113f91bf5cb1 (patch) | |
tree | aab806f530e8871dbc35368e021485dc02265c54 /src/guilds.rs | |
parent | f7a0f17ce47e15f4cb39b49fecf4e252ce7897c3 (diff) | |
download | raidgrep-a304370df4f998f7054731bac173113f91bf5cb1.tar.gz raidgrep-a304370df4f998f7054731bac173113f91bf5cb1.tar.bz2 raidgrep-a304370df4f998f7054731bac173113f91bf5cb1.zip |
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.
Diffstat (limited to 'src/guilds.rs')
-rw-r--r-- | src/guilds.rs | 79 |
1 files changed, 79 insertions, 0 deletions
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<RwLock<HashMap<String, Guild>>> = 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<Guild> { + { + 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(); +} |