diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2025-10-04 16:38:40 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2025-10-04 16:38:40 -0700 |
| commit | 014b84ec226b8a98d1aa5cfa54a847e6eae6030f (patch) | |
| tree | 5f33616f78fd1a7a42752760071e6916eb8e84a7 /tools | |
| parent | 8f3927cc91b8f9dcc2bd3e05c2ddd225a92c96dc (diff) | |
| download | roseh.moe-014b84ec226b8a98d1aa5cfa54a847e6eae6030f.tar.zst | |
Allow http multipart upload
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/notes/notes.go | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/tools/notes/notes.go b/tools/notes/notes.go index f22b7f9..9f190f6 100644 --- a/tools/notes/notes.go +++ b/tools/notes/notes.go @@ -10,6 +10,7 @@ import ( "io" "net/http" "os" + "time" "github.com/google/subcommands" "gitlab.com/rhogenson/roseh.moe/internal/api" @@ -20,10 +21,12 @@ var serverURL = flag.String("url", "https://roseh.moe", "server url") const tokenCache = "/dev/shm/roseh.moe-upload-token" +var errUnavailable = errors.New("unavailable") + func readGobResp[Response any](req *http.Request) (*Response, error) { httpResp, err := http.DefaultClient.Do(req) if err != nil { - return nil, fmt.Errorf("read gob response: http: %s", err) + return nil, fmt.Errorf("%w: read gob response: http: %s", errUnavailable, err) } defer httpResp.Body.Close() if httpResp.StatusCode != http.StatusOK { @@ -45,9 +48,9 @@ func readGobResp[Response any](req *http.Request) (*Response, error) { } func login(ctx context.Context) (*api.LoginResponse, error) { - fmt.Print("Enter password:") + fmt.Fprint(os.Stderr, "Enter password:") password, err := term.ReadPassword(int(os.Stdin.Fd())) - fmt.Println() + fmt.Fprintln(os.Stderr) if err != nil { return nil, err } @@ -214,11 +217,28 @@ type createNoteRequestStreamWriter struct { } func (w *createNoteRequestStreamWriter) Write(buf []byte) (int, error) { - resp, err := createNote(w.ctx, &api.CreateNoteRequest{ - ContinuationToken: w.continuationToken, - Chunk: buf, - More: true, - }) + var ( + resp *api.CreateNoteResponse + err error + ) + delay := time.Second + for i := 0; i < 3; i++ { + resp, err = createNote(w.ctx, &api.CreateNoteRequest{ + ContinuationToken: w.continuationToken, + Chunk: buf, + More: true, + }) + if !errors.Is(err, errUnavailable) { + break + } + fmt.Fprintf(os.Stderr, "Warning: %s (retrying)\n", err) + select { + case <-time.After(delay): + case <-w.ctx.Done(): + return 0, w.ctx.Err() + } + delay *= 2 + } if err != nil { return 0, err } |
