2023-08-05 12:49:17 +00:00
|
|
|
use crate::app_config::AppConfig;
|
|
|
|
use s3::error::S3Error;
|
|
|
|
use s3::{Bucket, BucketConfiguration};
|
|
|
|
|
|
|
|
#[derive(thiserror::Error, Debug)]
|
|
|
|
enum BucketServiceError {
|
|
|
|
#[error("Failed to fetch bucket information!")]
|
|
|
|
FailedFetchBucketInfo,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create S3 bucket if required
|
|
|
|
pub async fn create_bucket_if_required() -> anyhow::Result<()> {
|
|
|
|
if AppConfig::get().s3_skip_auto_create_bucket {
|
|
|
|
log::debug!("Skipping bucket existence check");
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
|
|
|
let bucket = AppConfig::get().s3_bucket()?;
|
|
|
|
|
|
|
|
match bucket.location().await {
|
|
|
|
Ok(_) => {
|
|
|
|
log::debug!("The bucket already exists.");
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
Err(S3Error::Http(404, s)) if s.contains("<Code>NoSuchKey</Code>") => {
|
|
|
|
log::warn!("Failed to fetch bucket location, but it seems that bucket exists.");
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
Err(S3Error::Http(404, s)) if s.contains("<Code>NoSuchBucket</Code>") => {
|
|
|
|
log::warn!("The bucket does not seem to exists, trying to create it!")
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
log::error!("Got unexpected error when querying bucket info: {}", e);
|
|
|
|
return Err(BucketServiceError::FailedFetchBucketInfo.into());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Bucket::create_with_path_style(
|
|
|
|
&bucket.name,
|
|
|
|
bucket.region,
|
|
|
|
AppConfig::get().s3_credentials()?,
|
|
|
|
BucketConfiguration::private(),
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2023-08-07 09:07:24 +00:00
|
|
|
|
|
|
|
/// Upload a new file to the bucket
|
|
|
|
pub async fn upload_file(path: &str, content: &[u8]) -> anyhow::Result<()> {
|
|
|
|
let bucket = AppConfig::get().s3_bucket()?;
|
|
|
|
|
|
|
|
bucket.put_object(path, content).await?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-08-07 12:53:44 +00:00
|
|
|
/// Get a file
|
|
|
|
pub async fn get_file(path: &str) -> anyhow::Result<Vec<u8>> {
|
|
|
|
let bucket = AppConfig::get().s3_bucket()?;
|
|
|
|
|
|
|
|
Ok(bucket.get_object(path).await?.to_vec())
|
|
|
|
}
|
|
|
|
|
2023-08-07 09:07:24 +00:00
|
|
|
/// Delete a file, if it exists
|
|
|
|
pub async fn delete_file_if_exists(path: &str) -> anyhow::Result<()> {
|
|
|
|
let bucket = AppConfig::get().s3_bucket()?;
|
|
|
|
|
|
|
|
bucket.delete_object(path).await?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|