diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2025-09-30 21:50:36 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2025-09-30 21:50:36 -0700 |
| commit | c2ca26a918b7054199234e8459d84ee2fd260759 (patch) | |
| tree | a44f8dad1ca70eb25d4dc12bf17e136fd0711e04 /tools/notes/notes.go | |
| parent | ed285a247a3a967e02f428fa2b6e69d629e2bd14 (diff) | |
| download | roseh.moe-c2ca26a918b7054199234e8459d84ee2fd260759.tar.zst | |
Allow appending to notes
Right now it's n^2 which is a big problem (to be fixed later)
Diffstat (limited to 'tools/notes/notes.go')
| -rw-r--r-- | tools/notes/notes.go | 108 |
1 files changed, 59 insertions, 49 deletions
diff --git a/tools/notes/notes.go b/tools/notes/notes.go index adc7e6a..2b03694 100644 --- a/tools/notes/notes.go +++ b/tools/notes/notes.go @@ -35,7 +35,7 @@ func readGobResp[Response any](req *http.Request) (*Response, error) { return nil, fmt.Errorf("read gob response: decode response: %s", err) } if apiResp.Status != api.Ok { - return nil, fmt.Errorf("read gob response: api error: %s", apiResp.Err) + return nil, fmt.Errorf("read gob response: api error: %s: %s", apiResp.Status, apiResp.Err) } resp, ok := apiResp.Ok.(*Response) if !ok { @@ -44,23 +44,19 @@ func readGobResp[Response any](req *http.Request) (*Response, error) { return resp, nil } -func login(ctx context.Context) (string, error) { +func login(ctx context.Context) (*api.LoginResponse, error) { fmt.Print("Enter password:") password, err := term.ReadPassword(int(os.Stdin.Fd())) fmt.Println() if err != nil { - return "", err + return nil, err } req, err := http.NewRequestWithContext(ctx, "POST", *serverURL+"/api/login", nil) if err != nil { - return "", err + return nil, err } req.Header.Set("Roseh-Password", string(password)) - resp, err := readGobResp[api.LoginResponse](req) - if err != nil { - return "", err - } - return resp.Token, nil + return readGobResp[api.LoginResponse](req) } func loadToken(ctx context.Context) (string, error) { @@ -71,8 +67,8 @@ func loadToken(ctx context.Context) (string, error) { if err != nil { return "", err } - os.WriteFile(tokenCache, []byte(token), 0600) - return token, nil + os.WriteFile(tokenCache, []byte(token.Token), 0600) + return token.Token, nil } return "", err } @@ -96,6 +92,39 @@ func gobReq(ctx context.Context, method, url string, req any) (*http.Request, er return httpReq, nil } +func gobReqResp[Response any](ctx context.Context, method, url string, req any) (*Response, error) { + httpReq, err := gobReq(ctx, method, url, req) + if err != nil { + return nil, err + } + return readGobResp[Response](httpReq) +} + +func listNotes(ctx context.Context, req *api.ListNotesRequest) (*api.ListNotesResponse, error) { + return gobReqResp[api.ListNotesResponse](ctx, "GET", *serverURL+"/api/list-notes", req) +} + +func createNote(ctx context.Context, req *api.CreateNoteRequest) (*api.CreateNoteResponse, error) { + return gobReqResp[api.CreateNoteResponse](ctx, "POST", *serverURL+"/api/create-note", req) +} + +func readNote(ctx context.Context, req *api.ReadNoteRequest) (*gob.Decoder, func() error, error) { + httpReq, err := gobReq(ctx, "GET", *serverURL+"/api/read-note", req) + if err != nil { + return nil, nil, err + } + resp, err := http.DefaultClient.Do(httpReq) + if err != nil { + return nil, nil, err + } + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + resp.Body.Close() + return nil, nil, fmt.Errorf("error status: %s\n%s", resp.Status, body) + } + return gob.NewDecoder(resp.Body), resp.Body.Close, nil +} + type loginCommand struct{} func (*loginCommand) Name() string { @@ -117,7 +146,7 @@ func (*loginCommand) login(ctx context.Context) error { if err != nil { return err } - return os.WriteFile(tokenCache, []byte(token), 0600) + return os.WriteFile(tokenCache, []byte(token.Token), 0600) } func (c *loginCommand) Execute(ctx context.Context, _ *flag.FlagSet, _ ...any) subcommands.ExitStatus { @@ -145,11 +174,7 @@ func (*listCommand) Usage() string { func (*listCommand) SetFlags(*flag.FlagSet) {} func (*listCommand) list(ctx context.Context) error { - req, err := gobReq(ctx, "GET", *serverURL+"/api/list-notes", &api.ListNotesRequest{}) - if err != nil { - return err - } - resp, err := readGobResp[api.ListNotesResponse](req) + resp, err := listNotes(ctx, &api.ListNotesRequest{}) if err != nil { return err } @@ -184,13 +209,21 @@ func (*newCommand) Usage() string { func (*newCommand) SetFlags(*flag.FlagSet) {} type createNoteRequestStreamWriter struct { - w *gob.Encoder + ctx context.Context + continuationToken []byte + name string } func (w *createNoteRequestStreamWriter) Write(buf []byte) (int, error) { - if err := w.w.Encode(&api.CreateNoteRequestStream{Chunk: buf}); err != nil { + resp, err := createNote(w.ctx, &api.CreateNoteRequest{ + ContinuationToken: w.continuationToken, + Chunk: buf, + }) + if err != nil { return 0, err } + w.continuationToken = resp.ContinuationToken + w.name = resp.Name return len(buf), nil } @@ -200,25 +233,11 @@ func (*newCommand) new(ctx context.Context, fileName string) error { return err } defer f.Close() - r, w := io.Pipe() - req, err := http.NewRequestWithContext(ctx, "POST", *serverURL+"/api/create-note", r) - if err != nil { - return fmt.Errorf("request: %s", err) - } - token, err := loadToken(ctx) - if err != nil { - return fmt.Errorf("token: %s", err) - } - req.Header.Set("Roseh-Token", token) - go func() { - io.Copy(&createNoteRequestStreamWriter{gob.NewEncoder(w)}, f) - w.Close() - }() - resp, err := readGobResp[api.CreateNoteResponse](req) - if err != nil { - return fmt.Errorf("req: %s", err) + streamWriter := &createNoteRequestStreamWriter{ctx: ctx} + if _, err := io.Copy(streamWriter, f); err != nil { + return err } - fmt.Println(resp.Name) + fmt.Println(streamWriter.name) return nil } @@ -252,20 +271,11 @@ func (*readCommand) Usage() string { func (*readCommand) SetFlags(*flag.FlagSet) {} func (*readCommand) read(ctx context.Context, key string) error { - req, err := gobReq(ctx, "GET", *serverURL+"/api/read-note", &api.ReadNoteRequest{Note: key}) + decoder, close, err := readNote(ctx, &api.ReadNoteRequest{Note: key}) if err != nil { return err } - resp, err := http.DefaultClient.Do(req) - if err != nil { - return fmt.Errorf("http: %s", err) - } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - body, _ := io.ReadAll(resp.Body) - return fmt.Errorf("error status: %s\n%s", resp.Status, body) - } - decoder := gob.NewDecoder(resp.Body) + defer close() for { apiResp := new(api.Response) if err := decoder.Decode(apiResp); err != nil { @@ -275,7 +285,7 @@ func (*readCommand) read(ctx context.Context, key string) error { return err } if apiResp.Status != api.Ok { - return fmt.Errorf("api error: %s", apiResp.Err) + return fmt.Errorf("%s: %s", apiResp.Status, apiResp.Err) } resp, ok := apiResp.Ok.(*api.ReadNoteResponseStream) if !ok { |
