diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 2faf28c10..baf61760c 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -1,7 +1,6 @@ extern crate dirs; use std::str::FromStr; -use std::time::{SystemTime, UNIX_EPOCH}; use anyhow::{bail, ensure, Error}; use async_std::path::Path; @@ -15,7 +14,7 @@ use deltachat::context::*; use deltachat::dc_receive_imf::*; use deltachat::dc_tools::*; use deltachat::error::Error; -use deltachat::export_chat::{export_chat, pack_exported_chat}; +use deltachat::export_chat::export_chat_to_zip; use deltachat::imex::*; use deltachat::location; use deltachat::log::LogExt; @@ -390,7 +389,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu protect \n\ unprotect \n\ delchat \n\ - export-chat \n\ + export-chat \n\ ===========================Contact requests==\n\ decidestartchat \n\ decideblock \n\ @@ -1028,24 +1027,10 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu } "export-chat" => { ensure!(!arg1.is_empty(), "Argument missing."); + ensure!(!arg2.is_empty(), "Argument missing."); let chat_id = ChatId::new(arg1.parse()?); - let res = export_chat(&context, chat_id).await; - // println!("{:?}", res); - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs(); - let destination_raw = context.get_blobdir().join(format!( - "exported_{}_{}.zip", - chat_id.to_u32(), - timestamp - )); - let destination = destination_raw.to_str().unwrap(); - let pack_res = pack_exported_chat(&context, res, destination); - match &pack_res { - Ok(()) => println!("Exported chat successfully to {}", destination), - Err(err) => println!("Error {:?}", err), - }; + // todo check if path is valid (dest dir exists) and ends in .zip + export_chat_to_zip(&context, chat_id, arg2).await; } "msginfo" => { ensure!(!arg1.is_empty(), "Argument missing."); diff --git a/src/export_chat.rs b/src/export_chat.rs index 97772fe77..d25b4521a 100644 --- a/src/export_chat.rs +++ b/src/export_chat.rs @@ -38,20 +38,29 @@ use futures::future::join_all; use serde::Serialize; #[derive(Debug)] -pub struct ExportChatResult { +struct ExportChatResult { chat_json: String, // locations_geo_json: String, message_info: Vec<(u32, String, Option)>, referenced_blobs: Vec, } -pub fn pack_exported_chat( +pub async fn export_chat_to_zip(context: &Context, chat_id: ChatId, filename: &str) -> () { + let res = export_chat_data(&context, chat_id).await; + let destination = std::path::Path::new(filename); + let pack_res = pack_exported_chat(&context, res, destination); + match &pack_res { + Ok(()) => println!("Exported chat successfully to {}", filename), + Err(err) => println!("Error {:?}", err), + }; +} + +fn pack_exported_chat( context: &Context, artifact: ExportChatResult, - filename: &str, + destination: &Path, ) -> zip::result::ZipResult<()> { - let path = std::path::Path::new(filename); - let file = std::fs::File::create(&path).unwrap(); + let file = std::fs::File::create(&destination).unwrap(); let mut zip = zip::ZipWriter::new(file); @@ -88,6 +97,8 @@ pub fn pack_exported_chat( } } + // todo maybe memory optimisation -> load message source here and pack it directly into zip + zip.finish()?; Ok(()) } @@ -169,7 +180,7 @@ impl MessageJSON { } } -pub async fn export_chat(context: &Context, chat_id: ChatId) -> ExportChatResult { +async fn export_chat_data(context: &Context, chat_id: ChatId) -> ExportChatResult { let mut blobs = Vec::new(); let mut chat_author_ids = Vec::new(); // get all messages