aboutsummaryrefslogtreecommitdiff
path: root/mastodon
diff options
context:
space:
mode:
authorr <r@freesoftwareextremist.com>2023-10-01 13:04:07 +0000
committerr <r@freesoftwareextremist.com>2023-10-01 13:04:07 +0000
commit81bdc7c705d5d21f62927167d5b2c8e4932c9570 (patch)
tree8bdd670af920ac0541391366b5711462d9df0fab /mastodon
parent8e3999fc3d9761f9ce71c35a7154a77c251caa66 (diff)
downloadbloat-81bdc7c705d5d21f62927167d5b2c8e4932c9570.tar.gz
bloat-81bdc7c705d5d21f62927167d5b2c8e4932c9570.zip
Add profile edit page
Diffstat (limited to 'mastodon')
-rw-r--r--mastodon/accounts.go106
-rw-r--r--mastodon/mastodon.go11
2 files changed, 97 insertions, 20 deletions
diff --git a/mastodon/accounts.go b/mastodon/accounts.go
index f4e9002..c9e0065 100644
--- a/mastodon/accounts.go
+++ b/mastodon/accounts.go
@@ -1,10 +1,14 @@
package mastodon
import (
+ "bytes"
"context"
"fmt"
+ "io"
+ "mime/multipart"
"net/http"
"net/url"
+ "path/filepath"
"strconv"
"time"
)
@@ -34,6 +38,7 @@ type Account struct {
Moved *Account `json:"moved"`
Fields []Field `json:"fields"`
Bot bool `json:"bot"`
+ Source *AccountSource `json:"source"`
Pleroma *AccountPleroma `json:"pleroma"`
}
@@ -95,54 +100,115 @@ type Profile struct {
Source *AccountSource
// Set the base64 encoded character string of the image.
- Avatar string
- Header string
+ Avatar *multipart.FileHeader
+ Header *multipart.FileHeader
}
// AccountUpdate updates the information of the current user.
func (c *Client) AccountUpdate(ctx context.Context, profile *Profile) (*Account, error) {
- params := url.Values{}
+ var buf bytes.Buffer
+ mw := multipart.NewWriter(&buf)
if profile.DisplayName != nil {
- params.Set("display_name", *profile.DisplayName)
+ err := mw.WriteField("display_name", *profile.DisplayName)
+ if err != nil {
+ return nil, err
+ }
}
if profile.Note != nil {
- params.Set("note", *profile.Note)
+ err := mw.WriteField("note", *profile.Note)
+ if err != nil {
+ return nil, err
+ }
}
if profile.Locked != nil {
- params.Set("locked", strconv.FormatBool(*profile.Locked))
+ err := mw.WriteField("locked", strconv.FormatBool(*profile.Locked))
+ if err != nil {
+ return nil, err
+ }
}
if profile.Fields != nil {
for idx, field := range *profile.Fields {
- params.Set(fmt.Sprintf("fields_attributes[%d][name]", idx), field.Name)
- params.Set(fmt.Sprintf("fields_attributes[%d][value]", idx), field.Value)
+ err := mw.WriteField(fmt.Sprintf("fields_attributes[%d][name]", idx), field.Name)
+ if err != nil {
+ return nil, err
+ }
+ err = mw.WriteField(fmt.Sprintf("fields_attributes[%d][value]", idx), field.Value)
+ if err != nil {
+ return nil, err
+ }
}
}
- if profile.Source != nil {
- if profile.Source.Privacy != nil {
- params.Set("source[privacy]", *profile.Source.Privacy)
+ if profile.Avatar != nil {
+ f, err := profile.Avatar.Open()
+ if err != nil {
+ return nil, err
}
- if profile.Source.Sensitive != nil {
- params.Set("source[sensitive]", strconv.FormatBool(*profile.Source.Sensitive))
+ fname := filepath.Base(profile.Avatar.Filename)
+ part, err := mw.CreateFormFile("avatar", fname)
+ if err != nil {
+ return nil, err
}
- if profile.Source.Language != nil {
- params.Set("source[language]", *profile.Source.Language)
+ _, err = io.Copy(part, f)
+ if err != nil {
+ return nil, err
}
}
- if profile.Avatar != "" {
- params.Set("avatar", profile.Avatar)
+ if profile.Header != nil {
+ f, err := profile.Header.Open()
+ if err != nil {
+ return nil, err
+ }
+ fname := filepath.Base(profile.Header.Filename)
+ part, err := mw.CreateFormFile("header", fname)
+ if err != nil {
+ return nil, err
+ }
+ _, err = io.Copy(part, f)
+ if err != nil {
+ return nil, err
+ }
}
- if profile.Header != "" {
- params.Set("header", profile.Header)
+ err := mw.Close()
+ if err != nil {
+ return nil, err
}
+ params := &multipartRequest{Data: &buf, ContentType: mw.FormDataContentType()}
+ var account Account
+ err = c.doAPI(ctx, http.MethodPatch, "/api/v1/accounts/update_credentials", params, &account, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &account, nil
+}
+func (c *Client) accountDeleteField(ctx context.Context, field string) (*Account, error) {
+ var buf bytes.Buffer
+ mw := multipart.NewWriter(&buf)
+ _, err := mw.CreateFormField(field)
+ if err != nil {
+ return nil, err
+ }
+ err = mw.Close()
+ if err != nil {
+ return nil, err
+ }
+ params := &multipartRequest{Data: &buf, ContentType: mw.FormDataContentType()}
var account Account
- err := c.doAPI(ctx, http.MethodPatch, "/api/v1/accounts/update_credentials", params, &account, nil)
+ err = c.doAPI(ctx, http.MethodPatch, "/api/v1/accounts/update_credentials", params, &account, nil)
if err != nil {
return nil, err
}
return &account, nil
}
+func (c *Client) AccountDeleteAvatar(ctx context.Context) (*Account, error) {
+ return c.accountDeleteField(ctx, "avatar")
+}
+
+func (c *Client) AccountDeleteHeader(ctx context.Context) (*Account, error) {
+ return c.accountDeleteField(ctx, "header")
+}
+
// GetAccountStatuses return statuses by specified accuont.
func (c *Client) GetAccountStatuses(ctx context.Context, id string, onlyMedia bool, pg *Pagination) ([]*Status, error) {
var statuses []*Status
diff --git a/mastodon/mastodon.go b/mastodon/mastodon.go
index f114169..94e2cf5 100644
--- a/mastodon/mastodon.go
+++ b/mastodon/mastodon.go
@@ -33,6 +33,11 @@ type Client struct {
config *Config
}
+type multipartRequest struct {
+ Data io.Reader
+ ContentType string
+}
+
func (c *Client) doAPI(ctx context.Context, method string, uri string, params interface{}, res interface{}, pg *Pagination) error {
u, err := url.Parse(c.config.Server)
if err != nil {
@@ -133,6 +138,12 @@ func (c *Client) doAPI(ctx context.Context, method string, uri string, params in
return err
}
ct = mw.FormDataContentType()
+ } else if mr, ok := params.(*multipartRequest); ok {
+ req, err = http.NewRequest(method, u.String(), mr.Data)
+ if err != nil {
+ return err
+ }
+ ct = mr.ContentType
} else {
if method == http.MethodGet && pg != nil {
u.RawQuery = pg.toValues().Encode()