add function to generate blob path from blob id

This commit is contained in:
glyph 2022-02-24 11:02:21 +02:00
parent 29c23f424b
commit 6ece486103
3 changed files with 63 additions and 2 deletions

56
src/blobs.rs Normal file
View File

@ -0,0 +1,56 @@
//! Blob utilities which do not require RPC calls.
//!
//! Offers the following functions:
//!
//! - [`get_blob_path()`]
use crate::error::GolgiError;
/// Lookup the filepath for a blob.
///
/// # Example
///
/// ```rust
/// use golgi::blobs;
///
/// fn lookup_blob_path() -> Result<(), GolgiError> {
/// let blob_ref = "&JlJHc9yeG1EpZA9fIPGLzUKDH0FeR39Ai57euhKT1G8=.sha256";
///
/// let blob_path = blobs::get_blob_path(blob_ref)?;
///
/// println!("{}", blob_path);
///
/// // 26/524773dc9e1b5129640f5f20f18bcd42831f415e477f408b9edeba1293d46f
///
/// Ok(())
/// }
/// ```
pub fn get_blob_path(blob_id: &str) -> Result<String, GolgiError> {
let dot_index = blob_id.rfind('.').ok_or_else(|| {
GolgiError::SigilLink(format!(
"Invalid blob ID; no dot index was found: {}",
blob_id
))
})?;
// obtain the base64 portion (substring) of the blob id
let base64_str = &blob_id[1..dot_index];
// decode blob substring from base64 (to bytes)
let blob_bytes = base64::decode_config(base64_str, base64::STANDARD)?;
// represent the blob bytes as hex, removing all unnecessary characters
let blob_hex = format!("{:02x?}", blob_bytes)
.replace('[', "")
.replace(']', "")
.replace(',', "")
.replace(' ', "");
// split the hex representation of the decoded base64
// this is how paths are formatted for the blobstore
// e.g. 26/524773dc9e1b5129640f5f20f18bcd42831f415e477f408b9edeba1293d46f
// full path would be: `/home/user/.ssb-go/blobs/sha256/26/524773dc...`
let blob_path = format!("{}/{}", &blob_hex[..2], &blob_hex[2..]);
Ok(blob_path)
}

View File

@ -34,9 +34,11 @@ pub enum GolgiError {
Rpc(RpcError),
/// Go-sbot error.
Sbot(String),
/// SSB sigil-link error.
SigilLink(String),
/// JSON serialization or deserialization error.
SerdeJson(JsonError),
/// Error decoding typed ssb message from content.
/// Error decoding typed SSB message from content.
ContentType(String),
/// Error decoding UTF8 string from bytes
Utf8Parse {
@ -55,6 +57,7 @@ impl std::error::Error for GolgiError {
GolgiError::Feed(ref err) => Some(err),
GolgiError::Rpc(ref err) => Some(err),
GolgiError::Sbot(_) => None,
GolgiError::SigilLink(_) => None,
GolgiError::SerdeJson(ref err) => Some(err),
GolgiError::ContentType(_) => None,
GolgiError::Utf8Parse { ref source } => Some(source),
@ -75,11 +78,12 @@ impl std::fmt::Display for GolgiError {
// then have the core display msg be: "SSB RPC error: {}", context
GolgiError::Rpc(ref err) => write!(f, "SSB RPC failure: {}", err),
GolgiError::Sbot(ref err) => write!(f, "Sbot returned an error response: {}", err),
GolgiError::SigilLink(ref context) => write!(f, "SSB sigil-link error: {}", context),
GolgiError::SerdeJson(_) => write!(f, "Failed to serialize JSON slice"),
//GolgiError::WhoAmI(ref err) => write!(f, "{}", err),
GolgiError::ContentType(ref err) => write!(
f,
"Failed to decode typed message from ssb message content: {}",
"Failed to decode typed message from SSB message content: {}",
err
),
GolgiError::Utf8Parse { source } => {

View File

@ -69,6 +69,7 @@
//! ```
pub mod api;
pub mod blobs;
pub mod error;
pub mod messages;
pub mod sbot;