Add configuration options when uploading an emoji
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
parent
9921bfeb2f
commit
db8ad18bb3
1 changed files with 51 additions and 43 deletions
94
emoji.go
94
emoji.go
|
@ -4,13 +4,17 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"golang.org/x/net/context/ctxhttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EmojiService handles communication with the emoji
|
// EmojiService handles communication with the emoji
|
||||||
|
@ -32,6 +36,21 @@ type Emoji struct {
|
||||||
CreatedBy string `json:"created_by,omitempty"`
|
CreatedBy string `json:"created_by,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EmojiCreateRequest represents a request to copy an emoji.
|
||||||
|
type EmojiCreateRequest struct {
|
||||||
|
Name string `url:"name"`
|
||||||
|
UserFlairAllowed *bool `url:"user_flair_allowed,omitempty"`
|
||||||
|
PostFlairAllowed *bool `url:"post_flair_allowed,omitempty"`
|
||||||
|
ModFlairOnly *bool `url:"mod_flair_only,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *EmojiCreateRequest) validate() error {
|
||||||
|
if r.Name == "" {
|
||||||
|
return errors.New("name: cannot be empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type emojis []*Emoji
|
type emojis []*Emoji
|
||||||
|
|
||||||
func (e *emojis) UnmarshalJSON(data []byte) (err error) {
|
func (e *emojis) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
@ -69,13 +88,6 @@ func (s *EmojiService) Get(ctx context.Context, subreddit string) ([]*Emoji, []*
|
||||||
return nil, nil, resp, err
|
return nil, nil, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
The response to this request is something like:
|
|
||||||
{
|
|
||||||
"snoomojis": { ... },
|
|
||||||
"t5_subredditId": { ... }
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
defaultEmojis := root["snoomojis"]
|
defaultEmojis := root["snoomojis"]
|
||||||
var subredditEmojis []*Emoji
|
var subredditEmojis []*Emoji
|
||||||
|
|
||||||
|
@ -132,12 +144,7 @@ func (s *EmojiService) DisableCustomSize(ctx context.Context, subreddit string)
|
||||||
return s.client.Do(ctx, req, nil)
|
return s.client.Do(ctx, req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type field struct {
|
func (s *EmojiService) lease(ctx context.Context, subreddit, imagePath string) (string, map[string]string, *Response, error) {
|
||||||
Name string `json:"name"`
|
|
||||||
Value string `json:"value"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *EmojiService) lease(ctx context.Context, subreddit, imagePath string) (string, []field, *Response, error) {
|
|
||||||
path := fmt.Sprintf("api/v1/%s/emoji_asset_upload_s3.json", subreddit)
|
path := fmt.Sprintf("api/v1/%s/emoji_asset_upload_s3.json", subreddit)
|
||||||
|
|
||||||
form := url.Values{}
|
form := url.Values{}
|
||||||
|
@ -154,8 +161,11 @@ func (s *EmojiService) lease(ctx context.Context, subreddit, imagePath string) (
|
||||||
|
|
||||||
var response struct {
|
var response struct {
|
||||||
S3UploadLease struct {
|
S3UploadLease struct {
|
||||||
Action string `json:"action"`
|
Action string `json:"action"`
|
||||||
Fields []field `json:"fields"`
|
Fields []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
} `json:"fields"`
|
||||||
} `json:"s3UploadLease"`
|
} `json:"s3UploadLease"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,16 +175,22 @@ func (s *EmojiService) lease(ctx context.Context, subreddit, imagePath string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadURL := fmt.Sprintf("http:%s", response.S3UploadLease.Action)
|
uploadURL := fmt.Sprintf("http:%s", response.S3UploadLease.Action)
|
||||||
fields := response.S3UploadLease.Fields
|
|
||||||
|
fields := make(map[string]string)
|
||||||
|
for _, field := range response.S3UploadLease.Fields {
|
||||||
|
fields[field.Name] = field.Value
|
||||||
|
}
|
||||||
|
|
||||||
return uploadURL, fields, resp, nil
|
return uploadURL, fields, resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EmojiService) upload(ctx context.Context, subreddit, emojiName, awsKey string) (*Response, error) {
|
func (s *EmojiService) upload(ctx context.Context, createRequest *EmojiCreateRequest, subreddit, awsKey string) (*Response, error) {
|
||||||
path := fmt.Sprintf("api/v1/%s/emoji.json", subreddit)
|
path := fmt.Sprintf("api/v1/%s/emoji.json", subreddit)
|
||||||
|
|
||||||
form := url.Values{}
|
form, err := query.Values(createRequest)
|
||||||
form.Set("name", emojiName)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
form.Set("s3_key", awsKey)
|
form.Set("s3_key", awsKey)
|
||||||
|
|
||||||
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
@ -186,7 +202,16 @@ func (s *EmojiService) upload(ctx context.Context, subreddit, emojiName, awsKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload uploads an emoji.
|
// Upload uploads an emoji.
|
||||||
func (s *EmojiService) Upload(ctx context.Context, subreddit, emojiName, imagePath string) (*Response, error) {
|
func (s *EmojiService) Upload(ctx context.Context, createRequest *EmojiCreateRequest, subreddit, imagePath string) (*Response, error) {
|
||||||
|
if createRequest == nil {
|
||||||
|
return nil, errors.New("createRequest: cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := createRequest.validate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
uploadURL, fields, resp, err := s.lease(ctx, subreddit, imagePath)
|
uploadURL, fields, resp, err := s.lease(ctx, subreddit, imagePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
|
@ -198,24 +223,13 @@ func (s *EmojiService) Upload(ctx context.Context, subreddit, emojiName, imagePa
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
fileContents, err := ioutil.ReadAll(file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
body := new(bytes.Buffer)
|
body := new(bytes.Buffer)
|
||||||
writer := multipart.NewWriter(body)
|
writer := multipart.NewWriter(body)
|
||||||
|
|
||||||
// This will be used to trigger the upload on the AWS side.
|
|
||||||
var key string
|
|
||||||
|
|
||||||
// AWS ignores all fields in the request that come after the file field, so we need to set these before
|
// AWS ignores all fields in the request that come after the file field, so we need to set these before
|
||||||
// https://stackoverflow.com/questions/15234496/upload-directly-to-amazon-s3-using-ajax-returning-error-bucket-post-must-contai/15235866#15235866
|
// https://stackoverflow.com/questions/15234496/upload-directly-to-amazon-s3-using-ajax-returning-error-bucket-post-must-contai/15235866#15235866
|
||||||
for _, field := range fields {
|
for k, v := range fields {
|
||||||
if field.Name == "key" {
|
writer.WriteField(k, v)
|
||||||
key = field.Value
|
|
||||||
}
|
|
||||||
writer.WriteField(field.Name, field.Value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
part, err := writer.CreateFormFile("file", file.Name())
|
part, err := writer.CreateFormFile("file", file.Name())
|
||||||
|
@ -223,7 +237,7 @@ func (s *EmojiService) Upload(ctx context.Context, subreddit, emojiName, imagePa
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = part.Write(fileContents)
|
_, err = io.Copy(part, file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -233,13 +247,7 @@ func (s *EmojiService) Upload(ctx context.Context, subreddit, emojiName, imagePa
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, uploadURL, body)
|
httpResponse, err := ctxhttp.Post(ctx, nil, uploadURL, writer.FormDataContentType(), body)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Header.Set(headerContentType, writer.FormDataContentType())
|
|
||||||
|
|
||||||
httpResponse, err := DoRequest(ctx, req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -249,5 +257,5 @@ func (s *EmojiService) Upload(ctx context.Context, subreddit, emojiName, imagePa
|
||||||
return &Response{httpResponse}, err
|
return &Response{httpResponse}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.upload(ctx, subreddit, emojiName, key)
|
return s.upload(ctx, createRequest, subreddit, fields["key"])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue