Files
log/src/commands/push.rs
2026-02-04 22:18:09 +09:00

86 lines
2.4 KiB
Rust

use anyhow::Result;
use serde_json::Value;
use std::fs;
use super::auth;
use crate::lexicons::com_atproto_repo;
use crate::types::{PutRecordRequest, PutRecordResponse};
use crate::xrpc::XrpcClient;
/// Push local content to PDS
pub async fn push_to_remote(input: &str, collection: &str, is_bot: bool) -> Result<()> {
let session = if is_bot {
auth::refresh_bot_session().await?
} else {
auth::refresh_session().await?
};
let pds = session.pds.as_deref().unwrap_or("bsky.social");
let did = &session.did;
let client = XrpcClient::new(pds);
// Build collection directory path
let collection_dir = format!("{}/{}/{}", input, did, collection);
if !std::path::Path::new(&collection_dir).exists() {
anyhow::bail!("Collection directory not found: {}", collection_dir);
}
println!("Pushing records from {} to {}", collection_dir, collection);
let mut count = 0;
for entry in fs::read_dir(&collection_dir)? {
let entry = entry?;
let path = entry.path();
// Skip non-JSON files and index.json
if path.extension().map(|e| e != "json").unwrap_or(true) {
continue;
}
let filename = path.file_stem().and_then(|s| s.to_str()).unwrap_or("");
if filename == "index" {
continue;
}
let rkey = filename.to_string();
let content = fs::read_to_string(&path)?;
let record_data: Value = serde_json::from_str(&content)?;
// Extract value from record (sync saves as {uri, cid, value})
let record = if record_data.get("value").is_some() {
record_data["value"].clone()
} else {
record_data
};
let req = PutRecordRequest {
repo: did.clone(),
collection: collection.to_string(),
rkey: rkey.clone(),
record,
};
println!("Pushing: {}", rkey);
match client
.call::<_, PutRecordResponse>(
&com_atproto_repo::PUT_RECORD,
&req,
&session.access_jwt,
)
.await
{
Ok(result) => {
println!(" OK: {}", result.uri);
count += 1;
}
Err(e) => {
println!(" Failed: {}", e);
}
}
}
println!("Pushed {} records to {}", count, collection);
Ok(())
}