use crate::connections::s3_connection; use crate::controllers::HttpResult; use crate::extractors::family_extractor::FamilyInPath; use crate::services::{couples_service, members_service, photos_service}; use actix_web::HttpResponse; use std::io::{Cursor, Write}; use zip::write::FileOptions; use zip::CompressionMethod; const MEMBERS_FILE: &str = "members.json"; const COUPLES_FILE: &str = "couples.json"; /// Export whole family data pub async fn export_family(f: FamilyInPath) -> HttpResult { let files_opt = FileOptions::default().compression_method(CompressionMethod::Bzip2); let members = members_service::get_all_of_family(f.family_id()).await?; let couples = couples_service::get_all_of_family(f.family_id()).await?; let buff = Vec::with_capacity(1000000); let mut zip_file = zip::ZipWriter::new(Cursor::new(buff)); // Add main files zip_file.start_file(MEMBERS_FILE, files_opt)?; zip_file.write_all(serde_json::to_string(&members)?.as_bytes())?; zip_file.start_file(COUPLES_FILE, files_opt)?; zip_file.write_all(serde_json::to_string(&couples)?.as_bytes())?; // Add photos let mut photos = Vec::new(); for member in &members { if let Some(id) = member.photo_id() { photos.push(id); } } for couple in &couples { if let Some(id) = couple.photo_id() { photos.push(id); } } for id in photos { let photo = photos_service::get_by_id(id).await?; let ext = photo.mime_extension().unwrap_or("bad"); let file = s3_connection::get_file(&photo.photo_path()).await?; zip_file.start_file(format!("photos/{}.{ext}", id.0), files_opt)?; zip_file.write_all(&file)?; } let buff = zip_file.finish()?.into_inner(); Ok(HttpResponse::Ok() .content_type("application/zip") .body(buff)) }