Browse Source

add save templates to file cache

master
Schneider 5 years ago
parent
commit
010f6f8592
Signed by: schneider GPG Key ID: 3F50B02A50039F3B
  1. 86
      Cargo.lock
  2. 1
      Cargo.toml
  3. 52
      src/template.rs

86
Cargo.lock

@ -15,6 +15,18 @@ version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c"
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.11" version = "0.2.11"
@ -66,6 +78,17 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "blake2b_simd"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.2.0" version = "3.2.0"
@ -125,6 +148,12 @@ dependencies = [
"vec_map", "vec_map",
] ]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.6.4" version = "0.6.4"
@ -141,6 +170,39 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static 1.4.0",
]
[[package]]
name = "directories"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c"
dependencies = [
"cfg-if",
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
dependencies = [
"cfg-if",
"libc",
"redox_users",
"winapi 0.3.8",
]
[[package]] [[package]]
name = "dtoa" name = "dtoa"
version = "0.4.5" version = "0.4.5"
@ -265,6 +327,7 @@ dependencies = [
name = "gitig" name = "gitig"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"directories",
"error-chain", "error-chain",
"libc", "libc",
"log", "log",
@ -773,6 +836,17 @@ dependencies = [
"redox_syscall", "redox_syscall",
] ]
[[package]]
name = "redox_users"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
dependencies = [
"getrandom",
"redox_syscall",
"rust-argon2",
]
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
version = "0.5.2" version = "0.5.2"
@ -818,6 +892,18 @@ dependencies = [
"winreg", "winreg",
] ]
[[package]]
name = "rust-argon2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.16" version = "0.1.16"

1
Cargo.toml

@ -11,6 +11,7 @@ structopt = "0.3"
reqwest = { version = "0.10", features = ["blocking", "json"] } reqwest = { version = "0.10", features = ["blocking", "json"] }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
directories = "2.0"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
libc = "0.2" libc = "0.2"

52
src/template.rs

@ -6,15 +6,19 @@ use reqwest::header::{ACCEPT, CONTENT_TYPE, USER_AGENT};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::BufReader;
use std::io::{BufReader, BufWriter};
use std::path::PathBuf; use std::path::PathBuf;
use std::time::{Duration, SystemTime};
use crate::errors::*; use crate::errors::*;
/// Default user agent string used for api requests
pub const DEFAULT_USER_AGENT: &str = "gitig"; pub const DEFAULT_USER_AGENT: &str = "gitig";
/// Response objects from github api
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[allow(clippy::missing_docs_in_private_items)]
pub struct Template { pub struct Template {
pub name: String, pub name: String,
pub path: String, pub path: String,
@ -33,8 +37,10 @@ pub struct Template {
pub links: Links, pub links: Links,
} }
/// Part of github api response
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[allow(clippy::missing_docs_in_private_items)]
pub struct Links { pub struct Links {
#[serde(rename = "self")] #[serde(rename = "self")]
pub self_field: String, pub self_field: String,
@ -76,14 +82,40 @@ impl GithubTemplates {
.send() .send()
.chain_err(|| "Error while sending request to query all templates")?; .chain_err(|| "Error while sending request to query all templates")?;
let body: Vec<Template> = res.json().chain_err(|| "json")?; let body: Vec<Template> = res.json().chain_err(|| "json")?;
debug!("Received and deserialized {} templates", body.len());
trace!("Serializing templates to file cache");
let cache = File::create(Self::cache_path())
.chain_err(|| "Error while creating file cache to write")?;
let writer = BufWriter::new(cache);
serde_json::to_writer(writer, &body)
.chain_err(|| "Error while serialzing templates to file cache")?;
debug!("Serialization of templates completed");
Ok(GithubTemplates { templates: body }) Ok(GithubTemplates { templates: body })
} }
/// Returns whether there is an cached json version /// Returns whether there is an cached json version
fn is_cached() -> bool { Self::cache_path().exists() }
fn is_cached() -> bool {
let path = Self::cache_path();
if !path.exists() {
return false;
}
let modified: SystemTime = path
.metadata()
.map(|meta| meta.modified().unwrap_or(SystemTime::UNIX_EPOCH))
.unwrap_or(SystemTime::UNIX_EPOCH);
let max_age = Duration::from_secs(60 * 24 * 2 /* two days */);
if modified.elapsed().unwrap_or(Duration::from_secs(u64::max_value())) > max_age {
debug!("Cache file is too older (> days), won't be used");
return false;
}
true
}
/// Returns the path of the file cache /// Returns the path of the file cache
fn cache_path() -> PathBuf { fn cache_path() -> PathBuf {
let proj = directories::ProjectDirs::from("org", "webschneider", env!("CARGO_PKG_NAME"));
let mut cache: PathBuf = crate::helpers::cache_dir(); let mut cache: PathBuf = crate::helpers::cache_dir();
cache.push("templates.json"); cache.push("templates.json");
debug!("Using cache path for templates: {}", cache.to_str().unwrap_or("err")); debug!("Using cache path for templates: {}", cache.to_str().unwrap_or("err"));
@ -93,22 +125,22 @@ impl GithubTemplates {
/// Reads the templates from the file cache /// Reads the templates from the file cache
fn from_cache() -> Result<GithubTemplates> { fn from_cache() -> Result<GithubTemplates> {
trace!("Reading templates from file cache"); trace!("Reading templates from file cache");
if !Self::is_cached() {
debug!("Templates response not yet cached");
return Err("Results are not yet cached".into());
}
let f = File::open(Self::cache_path()) let f = File::open(Self::cache_path())
.chain_err(|| "Error while opening cache file for templates")?; .chain_err(|| "Error while opening cache file for templates")?;
let reader = BufReader::new(f); let reader = BufReader::new(f);
let tpls = serde_json::from_reader(reader)
let tpls: Vec<Template> = serde_json::from_reader(reader)
.chain_err(|| "Error while reading templates from file cache")?; .chain_err(|| "Error while reading templates from file cache")?;
debug!("Deserialized {} templates from file cache", tpls.len());
Ok(GithubTemplates { templates: tpls }) Ok(GithubTemplates { templates: tpls })
} }
/// Creates a new struct with templates /// Creates a new struct with templates
pub fn new() -> Result<GithubTemplates> {
if Self::is_cached() {
Self::from_cache()
} else {
Self::from_server()
}
}
pub fn new() -> Result<GithubTemplates> { Self::from_cache().or_else(|_| Self::from_server()) }
/// Returns a list of the template names /// Returns a list of the template names
pub fn list_names(&self) -> Vec<&str> { pub fn list_names(&self) -> Vec<&str> {

Loading…
Cancel
Save