Codebase list golang-github-nlopes-slack / 7e1f447
file.upload: allow uploads with io.Reader (#165) file.upload: allow uploads with io.Reader Denys Smirnov authored 6 years ago Florin Pățan committed 6 years ago
3 changed file(s) with 28 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
11
22 import (
33 "errors"
4 "io"
45 "net/url"
56 "strconv"
67 "strings"
8586 IsStarred bool `json:"is_starred"`
8687 }
8788
88 // FileUploadParameters contains all the parameters necessary (including the optional ones) for an UploadFile() request
89 // FileUploadParameters contains all the parameters necessary (including the optional ones) for an UploadFile() request.
90 //
91 // There are three ways to upload a file. You can either set Content if file is small, set Reader if file is large,
92 // or provide a local file path in File to upload it from your filesystem.
8993 type FileUploadParameters struct {
9094 File string
9195 Content string
96 Reader io.Reader
9297 Filetype string
9398 Filename string
9499 Title string
220225 values.Add("content", params.Content)
221226 err = post("files.upload", values, response, api.debug)
222227 } else if params.File != "" {
223 err = postWithMultipartResponse("files.upload", params.File, "file", values, response, api.debug)
228 err = postLocalWithMultipartResponse("files.upload", params.File, "file", values, response, api.debug)
229 } else if params.Reader != nil {
230 err = postWithMultipartResponse("files.upload", params.Filename, "file", values, params.Reader, response, api.debug)
224231 }
225232 if err != nil {
226233 return nil, err
22 import (
33 "bytes"
44 "encoding/json"
5 "errors"
65 "fmt"
76 "io"
87 "io/ioutil"
4140 return string(s)
4241 }
4342
44 func fileUploadReq(path, fpath, fieldname string, values url.Values) (*http.Request, error) {
45 fullpath, err := filepath.Abs(fpath)
46 if err != nil {
47 return nil, err
48 }
49 file, err := os.Open(fullpath)
50 if err != nil {
51 return nil, err
52 }
53 defer file.Close()
54
43 func fileUploadReq(path, fieldname, filename string, values url.Values, r io.Reader) (*http.Request, error) {
5544 body := &bytes.Buffer{}
5645 wr := multipart.NewWriter(body)
5746
58 ioWriter, err := wr.CreateFormFile(fieldname, filepath.Base(fullpath))
47 ioWriter, err := wr.CreateFormFile(fieldname, filename)
5948 if err != nil {
6049 wr.Close()
6150 return nil, err
6251 }
63 bytes, err := io.Copy(ioWriter, file)
52 _, err = io.Copy(ioWriter, r)
6453 if err != nil {
6554 wr.Close()
6655 return nil, err
6756 }
6857 // Close the multipart writer or the footer won't be written
6958 wr.Close()
70 stat, err := file.Stat()
71 if err != nil {
72 return nil, err
73 }
74 if bytes != stat.Size() {
75 return nil, errors.New("could not read the whole file")
76 }
7759 req, err := http.NewRequest("POST", path, body)
7860 if err != nil {
7961 return nil, err
10284 return nil
10385 }
10486
105 func postWithMultipartResponse(path, filepath, fieldname string, values url.Values, intf interface{}, debug bool) error {
106 req, err := fileUploadReq(SLACK_API+path, filepath, fieldname, values)
87 func postLocalWithMultipartResponse(path, fpath, fieldname string, values url.Values, intf interface{}, debug bool) error {
88 fullpath, err := filepath.Abs(fpath)
89 if err != nil {
90 return err
91 }
92 file, err := os.Open(fullpath)
93 if err != nil {
94 return err
95 }
96 defer file.Close()
97 return postWithMultipartResponse(path, filepath.Base(fpath), fieldname, values, file, intf, debug)
98 }
99
100 func postWithMultipartResponse(path, name, fieldname string, values url.Values, r io.Reader, intf interface{}, debug bool) error {
101 req, err := fileUploadReq(SLACK_API+path, fieldname, name, values, r)
107102 if err != nil {
108103 return err
109104 }
227227 if params.CropW != DEFAULT_USER_PHOTO_CROP_W {
228228 values.Add("crop_w", string(params.CropW))
229229 }
230 err := postWithMultipartResponse("users.setPhoto", image, "image", values, response, api.debug)
230 err := postLocalWithMultipartResponse("users.setPhoto", image, "image", values, response, api.debug)
231231 if err != nil {
232232 return err
233233 }