From a10b75d453c266764e4e74d64cf63e3902625d4a Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Thu, 21 Aug 2025 14:13:42 -0500 Subject: [PATCH] make an --add option --- argv.go | 2 +- argvAutoshell.go | 2 +- format_rich_log.go | 35 +++++++++++++++++++++++++++++++++++ main.go | 40 ++++++++++++++++++++++++++++++++++++++-- structs.go | 7 +++++-- 5 files changed, 80 insertions(+), 6 deletions(-) diff --git a/argv.go b/argv.go index d1ce699..398cd8d 100644 --- a/argv.go +++ b/argv.go @@ -10,7 +10,7 @@ package main var argv args type args struct { - Add *EmptyCmd `arg:"subcommand:add" help:"add a conversation"` + Add string `arg:"--add" help:"add a new chat"` Format *EmptyCmd `arg:"subcommand:format" help:"add a conversation"` Playback *PlaybackCmd `arg:"subcommand:playback" help:"dump your prior conversations to the terminal'"` Force bool `arg:"--force" help:"try to strong arm things"` diff --git a/argvAutoshell.go b/argvAutoshell.go index 912d799..28d3f56 100644 --- a/argvAutoshell.go +++ b/argvAutoshell.go @@ -30,7 +30,7 @@ func (args) doBashAuto() { default: if argv.BashAuto[0] == ARGNAME { // list the subcommands here - fmt.Println("add format playback") + fmt.Println("--add format playback") } } os.Exit(0) diff --git a/format_rich_log.go b/format_rich_log.go index ddf75bf..09bea60 100644 --- a/format_rich_log.go +++ b/format_rich_log.go @@ -12,6 +12,41 @@ import ( const termWidth = 120 // The target width for the formatted output boxes. +func parseRichLog(filename string) *chatpb.Chats { + data, err := os.ReadFile(filename) + if err != nil { + log.Fatalf("Error reading file %s: %v", filename, err) + } + + logData, err := chatpb.UnmarshalChatsTEXT(data) + if err != nil { + log.Fatalf("Error unmarshaling log file %s: %v", filename, err) + } + + for _, chat := range logData.GetChats() { + // Handle content: prefer content_file, fallback to content. + var content string + if contentFile := chat.GetContentFile(); contentFile != "" { + // Construct the full path relative to the log file's directory. + logDir := filepath.Dir(filename) + contentPath := filepath.Join(logDir, contentFile) + + contentBytes, err := os.ReadFile(contentPath) + if err != nil { + content = fmt.Sprintf("--- ERROR: Could not read content file %s: %v ---", contentPath, err) + } else { + content = string(contentBytes) + } + } else { + // Fallback for older log formats. + content = chat.GetContent() + } + chat.Content = content + } + + return logData +} + func formatRichLog(filename string) *chatpb.Chats { data, err := os.ReadFile(filename) if err != nil { diff --git a/main.go b/main.go index ac443c6..e5a4ee7 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ import ( "embed" "os" + "github.com/google/uuid" "go.wit.com/dev/alexflint/arg" "go.wit.com/gui" "go.wit.com/lib/protobuf/chatpb" @@ -55,8 +56,29 @@ func main() { os.Exit(0) } - if argv.Add != nil { - log.Info("add new conversation to protobuf") + me.chats = chatpb.NewChats() + if err := me.chats.ConfigLoad(); err != nil { + badExit(err) + } + if verifyUuids(me.chats) { + me.chats.ConfigSave() + } + + if argv.Add != "" { + log.Info("add new conversation to protobuf", argv.Add) + pb := parseRichLog(argv.Add) + verifyUuids(pb) + all := pb.SortByUuid() + for all.Scan() { + chat := all.Next() + log.Info("NEW CHAT", chat.From, chat.Uuid) + if test := me.chats.FindByContentFile(chat.ContentFile); test != nil { + log.Info("NOT NEW CHAT", test.ContentFile) + continue + } + me.chats.AppendByUuid(chat) + } + pb.ConfigSave() okExit("") } @@ -76,3 +98,17 @@ func main() { // doGui() okExit("") } + +func verifyUuids(chats *chatpb.Chats) bool { + var changed bool + + all := chats.SortByUuid() + for all.Scan() { + chat := all.Next() + if chat.Uuid == "" { + chat.Uuid = uuid.New().String() + changed = true + } + } + return changed +} diff --git a/structs.go b/structs.go index 6f7efa0..8b60bb2 100644 --- a/structs.go +++ b/structs.go @@ -5,12 +5,15 @@ package main import ( "go.wit.com/dev/alexflint/arg" + "go.wit.com/gui" + "go.wit.com/lib/protobuf/chatpb" ) var me *mainType // this app's variables type mainType struct { - pp *arg.Parser // for parsing the command line args. Yay to alexf lint! - // myGui *gui.Node // the gui toolkit handle + pp *arg.Parser // for parsing the command line args. Yay to alexf lint! + chats *chatpb.Chats // all our prior conversations with gemini + myGui *gui.Node // the gui toolkit handle }