session_converter.rs (2412B)
1 //! Orchestrates converting a claude-code session JSONL file into nostr events. 2 //! 3 //! Reads the JSONL file line-by-line, builds kind-1988 nostr events with 4 //! proper threading, and ingests them into the local nostr database. 5 6 use crate::session_events::{self, BuiltEvent, ThreadingState}; 7 use crate::session_jsonl::JsonlLine; 8 use nostrdb::{IngestMetadata, Ndb}; 9 use std::fs::File; 10 use std::io::{BufRead, BufReader}; 11 use std::path::Path; 12 13 /// Convert a session JSONL file into nostr events and ingest them locally. 14 /// 15 /// Returns the ordered list of note IDs for the ingested events. 16 pub fn convert_session_to_events( 17 jsonl_path: &Path, 18 ndb: &Ndb, 19 secret_key: &[u8; 32], 20 ) -> Result<Vec<[u8; 32]>, ConvertError> { 21 let file = File::open(jsonl_path).map_err(ConvertError::Io)?; 22 let reader = BufReader::new(file); 23 24 let mut threading = ThreadingState::new(); 25 let mut note_ids = Vec::new(); 26 27 for (line_num, line) in reader.lines().enumerate() { 28 let line = line.map_err(ConvertError::Io)?; 29 if line.trim().is_empty() { 30 continue; 31 } 32 33 let parsed = JsonlLine::parse(&line) 34 .map_err(|e| ConvertError::Parse(format!("line {}: {}", line_num + 1, e)))?; 35 36 let events = session_events::build_events(&parsed, &mut threading, secret_key) 37 .map_err(|e| ConvertError::Build(format!("line {}: {}", line_num + 1, e)))?; 38 39 for event in events { 40 ingest_event(ndb, &event)?; 41 note_ids.push(event.note_id); 42 } 43 } 44 45 Ok(note_ids) 46 } 47 48 /// Ingest a single built event into the local ndb. 49 fn ingest_event(ndb: &Ndb, event: &BuiltEvent) -> Result<(), ConvertError> { 50 ndb.process_event_with(&event.to_event_json(), IngestMetadata::new().client(true)) 51 .map_err(|e| ConvertError::Ingest(format!("{:?}", e)))?; 52 Ok(()) 53 } 54 55 #[derive(Debug)] 56 pub enum ConvertError { 57 Io(std::io::Error), 58 Parse(String), 59 Build(String), 60 Ingest(String), 61 } 62 63 impl std::fmt::Display for ConvertError { 64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 65 match self { 66 ConvertError::Io(e) => write!(f, "IO error: {}", e), 67 ConvertError::Parse(e) => write!(f, "parse error: {}", e), 68 ConvertError::Build(e) => write!(f, "build error: {}", e), 69 ConvertError::Ingest(e) => write!(f, "ingest error: {}", e), 70 } 71 } 72 }