|
1 /* |
|
2 Copyright 2017-2018 Mikael Berthe |
|
3 |
|
4 Licensed under the MIT license. Please see the LICENSE file is this directory. |
|
5 */ |
|
6 |
|
7 package madon |
|
8 |
|
9 import ( |
|
10 "bytes" |
|
11 "encoding/json" |
|
12 "io" |
|
13 "mime/multipart" |
|
14 "os" |
|
15 "path/filepath" |
|
16 "strconv" |
|
17 |
|
18 "github.com/pkg/errors" |
|
19 "github.com/sendgrid/rest" |
|
20 ) |
|
21 |
|
22 const mediaUploadFieldName = "file" |
|
23 |
|
24 // UploadMedia uploads the given file and returns an attachment |
|
25 // The description and focus arguments can be empty strings. |
|
26 // 'focus' is the "focal point", written as two comma-delimited floating points. |
|
27 func (mc *Client) UploadMedia(filePath, description, focus string) (*Attachment, error) { |
|
28 if filePath == "" { |
|
29 return nil, ErrInvalidParameter |
|
30 } |
|
31 |
|
32 f, err := os.Open(filePath) |
|
33 if err != nil { |
|
34 return nil, errors.Wrap(err, "cannot read file") |
|
35 } |
|
36 defer f.Close() |
|
37 |
|
38 return mc.UploadMediaReader(f, filepath.Base(f.Name()), description, focus) |
|
39 } |
|
40 |
|
41 // UploadMediaReader uploads data from the given reader and returns an attachment |
|
42 // name, description and focus arguments can be empty strings. |
|
43 // 'focus' is the "focal point", written as two comma-delimited floating points. |
|
44 func (mc *Client) UploadMediaReader(f io.Reader, name, description, focus string) (*Attachment, error) { |
|
45 buf := bytes.Buffer{} |
|
46 |
|
47 w := multipart.NewWriter(&buf) |
|
48 var formWriter io.Writer |
|
49 var err error |
|
50 if len(name) > 0 { |
|
51 formWriter, err = w.CreateFormFile(mediaUploadFieldName, name) |
|
52 } else { |
|
53 formWriter, err = w.CreateFormField(mediaUploadFieldName) |
|
54 } |
|
55 if err != nil { |
|
56 return nil, errors.Wrap(err, "media upload") |
|
57 } |
|
58 |
|
59 if _, err = io.Copy(formWriter, f); err != nil { |
|
60 return nil, errors.Wrap(err, "media upload") |
|
61 } |
|
62 |
|
63 w.Close() |
|
64 |
|
65 var params apiCallParams |
|
66 if description != "" || focus != "" { |
|
67 params = make(apiCallParams) |
|
68 if description != "" { |
|
69 params["description"] = description |
|
70 } |
|
71 if focus != "" { |
|
72 params["focus"] = focus |
|
73 } |
|
74 } |
|
75 |
|
76 req, err := mc.prepareRequest("v1/media", rest.Post, params) |
|
77 if err != nil { |
|
78 return nil, errors.Wrap(err, "media prepareRequest failed") |
|
79 } |
|
80 req.Headers["Content-Type"] = w.FormDataContentType() |
|
81 req.Body = buf.Bytes() |
|
82 |
|
83 // Make API call |
|
84 r, err := restAPI(req) |
|
85 if err != nil { |
|
86 return nil, errors.Wrap(err, "media upload failed") |
|
87 } |
|
88 |
|
89 // Check for error reply |
|
90 var errorResult Error |
|
91 if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil { |
|
92 // The empty object is not an error |
|
93 if errorResult.Text != "" { |
|
94 return nil, errors.New(errorResult.Text) |
|
95 } |
|
96 } |
|
97 |
|
98 // Not an error reply; let's unmarshal the data |
|
99 var attachment Attachment |
|
100 err = json.Unmarshal([]byte(r.Body), &attachment) |
|
101 if err != nil { |
|
102 return nil, errors.Wrap(err, "cannot decode API response (media)") |
|
103 } |
|
104 return &attachment, nil |
|
105 } |
|
106 |
|
107 // UpdateMedia updates the description and focal point of a media |
|
108 // One of the description and focus arguments can be nil to not be updated. |
|
109 func (mc *Client) UpdateMedia(mediaID int64, description, focus *string) (*Attachment, error) { |
|
110 params := make(apiCallParams) |
|
111 if description != nil { |
|
112 params["description"] = *description |
|
113 } |
|
114 if focus != nil { |
|
115 params["focus"] = *focus |
|
116 } |
|
117 |
|
118 endPoint := "media/" + strconv.FormatInt(mediaID, 10) |
|
119 var attachment Attachment |
|
120 if err := mc.apiCall("v1/"+endPoint, rest.Put, params, nil, nil, &attachment); err != nil { |
|
121 return nil, err |
|
122 } |
|
123 return &attachment, nil |
|
124 } |