Skip to content

Commit

Permalink
Merge pull request #307 from zhang-accounting/feat/document-cachable
Browse files Browse the repository at this point in the history
feat: make document cacheable
  • Loading branch information
Kilerd authored Apr 27, 2024
2 parents 39688d8 + 704c859 commit d8ebc9a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
9 changes: 6 additions & 3 deletions zhang-server/src/routes/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,21 @@ use tokio::sync::RwLock;
use zhang_core::ledger::Ledger;

use crate::response::{DocumentResponse, ResponseWrapper};
use crate::util::cacheable_data;
use crate::ApiResult;

pub async fn download_document(ledger: State<Arc<RwLock<Ledger>>>, path: Path<(String,)>) -> impl IntoResponse {
let encoded_file_path = path.0 .0;
let filename = String::from_utf8(BASE64_STANDARD.decode(encoded_file_path).unwrap()).unwrap();
let filename = String::from_utf8(BASE64_STANDARD.decode(&encoded_file_path).unwrap()).unwrap();
let ledger = ledger.read().await;
let entry = &ledger.entry.0;
let full_path = entry.join(filename);
let striped_path = full_path.strip_prefix(entry).unwrap();
let file_name = striped_path.file_name().unwrap().to_string_lossy().to_string();
let vec = ledger.data_source.async_get(striped_path.to_string_lossy().to_string()).await.unwrap();
let bytes = Bytes::from(vec);
let content = cacheable_data(&encoded_file_path, ledger.data_source.async_get(striped_path.to_string_lossy().to_string()))
.await
.expect("cannot get file data");
let bytes = Bytes::from(content);
let headers = AppendHeaders([(header::CONTENT_DISPOSITION, format!("inline; filename=\"{}\"", file_name))]);
(headers, bytes)
}
Expand Down
29 changes: 29 additions & 0 deletions zhang-server/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use std::future::Future;
use std::path::PathBuf;
use std::str::FromStr;

use bigdecimal::BigDecimal;
use zhang_core::domains::schemas::{AccountBalanceDomain, AccountDailyBalanceDomain};
use zhang_core::error::IoErrorIntoZhangError;
use zhang_core::ZhangResult;

pub trait AmountLike {
fn number(&self) -> &BigDecimal;
Expand All @@ -26,3 +32,26 @@ impl AmountLike for AccountBalanceDomain {
&self.balance_commodity
}
}

/// fetch the data from local if the cache exists, normally used for documents.
pub async fn cacheable_data<F>(id: &str, miss_fn: F) -> ZhangResult<Vec<u8>>
where
F: Future<Output = ZhangResult<Vec<u8>>>,
{
let data_cache_folder = PathBuf::from_str(".cache/data").expect("Cannot create path");

// create data cache folder if not exist
std::fs::create_dir_all(&data_cache_folder).with_path(data_cache_folder.as_path())?;

let target_file = data_cache_folder.join(id);

let vec = match std::fs::read(&target_file) {
Ok(data) => data,
_ => {
let fetched_data = miss_fn.await?;
std::fs::write(&target_file, &fetched_data).with_path(target_file.as_path())?;
fetched_data
}
};
Ok(vec)
}

0 comments on commit d8ebc9a

Please sign in to comment.