Export/Import: ZIP export with scope selection, import with public post merge
Export (export.rs): ZIP archive with auto-chunking at 4GB. Four scopes: identity only, posts only, posts+identity, everything (posts+key+follows+ profiles+settings). Includes blobs. Manifest JSON tracks metadata. Import (import.rs): Read ZIP summary without importing (preview). Import public posts into current identity with new PostIds + original timestamps. Import as new identity (creates identity subdir from key). Uses spawn_blocking for ZIP I/O to avoid Send issues with ZipArchive. Tauri IPC: export_data, import_summary, import_public_posts, import_as_new_identity commands. IdentityManager.base_dir() getter. Frontend: Export wizard lightbox with scope radio buttons + output dir. Import wizard with ZIP path, preview summary, action selection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fb1e92985c
commit
8ef32e6df6
7 changed files with 786 additions and 3 deletions
|
|
@ -2146,6 +2146,76 @@ async fn get_active_identity(state: State<'_, AppIdentity>) -> Result<Option<Ide
|
|||
}))
|
||||
}
|
||||
|
||||
// --- Export/Import IPC ---
|
||||
|
||||
#[tauri::command]
|
||||
async fn export_data(
|
||||
state: State<'_, AppNode>,
|
||||
scope: String,
|
||||
output_dir: String,
|
||||
) -> Result<String, String> {
|
||||
let node = get_node(&state).await;
|
||||
let export_scope = match scope.as_str() {
|
||||
"identity_only" => itsgoin_core::export::ExportScope::IdentityOnly,
|
||||
"posts_only" => itsgoin_core::export::ExportScope::PostsOnly,
|
||||
"posts_with_identity" => itsgoin_core::export::ExportScope::PostsWithIdentity,
|
||||
"everything" => itsgoin_core::export::ExportScope::Everything,
|
||||
_ => return Err("Invalid scope".to_string()),
|
||||
};
|
||||
let result = itsgoin_core::export::export_data(
|
||||
&node.data_dir,
|
||||
&node.storage,
|
||||
&node.blob_store,
|
||||
&node.node_id,
|
||||
export_scope,
|
||||
std::path::Path::new(&output_dir),
|
||||
).await.map_err(|e| e.to_string())?;
|
||||
|
||||
let paths: Vec<String> = result.paths.iter()
|
||||
.map(|p| p.to_string_lossy().to_string())
|
||||
.collect();
|
||||
Ok(format!("Exported {} posts, {} blobs to {} file(s): {}",
|
||||
result.post_count, result.blob_count, paths.len(),
|
||||
paths.join(", ")))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn import_summary(zip_path: String) -> Result<String, String> {
|
||||
let summary = itsgoin_core::import::read_import_summary(std::path::Path::new(&zip_path))
|
||||
.map_err(|e| e.to_string())?;
|
||||
serde_json::to_string(&summary).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn import_public_posts(
|
||||
state: State<'_, AppNode>,
|
||||
zip_path: String,
|
||||
) -> Result<String, String> {
|
||||
let node = get_node(&state).await;
|
||||
let result = itsgoin_core::import::import_public_posts(
|
||||
std::path::Path::new(&zip_path),
|
||||
&node.storage,
|
||||
&node.blob_store,
|
||||
&node.node_id,
|
||||
).await.map_err(|e| e.to_string())?;
|
||||
Ok(result.message)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn import_as_new_identity(
|
||||
state: State<'_, AppIdentity>,
|
||||
zip_path: String,
|
||||
) -> Result<String, String> {
|
||||
let mgr = state.lock().await;
|
||||
let base_dir = mgr.base_dir().to_path_buf();
|
||||
drop(mgr);
|
||||
let node_id = itsgoin_core::import::import_as_identity(
|
||||
std::path::Path::new(&zip_path),
|
||||
&base_dir,
|
||||
).map_err(|e| e.to_string())?;
|
||||
Ok(format!("Identity {} imported — switch to it in Settings", &node_id[..12]))
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tracing_subscriber::fmt()
|
||||
|
|
@ -2334,6 +2404,10 @@ pub fn run() {
|
|||
delete_identity,
|
||||
import_identity_key,
|
||||
get_active_identity,
|
||||
export_data,
|
||||
import_summary,
|
||||
import_public_posts,
|
||||
import_as_new_identity,
|
||||
])
|
||||
.build(tauri::generate_context!())
|
||||
.expect("error while building tauri application")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue