diff --git a/mastodon.go b/mastodon.go index d6f8d60..30a0516 100644 --- a/mastodon.go +++ b/mastodon.go @@ -83,6 +83,26 @@ func (c *Client) doAPI(ctx context.Context, method string, uri string, params in return err } ct = mw.FormDataContentType() + } else if reader, ok := params.(io.Reader); ok { + var buf bytes.Buffer + mw := multipart.NewWriter(&buf) + part, err := mw.CreateFormFile("file", "upload") + if err != nil { + return err + } + _, err = io.Copy(part, reader) + if err != nil { + return err + } + err = mw.Close() + if err != nil { + return err + } + req, err = http.NewRequest(method, u.String(), &buf) + if err != nil { + return err + } + ct = mw.FormDataContentType() } else { if method == http.MethodGet && pg != nil { u.RawQuery = pg.toValues().Encode() diff --git a/status.go b/status.go index cfa9911..ce280c4 100644 --- a/status.go +++ b/status.go @@ -6,6 +6,7 @@ import ( "net/http" "net/url" "time" + "io" ) // Status is struct to hold status. @@ -265,7 +266,7 @@ func (c *Client) Search(ctx context.Context, q string, resolve bool) (*Results, return &results, nil } -// UploadMedia upload a media attachment. +// UploadMedia upload a media attachment from a file. func (c *Client) UploadMedia(ctx context.Context, file string) (*Attachment, error) { var attachment Attachment err := c.doAPI(ctx, http.MethodPost, "/api/v1/media", file, &attachment, nil) @@ -274,3 +275,13 @@ func (c *Client) UploadMedia(ctx context.Context, file string) (*Attachment, err } return &attachment, nil } + +// UploadMediaFromReader uploads a media attachment from a io.Reader. +func (c *Client) UploadMediaFromReader(ctx context.Context, reader io.Reader) (*Attachment, error) { + var attachment Attachment + err := c.doAPI(ctx, http.MethodPost, "/api/v1/media", reader, &attachment, nil) + if err != nil { + return nil, err + } + return &attachment, nil +} diff --git a/status_test.go b/status_test.go index eb6a403..1da1bf1 100644 --- a/status_test.go +++ b/status_test.go @@ -6,6 +6,7 @@ import ( "net/http" "net/http/httptest" "testing" + "os" ) func TestGetFavourites(t *testing.T) { @@ -549,4 +550,13 @@ func TestUploadMedia(t *testing.T) { if attachment.ID != "123" { t.Fatalf("want %q but %q", "123", attachment.ID) } + file, err := os.Open("testdata/logo.png") + defer file.Close() + writerAttachment, err := client.UploadMediaFromReader(context.Background(), file) + if err != nil { + t.Fatalf("should not be fail: %v", err) + } + if writerAttachment.ID != "123" { + t.Fatalf("want %q but %q", "123", attachment.ID) + } }