deepr-s3 0.1.0

deepr SDK for S3 operations
Documentation
use crate::bucket::Bucket as S3Bucket;
use crate::bucket::BucketPolicy as S3BucketPolicy;
use crate::object::Object as S3Object;
use crate::object::ObjectVersion as S3ObjectVersion;
use anyhow::Result;
use aws_sdk_s3::{Client, Error};
use aws_types::SdkConfig;
use chrono::{DateTime, Utc};
use deepr_utils::dateutil::convert_naive_datetime_to_utc;

pub struct OpClient {
    pub client: Client,
}

impl OpClient {
    pub fn new(config: SdkConfig) -> Self {
        let client = Client::new(&config);
        Self { client }
    }

    pub async fn list_buckets(&self) -> Result<Vec<S3Bucket>, Error> {
        let mut list_buckets = self.client.list_buckets().into_paginator().send();
        let mut s3_bucket: Vec<S3Bucket> = Vec::new();
        while let Some(list_buckets_output) = list_buckets.next().await {
            match list_buckets_output {
                Ok(list_buckets) => {
                    let buckets = list_buckets.buckets();
                    for bucket in buckets {
                        s3_bucket.push(S3Bucket {
                            name: bucket.name().unwrap().to_string(),
                            created_at: bucket.creation_date().unwrap().to_string(),
                            region: bucket.bucket_region().unwrap_or("None").to_string(),
                        });
                    }
                }
                Err(e) => println!("{:?}", e),
            }
        }
        Ok(s3_bucket)
    }

    pub async fn list_objects(
        &self,
        bucket: &str,
        prefix: &str,
        last_modified_date: &str,
        predicate: &str,
    ) -> Result<Vec<S3Object>> {
        let mut list_objects = self
            .client
            .list_objects_v2()
            .bucket(bucket)
            .prefix(prefix)
            .into_paginator()
            .send();
        let mut s3_objects: Vec<S3Object> = Vec::new();
        let last_mod_time: DateTime<Utc> = convert_naive_datetime_to_utc(last_modified_date);
        while let Some(list_objects_v2_output) = list_objects.next().await {
            match list_objects_v2_output {
                Ok(list_objects) => {
                    let objects = list_objects.contents();
                    if predicate == "newer" {
                        for object in objects {
                            if object
                                .last_modified()
                                .unwrap()
                                .to_string()
                                .parse::<DateTime<Utc>>()
                                .unwrap()
                                > last_mod_time
                            {
                                s3_objects.push(S3Object {
                                    obj_key: object.key().unwrap().to_string(),
                                    obj_last_modified_at: object
                                        .last_modified()
                                        .unwrap()
                                        .to_string(),
                                    obj_etag: object.e_tag().unwrap().to_string(),
                                    obj_size: object.size().unwrap(),
                                    obj_storage_class: object.storage_class().unwrap().to_string(),
                                });
                            }
                        }
                    } else if predicate == "older" {
                        for object in objects {
                            if object
                                .last_modified()
                                .unwrap()
                                .to_string()
                                .parse::<DateTime<Utc>>()
                                .unwrap()
                                < last_mod_time
                            {
                                s3_objects.push(S3Object {
                                    obj_key: object.key().unwrap().to_string(),
                                    obj_last_modified_at: object
                                        .last_modified()
                                        .unwrap()
                                        .to_string(),
                                    obj_etag: object.e_tag().unwrap().to_string(),
                                    obj_size: object.size().unwrap(),
                                    obj_storage_class: object.storage_class().unwrap().to_string(),
                                });
                            }
                        }
                    }
                }
                Err(e) => return Err(e.into()),
            }
        }
        Ok(s3_objects)
    }

    pub async fn list_objects_versions(&self, bucket: &str) -> Result<Vec<S3ObjectVersion>, Error> {
        let list_objects_versions = self
            .client
            .list_object_versions()
            .bucket(bucket)
            .send()
            .await?;
        let mut s3_object_version: Vec<S3ObjectVersion> = Vec::new();
        for version in list_objects_versions.versions() {
            s3_object_version.push(S3ObjectVersion {
                obj_key: version.key().unwrap_or_default().to_string(),
                obj_version_id: version.version_id().unwrap_or_default().to_string(),
                obj_is_latest: version.is_latest().unwrap(),
                obj_last_modified_date: version.last_modified().unwrap().to_string(),
                obj_size: version.size().unwrap_or_default(),
                obj_etag: version.e_tag().unwrap_or_default().to_string(),
                obj_owner: version
                    .owner()
                    .unwrap()
                    .display_name()
                    .unwrap_or_default()
                    .to_string(),
            });
        }
        Ok(s3_object_version)
    }

    pub async fn get_bucket_access_policies(&self) -> Result<Vec<S3BucketPolicy>> {
        // Get all S3 buckets in the account as vector
        let mut s3_bucket_policy: Vec<S3BucketPolicy> = Vec::new();
        let mut list_buckets = self.client.list_buckets().into_paginator().send();
        while let Some(list_buckets_output) = list_buckets.next().await {
            match list_buckets_output {
                Ok(list_buckets) => {
                    let buckets = list_buckets.buckets();
                    for bucket in buckets {
                        let bucket_name = bucket.name().unwrap_or_default();
                        let bucket_public_access_policy = self
                            .client
                            .get_public_access_block()
                            .bucket(bucket_name)
                            .send()
                            .await?;
                        s3_bucket_policy.push(S3BucketPolicy {
                            name: bucket_name.into(),
                            public_access: bucket_public_access_policy
                                .public_access_block_configuration
                                .unwrap(),
                        });
                    }
                }
                Err(e) => println!("{:?}", e),
            }
        }
        // Loop through the bucket
        Ok(s3_bucket_policy)
    }
}