2
0
Files
log/src/commands/record.rs
2026-03-30 14:01:34 +09:00

132 lines
3.7 KiB
Rust

use anyhow::{Context, Result};
use serde_json::Value;
use std::fs;
use super::auth;
use crate::lexicons::com_atproto_repo;
use crate::tid;
use crate::types::{
DeleteRecordRequest, ListRecordsResponse, PutRecordRequest, PutRecordResponse,
};
use crate::xrpc::XrpcClient;
/// Put a record to ATProto
pub async fn put_record(file: &str, collection: &str, rkey: Option<&str>) -> Result<()> {
let session = auth::refresh_session().await?;
let pds = session.pds.as_deref().unwrap_or("bsky.social");
let client = XrpcClient::new(pds);
let content = fs::read_to_string(file)
.with_context(|| format!("Failed to read file: {}", file))?;
let record: Value = serde_json::from_str(&content)?;
let rkey = rkey
.map(|s| s.to_string())
.unwrap_or_else(tid::generate_tid);
let req = PutRecordRequest {
repo: session.did.clone(),
collection: collection.to_string(),
rkey: rkey.clone(),
record,
};
let result: PutRecordResponse = client
.call(&com_atproto_repo::PUT_RECORD, &req, &session.access_jwt)
.await?;
println!("{}", serde_json::to_string_pretty(&serde_json::json!({
"uri": result.uri,
"cid": result.cid,
}))?);
Ok(())
}
/// Put a lexicon schema
pub async fn put_lexicon(file: &str) -> Result<()> {
let session = auth::refresh_session().await?;
let pds = session.pds.as_deref().unwrap_or("bsky.social");
let client = XrpcClient::new(pds);
let content = fs::read_to_string(file)
.with_context(|| format!("Failed to read file: {}", file))?;
let lexicon: Value = serde_json::from_str(&content)?;
let lexicon_id = lexicon["id"]
.as_str()
.context("Lexicon file must have 'id' field")?
.to_string();
let req = PutRecordRequest {
repo: session.did.clone(),
collection: "com.atproto.lexicon.schema".to_string(),
rkey: lexicon_id.clone(),
record: lexicon,
};
let result: PutRecordResponse = client
.call(&com_atproto_repo::PUT_RECORD, &req, &session.access_jwt)
.await?;
println!("{}", serde_json::to_string_pretty(&serde_json::json!({
"uri": result.uri,
"cid": result.cid,
}))?);
Ok(())
}
/// Get records from a collection
pub async fn get_records(collection: &str, limit: u32) -> Result<()> {
let session = auth::refresh_session().await?;
let pds = session.pds.as_deref().unwrap_or("bsky.social");
let client = XrpcClient::new(pds);
let limit_str = limit.to_string();
let result: ListRecordsResponse = client
.query_auth(
&com_atproto_repo::LIST_RECORDS,
&[
("repo", &session.did),
("collection", collection),
("limit", &limit_str),
],
&session.access_jwt,
)
.await?;
println!("{}", serde_json::to_string_pretty(&result)?);
Ok(())
}
/// Delete a record
pub async fn delete_record(collection: &str, rkey: &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 client = if is_bot { XrpcClient::new_bot(pds) } else { XrpcClient::new(pds) };
let req = DeleteRecordRequest {
repo: session.did.clone(),
collection: collection.to_string(),
rkey: rkey.to_string(),
};
client
.call_no_response(&com_atproto_repo::DELETE_RECORD, &req, &session.access_jwt)
.await?;
println!("{}", serde_json::to_string_pretty(&serde_json::json!({
"deleted": true,
"collection": collection,
"rkey": rkey,
}))?);
Ok(())
}