use actix_web::error::ErrorInternalServerError; use aws_sdk_s3::{error::SdkError, primitives::ByteStream, Client as S3Client}; use mime_guess::mime; use std::str::FromStr; /// Загружает файл в S3 хранилище. pub async fn upload_to_s3( storj_client: &S3Client, bucket: &str, key: &str, body: Vec, content_type: &str, ) -> Result { let body_stream = ByteStream::from(body); // Преобразуем тело файла в поток байтов storj_client .put_object() .bucket(bucket) .key(key) .body(body_stream) .content_type(content_type) .send() .await .map_err(|_| ErrorInternalServerError("Failed to upload file to S3"))?; // Загрузка файла в S3 Ok(key.to_string()) // Возвращаем ключ файла } /// Проверяет, существует ли файл в S3. pub async fn check_file_exists( storj_client: &S3Client, bucket: &str, file_key: &str, ) -> Result { match storj_client.head_object().bucket(bucket).key(file_key).send().await { Ok(_) => Ok(true), // Файл найден Err(SdkError::ServiceError(service_error)) if service_error.err().is_not_found() => { Ok(false) // Файл не найден } Err(e) => Err(ErrorInternalServerError(e.to_string())), // Ошибка при проверке } } /// Загружает файл из S3. pub async fn load_file_from_s3( storj_client: &S3Client, bucket: &str, key: &str, ) -> Result, actix_web::Error> { let get_object_output = storj_client .get_object() .bucket(bucket) .key(key) .send() .await .map_err(|_| ErrorInternalServerError("Failed to get object from S3"))?; let data: aws_sdk_s3::primitives::AggregatedBytes = get_object_output .body .collect() .await .map_err(|_| ErrorInternalServerError("Failed to read object body"))?; Ok(data.to_vec()) } /// Генерирует ключ с правильным расширением на основе MIME-типа. pub fn generate_key_with_extension(base_key: String, mime_type: String) -> String { let mime: mime::Mime = mime::Mime::from_str(&mime_type).unwrap_or(mime::APPLICATION_OCTET_STREAM); if let Some(extensions) = mime_guess::get_mime_extensions_str(mime.as_ref()) { if let Some(extension) = extensions.first() { return format!("{}.{}", base_key, extension); } } base_key }